⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 facedetectdlg.cpp

📁 可以对人脸进行识别和拍短,也可以同时检测
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		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 + -