www.pudn.com > moisac_face_detect.rar > ImagePr.cpp
// ImagePr.cpp : implementation file
//
#include "stdafx.h"
#include "FaceDec.h"
#include "ImagePr.h"
#include "math.h"
#define PI 3.1415926
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// ImagePr
int RECD=0;
ImagePr::ImagePr()
{
myHSIArray=NULL;
}
ImagePr::~ImagePr()
{
}
BEGIN_MESSAGE_MAP(ImagePr, CWnd)
//{{AFX_MSG_MAP(ImagePr)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// ImagePr message handlers
void ImagePr::ReadDIB(CString fName)
{
BITMAPFILEHEADER tFileHead;
BITMAPINFOHEADER tFileInfo;
UINT RowLength;
UINT tPWidth;
UINT tPHeight;
LONG tOffset;
BYTE * tPArray;
BYTE tBlue;
BYTE tGreen;
BYTE tRed;
int i,j;
CFile tPfile(fName,CFile::modeRead);
tPfile.Read(&tFileHead,14); //读出头信息
tPfile.Read(&tFileInfo,40);
if(tFileInfo.biBitCount!=24)//是否是24位位图
{
AfxMessageBox("This file isn't a 24 bit BMP");
return;
}
tOffset=tFileHead.bfOffBits-54;
tPWidth=tFileInfo.biWidth; //图像的宽
tPHeight=tFileInfo.biHeight; //图像的高
tPArray= new BYTE[tFileHead.bfSize-54];
myPArray= new COLORREF[tPHeight*tPWidth]; //图像矩阵
// tPArray: File buffer
tPfile.Read(tPArray,(tFileHead.bfSize-54));
RowLength=tPWidth*3/4; //保证每一行都是4字节的整数倍
if ((tPWidth*3)!=(RowLength*4))
RowLength+=1;
RowLength*=4;
UINT tPP;
for (i=tPHeight-1; i>=0; i--) //先读出的是最后一行数据
{
tPP=tOffset;
for(j=0; j<(int)tPWidth; j++)
{
tBlue=tPArray[tPP];
tPP++;
tGreen=tPArray[tPP];
tPP++;
tRed=tPArray[tPP];
tPP++;
*(myPArray+i*tPWidth+j)=RGB(tRed,tGreen,tBlue);
}
tOffset+=RowLength; //读下一行
}
delete tPArray;
myPWidth=tPWidth;
myPHeight=tPHeight;
}
void ImagePr::HSItrans(char tp)
{
if (myHSIArray==NULL) myHSIArray= new sHSI[myPHeight*myPWidth];
double tH,tS,tI,fR,fG,fB;
BYTE R,G,B;
int i,j;
switch (tp)
{
case 't':
for(i=0; i<(int)myPHeight; i++)
{
for (j=0; j<(int)myPWidth; j++)
{
R=GetRValue(myPArray[i*myPWidth+j]);
G=GetGValue(myPArray[i*myPWidth+j]);
B=GetBValue(myPArray[i*myPWidth+j]);
if(R!=G || G!=B)
{
fR=(double)R;
fG=(double)G;
fB=(double)B;
myHSIArray[i*myPWidth+j].I=(fR+fG+fB)/3;
myHSIArray[i*myPWidth+j].S=1-min(min(fR,fG),fB)*3/(fR+fG+fB);
myHSIArray[i*myPWidth+j].H=acos((fR-fG+fR-fB)/2/pow(((fR-fG)*(fR-fG)+(fR-fB)*(fG-fB)),0.5));
if(G(1/3))
{
if(tH>(2/3))
{
fG=tI*(1-tS);
fB=tI*(1+(tS*cos((tH-2/3)*2*PI)/cos((5/6-tH)*2*PI)));
fR=3*tI-(fG+fB);
}
else
{
fR=tI*(1-tS);
fG=tI*(1+(tS*cos((tH-1/3)*2*PI)/cos(PI-tH*2*PI)));
fB=3*tI-(fG+fR);
}
}
else
{
fB=tI*(1-tS);
fR=tI*(1+(tS*cos(tH*2*PI)/cos((1/6-tH)*2*PI)));
fG=3*tI-(fR+fB);
}
R=(BYTE)fR;
G=(BYTE)fG;
B=(BYTE)fB;
myPArray[i*myPWidth+j]=RGB(R,G,B);
}
}
break;
}
}
/*void ImagePr::FaceDection()//检测用函数,可以设几个全局变量,返回是否有人脸,有几个,然后在view类中显示。
{
if(myPArray!=NULL) //或者利用这种方式来显示信息也可以。
{
AfxMessageBox("There is not any face");
return;
}
}
*/
void ImagePr::mosaic(double *image, int n)
{
int i,j,l,k;
double cc;
for(i=0;i255)
cc=255;
for(l=0;l255)
cc=255;
for(l=0;l<((int)myPHeight-n*((int)myPHeight/n));l++) //l represent height
for(k=0;k255)
cc=255;
for(l=0;l255)
cc=255;
for(l=0;l255)
cc=255;
for(l=0;l<((int)Shu-n*((int)Shu/n));l++) //l represent height
for(k=0;k255)
cc=255;
for(l=0;l120)
E++;
else continue;
}
}
// if(E<6) continue;
if(T>=7&&E>6)
{
RECD=RECD+1;
X[RECD]=i;
Y[RECD]=j;
U[RECD]=u;
}//记录候选人脸的起始位置
else continue;
}
}
}
if(RECD==0)
{
AfxMessageBox("There is no face exist");
return;
}
if(RECD>0)
{
for(m=1;m<(int)(RECD+1);m++)
{
MY[m]=(Y[m]+6*U[m])/2;
}
for(m=1;m<(int)(RECD+1);m++)
{
for(n=m+1;n<(int)(RECD+1);n++)
{
if(fabs(X[m]-X[n])<(myPHeight/10)&&fabs(MY[m]-MY[n])<(myPWidth/10))
{
MY[m]=MY[n];
X[m]=X[n];
Y[m]=Y[n];
U[m]=U[n];
}
else continue;
}
}
}
for(m=1;m<(int)(RECD+1);m++)
{
recdArray[m].X=X[m]+2*U[m];
recdArray[m].Y=Y[m];
recdArray[m].U=U[m];
}
for(i=0; i<(int)myPHeight; i++)
{
for (j=0; j<(int)myPWidth; j++)
{
v=myHSIArray[i*myPWidth+j].I;
*(myPArray+i*myPWidth+j)=RGB(v,v,v);
}
}
for(m=1;m<(int)(RECD+1);m++)
{
/*for(p=0;p<6*U[m];p++)
{
*(myPArray+X[m]*myPWidth+Y[m]+p)=RGB(255,255,255);
*(myPArray+(X[m]+3*U[m])*myPWidth+Y[m]+p)=RGB(255,255,255);
}
for(q=0;q<3*U[m];q++)
{
*(myPArray+(X[m]+q)*myPWidth+Y[m])=RGB(255,255,255);
*(myPArray+(X[m]+q)*myPWidth+Y[m]+6*U[m])=RGB(255,255,255);
}*/
for(p=0;p<6*recdArray[m].U;p++)
{
*(myPArray+(recdArray[m].X)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+5*recdArray[m].U)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
}
for(q=0;q<5*recdArray[m].U;q++)
{
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y+6*recdArray[m].U)=RGB(0,0,0);
}
}//构造人脸边框//
delete []tpArray;
}
/*void ImagePr::FaceDection()
{
int i,j,m,n,mi,mj,p,q;
double v;
double *tpArray;
int RD;
int X[200];int Y[200];int U[200];int N[200];
int mX[200];int mY[200];int mN[200];
RD=0;
for(m=1;m<(int)(RECD+1);m++)
{
//if(tpArray==NULL)
tpArray=new double[(5*recdArray[m].U)*(6*recdArray[m].U)];
int Heng=(6*recdArray[m].U);
int Shu=(5*recdArray[m].U);
int Long=recdArray[m].U;
int mRD=0;//记录每次检测到符合特征的地址数目
mX[1]=0;mY[1]=0;mN[1]=0;
for(i=0;i100)
ME++;
}
if((n-ME)>1) continue;
if(E!=3&&fabs((j+(int)(Heng/2)-(j+j+(n+2)*(int)(Long/2))/2)>(3*Long)))
continue;
/////////眼睛定位
int N=0;//判断鼻子位置的常量
if(*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<150)
N++;
if(*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2-(int)(Long/2)))
N++;
if(*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2+(int)(Long/2)))
N++;
if(*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<*(tpArray+(i+1*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2))
N++;
if(*(tpArray+(i+2*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<*(tpArray+(i+3*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2))
N++;
if(N<4) continue;
////////鼻子定位
int M=0;/////判断嘴巴位置的常量
if(*(tpArray+(i+4*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2)<150)
M++;
if(*(tpArray+(i+4*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2-(int)(Long/2))<150)
M++;
if(*(tpArray+(i+4*(int)(Long/2))*Heng+(j+j+(n+2)*(int)(Long/2))/2+(int)(Long/2))<150)
M++;
if(M<2) continue;
//////////嘴巴定位
mRD=mRD+1;
mX[mRD]=i;
mY[mRD]=j;
mN[mRD]=n;
//////记录人脸起始位置
}
}
}
for(mi=0;mi<(int)myPHeight;mi++)
{
for (mj=0;mj<(int)myPWidth;mj++)
{
v=myHSIArray[mi*myPWidth+mj].I;
*(myPArray+mi*myPWidth+mj)=RGB(v,v,v);
}
}////将原图灰度值赋回
for(p=0;p<6*recdArray[m].U;p++)
{
*(myPArray+(recdArray[m].X+)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+5*recdArray[m].U)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
}
for(q=0;q<5*recdArray[m].U;q++)
{
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y+6*recdArray[m].U)=RGB(0,0,0);
}
/////////构造人脸边框//
if(mRD==0) continue;
if(mRD>0)
{
RD=RD+1;
X[RD]=recdArray[m].X+mX[1];
Y[RD]=recdArray[m].Y+mY[1];
N[RD]=mN[1];
U[RD]=(int)Long/2;
}
///////记录准确人脸位置
for(p=0;p<(int)(Long/2);p++)
{
*(myPArray+(X[RD]+p)*myPWidth+Y[RD])=RGB(0,0,0);
*(myPArray+(X[RD]+p)*myPWidth+Y[RD]+(2+N[1])*(int)(Long/2))=RGB(0,0,0);
}
for(q=Y[RD];q<(int)(Y[RD]+(2+N[1])*(int)(Long/2));q++)
{
*(myPArray+X[RD]*myPWidth+q)=RGB(0,0,0);
*(myPArray+(X[RD]+(int)(Long/2))*myPWidth+q)=RGB(0,0,0);
}
////////画出眼睛边界
for(p=(X[RD]+4*(int)(Long/2));p<(X[RD]+5*(int)(Long/2));p++)
{
*(myPArray+p*myPWidth+Y[RD]+N[1]*(int)(Long/2))=RGB(0,0,0);
*(myPArray+p*myPWidth+Y[RD]+(N[1]+4)*(int)(Long/2))=RGB(0,0,0);
}
for(q=(Y[RD]+N[1]*(int)(Long/2));q<(Y[RD]+(N[1]+4)*(int)(Long/2));q++)
{
*(myPArray+(X[RD]+4*(int)(Long/2))*myPWidth+q)=RGB(0,0,0);
*(myPArray+(X[RD]+5*(int)(Long/2))*myPWidth+q)=RGB(0,0,0);
}
///////画出嘴巴边界
delete []tpArray;
}
if(RD==0)
{
AfxMessageBox("There is no face exist");
return;
}
delete []tpArray;
}
*/
void ImagePr::FaceDection()
{
int i,j,m,p,q;
double v;
//double *tpArray;
// double *ltpArray;
//tpArray= new double[myPHeight*myPWidth];
for(i=0; i<(int)myPHeight; i++)
{
for (j=0; j<(int)myPWidth; j++)
{
v=myHSIArray[i*myPWidth+j].I;
*(myPArray+i*myPWidth+j)=RGB(v,v,v);
}
}
for(m=1;m<(int)(RECD+1);m++)
{
//ltpArray=new double[(5*recdArray[m].U)*(6*recdArray[m].U)];
//int Heng=(6*recdArray[m].U);
//int Shu=(5*recdArray[m].U);
//int Long=recdArray[m].U;
for(p=0;p<6*recdArray[m].U;p++)
{
*(myPArray+(recdArray[m].X)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+5*recdArray[m].U)*myPWidth+recdArray[m].Y+p)=RGB(0,0,0);
}
for(q=0;q<5*recdArray[m].U;q++)
{
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y)=RGB(0,0,0);
*(myPArray+(recdArray[m].X+q)*myPWidth+recdArray[m].Y+6*recdArray[m].U)=RGB(0,0,0);
}
/*for(i=0;i