📄 facedetectdlg.cpp
字号:
int i,j;
for(i = 0; i<m_nWndHeight; i++) tArray[i] = 0;
for(i=nMidFaceV-nSlidWinHeight; i > m_rFaceRegion.top+6*nSlidWinHeight; i--)
for(j=LeftEyeAreaH.x; j<=LeftEyeAreaH.y;j++)
if(m_tResPixelArray[i][j].rgbRed == 255 && m_tResPixelArray[i][j].rgbGreen == 0)
tArray[i] ++;
CList<CPoint,CPoint&> myListA(sizeof(CPoint));
CList<CPoint,CPoint&> myListB(sizeof(CPoint));
int flag = 0;
CPoint tPoint(-1,-1);
for(i = nMidFaceV-nSlidWinHeight; i > m_rFaceRegion.top+6*nSlidWinHeight; i--)
{
if(tArray[i] > 0 && flag ==0)
{
tPoint.x = i;
flag = 1;
}
if(tArray[i] == 0 && flag ==1)
{
tPoint.y = i;
myListA.AddTail(tPoint);
flag = 0;
}
}
delete tArray;
//去掉长度太小的候选者
for(i=0; i<myListA.GetCount();i++)
{
CPoint temp(-1,-1);
temp = myListA.GetAt(myListA.FindIndex(i));
int minVal = (m_rFaceRegion.bottom - m_rFaceRegion.top)/100;
if((temp.x-temp.y)>=minVal)
myListB.AddTail(temp);
}
myListA.RemoveAll();
//合并相邻很紧的区域
bool quit = 1;
while(quit)
{
bool doJoin = false;
for(int i=0; i<myListB.GetCount()-1;i++)
{
CPoint temp1(-1,-1),temp2(-1,-1);
temp1 = myListB.GetAt(myListB.FindIndex(i));
temp2 = myListB.GetAt(myListB.FindIndex(i+1));
if((temp1.y-temp2.x)<=(m_rFaceRegion.bottom - m_rFaceRegion.top)/100)
{
temp1.y = temp2.y;
myListB.RemoveAt(myListB.FindIndex(i));
myListB.RemoveAt(myListB.FindIndex(i));
if(i == 0) myListB.AddHead(temp1);
else myListB.InsertAfter(myListB.FindIndex(i-1),temp1);
doJoin = true;
break;
}
}
if(!doJoin) quit = 0;
}
if(myListB.GetCount()==0)
{
AfxMessageBox("无法确定左眼的位置");
}
else
{
LeftEyeAreaV = myListB.GetHead();
double sumX = 0.0;
double sumY = 0.0;
int sum = 0;
m_LeftEyeLeftCorner.x = 100000;
m_LeftEyeRightCorner.x = -1;
for(i=LeftEyeAreaV.x; i>= LeftEyeAreaV.y;i--)
for(j=LeftEyeAreaH.x; j<=LeftEyeAreaH.y;j++)
if(m_tResPixelArray[i][j].rgbGreen == 0)
{
if(j<m_LeftEyeLeftCorner.x)
{
m_LeftEyeLeftCorner.x = j;
m_LeftEyeLeftCorner.y = i;
}
if(j>m_LeftEyeRightCorner.x)
{
m_LeftEyeRightCorner.x = j;
m_LeftEyeRightCorner.y = i;
}
sumX += j;
sumY += i;
sum++;
}
m_LeftEye.x = (int)(sumX/sum);
m_LeftEye.y = (int)(sumY/sum);
m_bLeftEyeOK = TRUE;
m_bLeftEyeLeftCornerOK = TRUE;
m_bLeftEyeRightCornerOK =TRUE;
}
myListB.RemoveAll();
}
//右眼
if(RightEyeAreaH != CPoint(-1,-1))
{
int *tArray = new int[m_nWndHeight];
int i,j;
for(i = 0; i<m_nWndHeight; i++) tArray[i] = 0;
for(i=nMidFaceV-nSlidWinHeight; i > m_rFaceRegion.top+6*nSlidWinHeight; i--)
for(j=RightEyeAreaH.x; j<=RightEyeAreaH.y;j++)
if(m_tResPixelArray[i][j].rgbRed == 255 && m_tResPixelArray[i][j].rgbGreen == 0)
tArray[i] ++;
CList<CPoint,CPoint&> myListA(sizeof(CPoint));
CList<CPoint,CPoint&> myListB(sizeof(CPoint));
int flag = 0;
CPoint tPoint(-1,-1);
for(i = nMidFaceV-nSlidWinHeight; i > m_rFaceRegion.top+6*nSlidWinHeight; i--)
{
if(tArray[i] > 0 && flag ==0)
{
tPoint.x = i;
flag = 1;
}
if(tArray[i] == 0 && flag ==1)
{
tPoint.y = i;
myListA.AddTail(tPoint);
flag = 0;
}
}
delete tArray;
//去掉长度太小的候选者
for(i=0; i<myListA.GetCount();i++)
{
CPoint temp(-1,-1);
temp = myListA.GetAt(myListA.FindIndex(i));
int minVal = (m_rFaceRegion.bottom - m_rFaceRegion.top)/100;
if((temp.x-temp.y)>=minVal)
myListB.AddTail(temp);
}
myListA.RemoveAll();
//合并相邻很紧的区域
bool quit = 1;
while(quit)
{
bool doJoin = false;
for(int i=0; i<myListB.GetCount()-1;i++)
{
CPoint temp1(-1,-1),temp2(-1,-1);
temp1 = myListB.GetAt(myListB.FindIndex(i));
temp2 = myListB.GetAt(myListB.FindIndex(i+1));
if((temp1.y-temp2.x)<=(m_rFaceRegion.bottom - m_rFaceRegion.top)/50)
{
temp1.y = temp2.y;
myListB.RemoveAt(myListB.FindIndex(i));
myListB.RemoveAt(myListB.FindIndex(i));
if(i == 0) myListB.AddHead(temp1);
else myListB.InsertAfter(myListB.FindIndex(i-1),temp1);
doJoin = true;
break;
}
}
if(!doJoin) quit = 0;
}
if(myListB.GetCount()==0)
{
AfxMessageBox("无法确定右眼的位置");
}
else
{
if(myListB.GetCount()==1)
RightEyeAreaV = myListB.GetHead();
else
{
CPoint tt = myListB.GetHead();
int index = myListB.GetCount();
while(tt.y > LeftEyeAreaV.x && index > 0)
{
index --;
tt = myListB.GetAt(myListB.FindIndex(myListB.GetCount()-index));
}
RightEyeAreaV = tt;
}
double sumX = 0.0;
double sumY = 0.0;
int sum = 0;
m_RightEyeLeftCorner.x = 100000;
m_RightEyeRightCorner.x = -1;
for(i=RightEyeAreaV.x; i>=RightEyeAreaV.y;i--)
for(j=RightEyeAreaH.x; j<=RightEyeAreaH.y;j++)
if(m_tResPixelArray[i][j].rgbGreen == 0)
{
if(j<m_RightEyeLeftCorner.x)
{
m_RightEyeLeftCorner.x = j;
m_RightEyeLeftCorner.y = i;
}
if(j>m_RightEyeRightCorner.x)
{
m_RightEyeRightCorner.x = j;
m_RightEyeRightCorner.y = i;
}
sumX += j;
sumY += i;
sum++;
}
m_RightEye.x = (int)(sumX/sum);
m_RightEye.y = (int)(sumY/sum);
m_bRightEyeOK = TRUE;
m_bRightEyeLeftCornerOK = TRUE;
m_bRightEyeRightCornerOK =TRUE;
}
myListB.RemoveAll();
}
CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
MakeBitMap();
}
////////////////////////////////////////////////////////////////////////////////
// 第一种方法标记脸部区域
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnMarkFace1()
{
if(!method1->m_bBinaryReady)
{
AfxMessageBox("请先计算二值化图!");
return;
}
m_bShowFace = true;
SetCursor(LoadCursor(NULL,IDC_WAIT));
int *temp = new int[m_nWndWidth];
int max = 0;
int pos = -1;
for(int j=0; j<m_nWndWidth; j++)
{
int count = 0;
for(int i=0; i<m_nWndHeight; i++)
{
if(method1->m_pBinaryArray[i][j] == 1) count++;
}
temp[j] = count;
if(count > max)
{
max = count;
pos = j;
}
}
int left,right,l,top,bottom;
for(l=pos; l>=0; l--)
{
if(temp[l]<max*0.2||l==0)
{
left = l;
break;
}
}
for(l=pos; l<m_nWndWidth; l++)
{
if(temp[l]<max*0.3||l==m_nWndWidth-1)
{
right = l;
break;
}
}
for(int i=0; i<m_nWndHeight; i++)
{
int count = 0;
for(l = left;l<=right;l++)
{
if(method1->m_pBinaryArray[i][l] == 1) count++;
}
if(count>=(right-left)*0.5)
{
top = i;
break;
}
}
bottom = (int)(top+(right-left)*1.5)>=m_nWndHeight? m_nWndHeight-1:(int)(top+(right-left)*1.5);
CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
for(i=top;i<=bottom;i++)
{
m_tResPixelArray[i][left].rgbBlue=255;
m_tResPixelArray[i][left].rgbGreen = m_tResPixelArray[i][left].rgbRed = 0;
m_tResPixelArray[i][right].rgbBlue=255;
m_tResPixelArray[i][right].rgbGreen = m_tResPixelArray[i][right].rgbRed = 0;
}
for(j=left;j<=right;j++)
{
m_tResPixelArray[top][j].rgbBlue=255;
m_tResPixelArray[top][j].rgbGreen = m_tResPixelArray[top][j].rgbRed = 0;
m_tResPixelArray[bottom][j].rgbBlue=255;
m_tResPixelArray[bottom][j].rgbGreen = m_tResPixelArray[bottom][j].rgbRed = 0;
}
MakeBitMap();
SetCursor(LoadCursor(NULL,IDC_ARROW));
if(m_bFaceOK)
{
ReplaceDlg dlg;
if(dlg.DoModal()==IDOK)
{
CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
CRect rect(left,top,right,bottom);
m_rFaceRegion = rect;
MakeBitMap();
}
}
else
{
m_bFaceOK = true;
CopyBitMap(m_tResPixelArray,m_tOriPixelArray);
CRect rect(left,top,right,bottom);
m_rFaceRegion = rect;
MakeBitMap();
}
}
////////////////////////////////////////////////////////////////////////////////
// 第二种方法标记脸部区域
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnMarkFace2()
{
if(!method2->m_bBinaryOK)
{
AfxMessageBox("请先计算二值化图");
return;
}
m_bShowFace = true;
SetCursor(LoadCursor(NULL,IDC_WAIT));
int *numR,*numB, i, j, left,right,top,bottom;
int maxnumR = 0, maxnumB = 0;
numR = new int[m_nWndWidth];
numB = new int[m_nWndWidth];
for(j=0;j<m_nWndWidth ;j++)
{
int countR = 0, countB = 0;
for(i=0;i<m_nWndHeight;i++)
{
if(method2->m_pBinaryArray[i][j] == 0)
countR++;
if(method2->m_pBinaryArray[i][j] == 1)
countB++;
}
if(countR > maxnumR) maxnumR = countR;
numR[j] = countR;
if(countB > maxnumB) maxnumB = countB;
numB[j] = countB;
}
CList<CPoint,CPoint> myListR(sizeof(CPoint));
CList<CPoint,CPoint> myListB(sizeof(CPoint));
CPoint tempR,tempB;
int flagR = 0,flagB = 0;
for(j=0;j<m_nWndWidth ;j++)
{
if(flagR == 0)
{
if(numR[j]>maxnumR/2)
{
flagR = 1;
tempR.x = j;
}
}
else
{
if(numR[j]<=maxnumR/2 || j==m_nWndWidth-1)
{
flagR = 0;
tempR.y = j;
myListR.AddTail(tempR);
}
}
if(flagB == 0)
{
if(numB[j]>maxnumB/5)
{
flagB = 1;
tempB.x = j;
}
}
else
{
if(numB[j]<=maxnumB/5 || j==m_nWndWidth-1)
{
flagB = 0;
tempB.y = j;
if(myListB.GetCount() > 1 && (tempB.x-myListB.GetTail().y)<20)
myListB.SetAt(myListB.GetTailPosition(),CPoint(myListB.GetTail().x,j));
else
myListB.AddTail(tempB);
}
}
}
if(numR!=NULL)delete numR;
if(numB!=NULL)delete numB;
int *hairmark, k;
hairmark = new int[m_nWndWidth];
for(j=0;j<m_nWndWidth ;j++) hairmark[j]=0;
for(k=0;k<myListB.GetCount();k++)
{
CPoint temp = myListB.GetAt(myListB.FindIndex(k));
if((temp.y-temp.x)>m_nWndWidth/10)
{
for(int t = temp.x;t<=temp.y;t++)
hairmark[t] = 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -