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

📄 facialfeaturedlg.cpp

📁 是一个人脸识别特征提取的Vc代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{
		for(int j=RightEyeAre.y; j>RightEyeAre.y-nEyeWidth/4; j--)
		{
			if (m_tPixelOfRefBmpArray[j][i].rgbBlue == 255) 
			{	
				findcornerRr = true;
				m_RightEyeRightCorner.x=i;
				m_RightEyeRightCorner.y=j+2;
				break;
			}
		}
		if (findcornerRr) {m_bRightEyeRightCornerOK = TRUE; break;}
	}
	
	m_LeftEye = LeftEyeArea;
	m_RightEye = RightEyeAre;
	m_bLeftEyeOK = TRUE;
	m_bRightEyeOK = TRUE;
	CopyBitMap(m_tPixelOfRefBmpArray,m_tPixelOfOriBmpArray);
	CreateBitMap();
}

void CFacialFeatureDlg::OnMouthCenter() 
{
	// 嘴巴特征的鉴别:1、色度空间;2、边缘信息
	if (!m_bLeftEyeOK)
	{
		AfxMessageBox("Please detect eyes first!");
		return;
	}
	//眼睛的倾斜角度
/*
	double tanEye;
	if (m_RightEye.y == m_LeftEye.y) tanEye = 0;
	else tanEye = double((m_RightEye.y - m_LeftEye.y))/(m_RightEye.x - m_LeftEye.x);
*/
	//双眼的距离
	int EyesDis = (m_RightEye.x - m_LeftEye.x)*(m_RightEye.x - m_LeftEye.x);
	EyesDis += (m_RightEye.y - m_LeftEye.y)*(m_RightEye.y - m_LeftEye.y);
	EyesDis = (int)sqrt(EyesDis);
	//可能的嘴巴水平区域在脸的下部1/4处,竖直区域在双眼之间
	int MouthUp    = m_rFaceArea.bottom - (m_rFaceArea.bottom - m_rFaceArea.top)/4;
	int MouthDown  = m_rFaceArea.bottom;
	int MouthLeft  = m_LeftEye.x;
    int MouthRight = m_RightEye.x;
	//嘴巴区域的颜色空间
	SetPixelValArray(m_tPixelOfRefBmpArray,0);
	yuvimg = cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);
	IplImage* temp = cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U,1);;
	cvFlip(yuvimg,yuvimg,0);
	
	BYTE* IplYuv = (BYTE*)yuvimg->imageData;
	BYTE* IplTemp = (BYTE*)temp->imageData;

	double nThreshold = 0.25;
	bool mouthCornerOK = true;
	bool mouthR = false;
	bool mouthL = false;

	BYTE R,G,B;
	double tempcolor,delta;


	while (mouthCornerOK) 
	{
		for(int i=MouthUp; i<MouthDown; i++)
		{
			for(int j=MouthLeft; j<MouthRight; j++)
			{
				R = m_tPixelOfOriBmpArray[i][j].rgbRed;
				G = m_tPixelOfOriBmpArray[i][j].rgbGreen;
				B = m_tPixelOfOriBmpArray[i][j].rgbBlue;
				if((R==G) && (G==B)) temp = 0;
				else tempcolor = 0.5*(2*R-G-B)/sqrt((R-G)*(R-G) +(R-B)*(G-B));
				delta = acos(tempcolor);
				if (delta < nThreshold) 
				{
					m_tPixelOfRefBmpArray[i][j].rgbRed = 255;
				}
				else m_tPixelOfRefBmpArray[i][j].rgbRed = 0;
			}
		}
		//对已经获得的嘴唇区域进行腐蚀等操作,以去除毛刺
		for(int row=0; row<m_nBmpHeigh; row++)
		{
			for(int col=0; col<m_nBmpWidth; col++)
				IplYuv[col + row*m_nBmpWidth] = m_tPixelOfRefBmpArray[row][col].rgbRed;
		}
			//使用下面这两个函数有时候会引起问题,导致程序的终止
			//原因可能是应为m_tPixelOfRefBmpArray[row][col].rgbRed均为0所导致的?
		cvDilate(yuvimg,temp,0,2);//死机的地方之一
		cvErode(yuvimg,temp, 0, 2);	//
		for(row=0; row<m_nBmpHeigh; row++)
		{
			for(int col=0; col<m_nBmpWidth; col++)
				m_tPixelOfRefBmpArray[row][col].rgbRed = IplTemp[col + row*m_nBmpWidth];
		}
		//在嘴唇区域内搜索两个嘴角
		//left mouth corner
		for(int j=MouthLeft; j<MouthRight; j++)
		{
			for(i=MouthDown; i>MouthUp; i--)
			{
				if (m_tPixelOfRefBmpArray[i][j].rgbRed == 255) 
				{
					m_LeftMouthCorner.x = j;
					m_LeftMouthCorner.y = i;
					mouthL = true;
					break;
				}
			}
			if (mouthL) break;
		}
		//right corner
		for(j=MouthRight; j>MouthLeft; j--)
		{
			for(i=MouthDown; i>MouthUp; i--)
			{
				if (m_tPixelOfRefBmpArray[i][j].rgbRed == 255)
				{
					m_RightMouthCorner.x = j;
					m_RightMouthCorner.y = i;
					mouthR = true;
					break;
				}
			}
			if (mouthR) break;
		}
		//适应不同光照下的阈值调节
		if (nThreshold>=0.2 && nThreshold<=0.5 && (m_RightMouthCorner.x - m_LeftMouthCorner.x)<(m_RightEye.x - m_LeftEye.x)*0.5)
		{
			nThreshold += 0.05;
			mouthR = false;
			mouthL = false;
		}
		else if (nThreshold>0 && nThreshold<=0.2 && (m_RightMouthCorner.x - m_LeftMouthCorner.x)>0.8*(m_RightEye.x - m_LeftEye.x))
		{
			nThreshold -= 0.05;
			mouthR = false;
			mouthL = false;
		}
		else mouthCornerOK = false;
	}

	if (mouthR && mouthL ) 
	{
		m_MidMouth.x = (m_LeftMouthCorner.x + m_RightMouthCorner.x)/2;
		m_MidMouth.y = (m_LeftMouthCorner.y + m_RightMouthCorner.y)/2;
		m_bLeftMouthCornerOK = TRUE;
		m_bRightMouthCornerOK = TRUE;
		//m_bMidMouthOK = TRUE;
	}
	else
	{
		AfxMessageBox("can't detect mouth features!");
		return;
	}
	//修正数值4
	m_LeftMouthCorner.y  -= 4;
	m_LeftMouthCorner.x  -= 4;
	m_RightMouthCorner.y -= 4;
	m_RightMouthCorner.x += 4;

	CopyBitMap(m_tPixelOfRefBmpArray,m_tPixelOfOriBmpArray);
	CreateBitMap();
	cvReleaseImage(&yuvimg);
	cvReleaseImage(&temp);

}

void CFacialFeatureDlg::OnNoseCenter() 
{
	if (!m_bLeftEyeOK)
	{
		AfxMessageBox("Please detect eyes first!");
		return;
	}
	//眼睛,嘴巴和鼻孔的倾斜角度
	double tanEye,tanMouth,tanNose;
	if (m_RightEye.y == m_LeftEye.y) tanEye = 0;
	else tanEye = double((m_RightEye.y - m_LeftEye.y))/(m_RightEye.x - m_LeftEye.x);
	if (m_RightMouthCorner.y == m_LeftMouthCorner.y) tanMouth = 0;
	else tanMouth = double((m_RightMouthCorner.y - m_LeftMouthCorner.y))/(m_RightMouthCorner.x - m_LeftMouthCorner.x);

	// 确定鼻子的水平区域在1/2和1/3之间, 竖直在两眼之间
	int NoseUp    = (m_rFaceArea.bottom + m_rFaceArea.top)/2 + m_nBmpWidth/30;
	int NoseDown  = m_rFaceArea.bottom - (m_rFaceArea.bottom - m_rFaceArea.top)/3+ m_nBmpWidth/30;
	int NoseLeft  = m_LeftMouthCorner.x;
	int NoseRight = m_RightMouthCorner.x;
	//鼻子区域的gray空间
	SetPixelValArray(m_tPixelOfRefBmpArray,0);
	double threshold = 100;
	double Y;
	bool findnose = false;
	
	while (!findnose)
	{
		for(int i=NoseUp; i<NoseDown; i++)
		{
			for(int j=NoseLeft; j<NoseRight; j++)
			{
				Y = 0.30*m_tPixelOfOriBmpArray[i][j].rgbRed+0.59*m_tPixelOfOriBmpArray[i][j].rgbGreen
					+0.11*m_tPixelOfOriBmpArray[i][j].rgbBlue;
				m_tPixelOfRefBmpArray[i][j].rgbBlue = 0.30*m_tPixelOfOriBmpArray[i][j].rgbRed+0.59*m_tPixelOfOriBmpArray[i][j].rgbGreen
					+0.11*m_tPixelOfOriBmpArray[i][j].rgbBlue;//用于后面的调整

				if(Y<threshold)
				{
					m_tPixelOfRefBmpArray[i][j].rgbRed = 255;  
				}
				else m_tPixelOfRefBmpArray[i][j].rgbRed = 0;
			}
		}
		//left nosestrill
		
		bool noseL = false;
		for(int j=NoseLeft; j<(m_LeftMouthCorner.x + m_RightMouthCorner.x)/2; j++)
		{
			for(i=NoseDown; i>NoseUp; i--)
			{
				if (m_tPixelOfRefBmpArray[i][j].rgbRed == 255)
				{
					m_LeftNostril.x = j;
					m_LeftNostril.y = i;
					noseL = true;
					break;
				}
			}
			if (noseL) break;
		}
		// right nostrill
		bool noseR = false;
		for(j=NoseRight; j>(m_LeftMouthCorner.x + m_RightMouthCorner.x)/2; j--)
		{
			for(i=NoseDown; i>NoseUp; i--)
			{
				if (m_tPixelOfRefBmpArray[i][j].rgbRed == 255)
				{
					m_RightNostril.x = j;
					m_RightNostril.y = i;
					noseR = true;
					break;
				}
			}
			if(noseR) break;
		}
		//only find left nostrill
		if (noseL && !noseR)
		{
			m_RightNostril.y = m_LeftNostril.y;
			m_RightNostril.x = m_LeftNostril.x + 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
			noseR = true;
			findnose = true;
		}
		//only find right nostrill
		if (noseR && !noseL) 
		{
			m_LeftNostril.y = m_RightNostril.y;
			m_LeftNostril.x = m_RightNostril.x - 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
			noseL = true;
			findnose = true;
		}
		//both are not found
		if (!noseR && !noseL)
		{
			threshold += 20;//调整阈值
//			AfxMessageBox("cannt find nose feature, please try the other method!");
//			return;
		}
		if (noseL && noseR)
		{
			if (m_RightNostril.y == m_LeftNostril.y) tanNose = 0;
			else tanNose = double((m_RightNostril.y - m_LeftNostril.y))/(m_RightNostril.x - m_LeftNostril.x);
			//修正鼻孔定的过于倾斜
			if (fabs(tanNose - tanEye)>=0.1)
			{
				if (double(m_LeftMouthCorner.y - m_LeftNostril.y)/(m_LeftMouthCorner.y-m_LeftEye.y)<0.2
					|| double(m_LeftNostril.y-m_LeftEye.y)/(m_LeftMouthCorner.y-m_LeftEye.y)<0.3)
				{
					m_LeftNostril.y = m_RightNostril.y;
					m_LeftNostril.x = m_RightNostril.x - 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
				}
				else if (double(m_RightMouthCorner.y - m_RightNostril.y)/(m_RightMouthCorner.y-m_RightEye.y)<0.2
					|| double(m_RightNostril.y-m_RightEye.y)/(m_RightMouthCorner.y-m_RightEye.y)<0.3)
				{
					m_RightNostril.y = m_LeftNostril.y;
					m_RightNostril.x = m_LeftNostril.x + 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
				}
				else if ((m_RightMouthCorner.y - m_RightNostril.y)<(m_LeftMouthCorner.y - m_LeftNostril.y))
				{
					m_LeftNostril.y = m_RightNostril.y;
					m_LeftNostril.x = m_RightNostril.x - 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
				}
				else if ((m_RightMouthCorner.y - m_RightNostril.y)<(m_LeftMouthCorner.y - m_LeftNostril.y))
				{
					m_LeftNostril.y = m_RightNostril.y;
					m_LeftNostril.x = m_RightNostril.x - 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
				}
			}

			m_bLeftNostrilOK = TRUE;
			m_bRightNostrilOK = TRUE;
			findnose = true;
		}
	}
	//一般而言,鼻孔的位置会定在外边缘,向里可能5象素调整
	double sumL1 = 0, sumR1 = 0, sumL2 = 0, sumR2 = 0;
	for(int i=-3; i<=3; i++)
	{
		for(int j=-3; j<=3;j++)
		{
			sumL1 += m_tPixelOfRefBmpArray[m_LeftNostril.y+i][m_LeftNostril.x+j].rgbBlue;
			sumL2 += m_tPixelOfRefBmpArray[m_RightNostril.y+i][m_RightNostril.x+j].rgbBlue;
			sumR1 += m_tPixelOfRefBmpArray[m_LeftNostril.y+i][m_LeftNostril.x + 5 + j].rgbBlue;
			sumR2 += m_tPixelOfRefBmpArray[m_RightNostril.y+i][m_RightNostril.x + 5 + j].rgbBlue;
		}
	}
	if (sumL2<sumL1) m_LeftNostril.x  += 5;
	if (sumR2<sumR1) m_RightNostril.x -= 5;
	//调整在人脸偏转情况下,定位在同一个鼻孔
	if ((m_RightNostril.x - m_LeftNostril.x)<=18 ) 
	{
		if ((m_RightMouthCorner.x-(m_RightNostril.x-m_LeftNostril.x)/2)>(m_LeftNostril.x-(m_RightNostril.x-m_LeftNostril.x)/2))
			m_LeftNostril.x = m_RightNostril.x - 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
		else
			m_RightNostril.x = m_LeftNostril.x + 0.6*(m_RightMouthCorner.x - m_LeftMouthCorner.x);
	}
	//对于基本正面的图像,鼻孔的距离眼睛的高度大于距离嘴巴的高度
	//一下属于强制措施,可以考虑改进
	if ((double(m_LeftMouthCorner.y - m_LeftNostril.y)/(m_LeftMouthCorner.y-m_LeftEye.y)<0.2)
		&& (double(m_RightMouthCorner.y - m_RightNostril.y)/(m_RightMouthCorner.y-m_RightEye.y)<0.2))
	{
		m_LeftNostril.x  = m_LeftMouthCorner.x + 0.2*(m_RightNostril.x - m_LeftNostril.x);
		m_LeftNostril.y  = m_LeftMouthCorner.y - (m_LeftMouthCorner.y - m_LeftEye.y)/3;
		m_RightNostril.x = m_RightNostril.x - 0.2*(m_RightNostril.x - m_LeftNostril.x);
		m_RightNostril.y = m_LeftNostril.y;
	}
	if ((m_LeftMouthCorner.y - m_LeftNostril.y)>(m_LeftNostril.y-m_LeftEye.y)
		&& (m_RightMouthCorner.y - m_RightNostril.y)>(m_RightNostril.y-m_RightEye.y)) 
	{
		m_LeftNostril.x  = m_LeftMouthCorner.x + 0.2*(m_RightNostril.x - m_LeftNostril.x);
		m_LeftNostril.y  = m_LeftMouthCorner.y - (m_LeftMouthCorner.y - m_LeftEye.y)/3;
		m_RightNostril.x = m_RightNostril.x - 0.2*(m_RightNostril.x - m_LeftNostril.x);
		m_RightNostril.y = m_LeftNostril.y;
	}
	CopyBitMap(m_tPixelOfRefBmpArray,m_tPixelOfOriBmpArray);
	CreateBitMap();
	cvReleaseImage(&image);
	cvReleaseImage(&grayimg);
	cvReleaseImage(&edgeimg);
	
}

void CFacialFeatureDlg::LightCompensation()
{
	//对图像进行亮度gamma校正
	int sumWhitePixel = 0;
	
}

⌨️ 快捷键说明

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