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

📄 facedetectdlg.cpp

📁 可以对人脸进行识别和拍短,也可以同时检测
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	for(j=left+1; j<right-1; j++)
	{
		int positive = 0;   
		int negtive  = 0;
		for(int m=-1;m<=1;m++)
		for(int n=-1;n<=1;n++)
		if(m!=0 || n!=0)
		{
			if(result[i+m][j+n]<-5)negtive++;
			if(result[i+m][j+n]>=5)positive++;
		}
		if(positive>2 && negtive>2) 
		{
			target[i][j].rgbBlue = target[i][j].rgbGreen = target[i][j].rgbRed = 0;
		}

	}

	if(result!=NULL)
	{
		for (int i=0 ;i<m_nWndHeight;i++)
			if(result[i]!=NULL) delete result[i];
		delete result;
	}
}

////////////////////////////////////////////////////////////////////////////////
// 二值化
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnBinary() 
{
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	
	if(!method1->CalBinary())
	{
		AfxMessageBox("请先计算相似度!");
		SetCursor(LoadCursor(NULL,IDC_ARROW));	
		return;
	}
	
	m_bShowFace = false;
	for(int i=0; i<m_nWndHeight; i++)
	for(int j=0; j<m_nWndWidth;  j++)
	{
		m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
		m_tResPixelArray[i][j].rgbRed  = (int)(method1->m_pBinaryArray[i][j]*255);
	}
	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));	
	MyDraw();
}

////////////////////////////////////////////////////////////////////////////////
// 边缘提取
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnEdge() 
{
	if(!m_bFaceOK)
	{
		AfxMessageBox("请先确定脸部区域");
		return;
	}
	//左右眼的水平区域
	int nLeft,nRight,nTop,nBottom;

	nLeft	= m_rFaceRegion.left-5  > 0 ? m_rFaceRegion.left-5:0;
	nRight	= m_rFaceRegion.right+5 < m_nWndWidth? m_rFaceRegion.right+5:m_nWndWidth-1;
	nTop	= m_rFaceRegion.top-5   > 0 ? m_rFaceRegion.top-5:0;
	nBottom = m_rFaceRegion.bottom+5< m_nWndHeight?m_rFaceRegion.bottom+5:m_nWndHeight-1;
	//边缘检查
	DoLOG(nLeft,nRight,nTop,nBottom,m_tOriPixelArray,m_tResPixelArray);
	MakeBitMap();	
}

////////////////////////////////////////////////////////////////////////////////
// 求取头发和脸部区域
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnFacehair() 
{
	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	method2->MarkHairFace();
	for(int i=0; i<m_nWndHeight; i++)
	for(int j=0; j<m_nWndWidth;  j++)
	{
		switch(method2->m_pBinaryArray[i][j])
		{
		case 0:
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	0;
			m_tResPixelArray[i][j].rgbRed  = 255;
			break;
		case 1:
			m_tResPixelArray[i][j].rgbBlue = 255;
			m_tResPixelArray[i][j].rgbGreen=m_tResPixelArray[i][j].rgbRed=0;
			break;
		case 2:
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 0;
			break;
		}
	}
	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));	
}

////////////////////////////////////////////////////////////////////////////////
// 脸部区域直方图
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnHistogramFace() 
{
	if(!method2->m_bBinaryOK)
	{
		AfxMessageBox("请先计算二值化图!");
		return;
	}

	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	for(int j=0; j<m_nWndWidth;  j++)	
	{
		int count = 0;
		for(int i=0; i<m_nWndHeight; i++)
		{
			if(method2->m_pBinaryArray[i][j] == 0) count++;
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 255;
		}
		for(i=m_nWndHeight-1; i>=m_nWndHeight-count;i--)
		{
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 0;
		}
	}

	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));			
}

////////////////////////////////////////////////////////////////////////////////
// 水平方向直方图
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnHistogramH() 
{
	if(!method1->m_bBinaryReady)
	{
		AfxMessageBox("请先计算二值图");
		return;
	}
	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	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++;
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 255;
		}
		for(i=m_nWndHeight-1; i>=m_nWndHeight-count;i--)
		{
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 0;
		}
	}
	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));		
}

////////////////////////////////////////////////////////////////////////////////
// 头发的直方图
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnHistogramHair() 
{
	if(!method2->m_bBinaryOK)
	{
		AfxMessageBox("请先计算二值图!");
		return;
	}
	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	for(int j=0; j<m_nWndWidth;  j++)	
	{
		int count = 0;
		for(int i=0; i<m_nWndHeight; i++)
		{
			if(method2->m_pBinaryArray[i][j] == 1) count++;
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 255;
		}
		for(i=m_nWndHeight-1; i>=m_nWndHeight-count;i--)
		{
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 0;
		}
	}
	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));					
}

////////////////////////////////////////////////////////////////////////////////
// 垂直方向的直方图
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnHistogramV() 
{
	if(!method1->m_bBinaryReady)
	{
		AfxMessageBox("请先计算二值图");
		return;
	}

	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	for(int i=0; i<m_nWndHeight; i++)		
	{
		int count = 0;
		for(int j=0; j<m_nWndWidth;  j++)
		{
			if(method1->m_pBinaryArray[i][j] == 1) count++;
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 255;
		}
		for(j=0; j<count;  j++)
		{
			m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
			m_tResPixelArray[i][j].rgbRed  = 0;
		}
	}
	MakeBitMap();
	SetCursor(LoadCursor(NULL,IDC_ARROW));			
}

////////////////////////////////////////////////////////////////////////////////
// 计算相似度
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnLikehood() 
{
	m_bShowFace = false;
	SetCursor(LoadCursor(NULL,IDC_WAIT));

	method1->CalLikeHood();
	for(int i=0; i<m_nWndHeight; i++)
	for(int j=0; j<m_nWndWidth;  j++)
	{
		m_tResPixelArray[i][j].rgbBlue = m_tResPixelArray[i][j].rgbGreen =	
		m_tResPixelArray[i][j].rgbRed  = (int)(method1->m_pLikeliHoodArray[i][j]*255);
	}
	MakeBitMap();

	SetCursor(LoadCursor(NULL,IDC_ARROW));	
}

////////////////////////////////////////////////////////////////////////////////
// 标记眼睛区域
////////////////////////////////////////////////////////////////////////////////
void CFaceDetectDlg::OnBtnMarkEye() 
{
	int i,j;
	if(!m_bFaceOK)
	{
		AfxMessageBox("请先确定脸部区域");
		return;
	}
	//左右眼的水平区域
	CPoint LeftEyeAreaH(-1,-1),RightEyeAreaH(-1,-1);
	CPoint LeftEyeAreaV(-1,-1),RightEyeAreaV(-1,-1);

	int nLeft,nRight,nTop,nBottom;

	nLeft	= m_rFaceRegion.left-5  > 0 ? m_rFaceRegion.left-5:0;
	nRight	= m_rFaceRegion.right+5 < m_nWndWidth? m_rFaceRegion.right+5:m_nWndWidth-1;
	nTop	= m_rFaceRegion.top-5   > 0 ? m_rFaceRegion.top-5:0;
	nBottom = m_rFaceRegion.bottom+5< m_nWndHeight?m_rFaceRegion.bottom+5:m_nWndHeight-1;
	//边缘检查
	DoLOG(nLeft,nRight,nTop,nBottom,m_tOriPixelArray,m_tResPixelArray);

	///////////////////////////////////
	//确认两个眼睛的水平区域
    //////////////////////////////////
	int nSlidWinWidth  = (m_rFaceRegion.right - m_rFaceRegion.left)/6/2;
	int nSlidWinHeight = (m_rFaceRegion.bottom - m_rFaceRegion.top)/15/2;
	int nMidFaceH = (m_rFaceRegion.right+m_rFaceRegion.left)/2;
	int nMidFaceV = (m_rFaceRegion.bottom+m_rFaceRegion.top)/2;

	int *tempArray = new int[m_nWndWidth]; 
	for(i = 0; i<m_nWndWidth; i++) tempArray[i] = 0;

	for(i=nMidFaceV-nSlidWinHeight; i > m_rFaceRegion.top+6*nSlidWinHeight; i--)
	for(j=m_rFaceRegion.left+nSlidWinWidth; j<m_rFaceRegion.right-nSlidWinWidth; j++)
	{
		int count = 0;
		for(int p= -nSlidWinHeight ;p<nSlidWinHeight;p++)
		for(int q= -nSlidWinWidth ;q<nSlidWinWidth;q++)
		{
			if(m_tResPixelArray[i+p][j+q].rgbRed == 0)	count++;
		}
		if(count >= nSlidWinWidth*nSlidWinHeight/3)
		{
			m_tResPixelArray[i][j].rgbRed = 255;
			tempArray[j] ++;
		}
	}

	MakeBitMap();
	AfxMessageBox("眼睛的区域鉴别");

	CList<CPoint,CPoint&> myList1(sizeof(CPoint));
	CList<CPoint,CPoint&> myList2(sizeof(CPoint));
	int flag = 0;
	CPoint tPoint(-1,-1);
	for(i = 0; i<m_nWndWidth; i++)
	{
		if(tempArray[i] > 0 && flag ==0)
		{
			tPoint.x = i;
			flag = 1;
		}
		if(tempArray[i] == 0 && flag ==1)
		{
			tPoint.y = i;
			myList1.AddTail(tPoint);
			flag = 0;
		}
	}
	delete tempArray;
	//去掉长度太小的候选者	
	for(i=0; i<myList1.GetCount();i++)
	{
		CPoint temp(-1,-1);
		temp = myList1.GetAt(myList1.FindIndex(i));
		int minVal = (m_rFaceRegion.right - m_rFaceRegion.left)/20;
		if((temp.y-temp.x)>=minVal)
			myList2.AddTail(temp);
	}
	myList1.RemoveAll();
    //合并相邻很紧的区域
	bool quit = 1;
	while(quit)
	{
		bool doJoin = false;
		for(int i=0; i<myList2.GetCount()-1;i++)
		{
			CPoint temp1(-1,-1),temp2(-1,-1);
			temp1 = myList2.GetAt(myList2.FindIndex(i));
			temp2 = myList2.GetAt(myList2.FindIndex(i+1));
			if((temp2.x-temp1.y)<=(m_rFaceRegion.right - m_rFaceRegion.left)/40)
			{
				temp1.y = temp2.y;
				myList2.RemoveAt(myList2.FindIndex(i));
				myList2.RemoveAt(myList2.FindIndex(i));
				if(i == 0)			myList2.AddHead(temp1);
				else			    myList2.InsertAfter(myList2.FindIndex(i-1),temp1);
				doJoin = true;
				break;
			}	
		}
		if(!doJoin)	quit = 0;
	}

	//没有找到眼睛区域
	if(myList2.GetCount()<2) 
	{
		CPoint t=myList2.GetHead();
		if((t.y-t.x)>(m_rFaceRegion.right - m_rFaceRegion.left)/2)
		{
			LeftEyeAreaH.x = t.x; 
			LeftEyeAreaH.y = t.x+(t.y-t.x)/3; 
			RightEyeAreaH.x = t.y-(t.y-t.x)/3;
			RightEyeAreaH.y = t.y; 
		}
		else
		{
			AfxMessageBox("确认眼睛位置失败,请手动标定");
			return;
		}
	}
	//仅有两个区域
	else if(myList2.GetCount()==2)
	{
		LeftEyeAreaH = myList2.GetHead();
		RightEyeAreaH = myList2.GetTail();
	}
	else  //多于两个区域
	{
		int ldis = -100000;
		int rdis = 100000;	
		for(i=0; i<myList2.GetCount();i++)
		{
			CPoint temp(-1,-1);
			temp = myList2.GetAt(myList2.FindIndex(i));
			//右眼
			if((temp.x+temp.y)/2 > nMidFaceH)
			{
				if(((temp.x+temp.y)/2-nMidFaceH)<rdis)
				{
					rdis = (temp.x+temp.y)/2-nMidFaceH;
					RightEyeAreaH = temp;
				}
			}
			//左眼
			else
			{
				if(((temp.x+temp.y)/2-nMidFaceH)>ldis)
				{
					ldis = (temp.x+temp.y)/2-nMidFaceH;
					LeftEyeAreaH = temp;
				}
			}
		}
	}
	myList2.RemoveAll();
	///////////////////////////////////
	//确认两个眼睛的垂直区域
    //////////////////////////////////
	//左眼
	if(LeftEyeAreaH != CPoint(-1,-1))
	{
		int *tArray = new int[m_nWndHeight]; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -