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

📄 facialfeaturedlg.cpp

📁 是一个人脸识别特征提取的Vc代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	return true;
}


void CFacialFeatureDlg::SetPixelValArray(RGBQUAD** target,int val)
{
	for (int i=0; i<m_nBmpHeigh; i++)
		for (int j=0; j<m_nBmpWidth; j++)
		{
			target[i][j].rgbBlue = val;
			target[i][j].rgbGreen = val;
			target[i][j].rgbRed = val;
		}
}


void CFacialFeatureDlg::DrawCross(CDC *pDC, CPoint point, COLORREF crColor)
{
	CPen pen,*oldPen;
	pen.CreatePen(PS_SOLID,1,crColor);
	oldPen = (CPen*)pDC->SelectObject(&pen);
	pDC->MoveTo(point.x-7,point.y);
	pDC->LineTo(point.x+7,point.y);
	pDC->MoveTo(point.x,point.y-7);
	pDC->LineTo(point.x,point.y+7);
	pDC->SelectObject(oldPen);
	pen.DeleteObject();
}



void CFacialFeatureDlg::OnFaceDetect() 
{
	// TODO: Add your control notification handler code here
	LightCompensation();
	ConverFromDib();
	
	CvCapture* capture = 0;
	CvHaarClassifierCascade* cascade =
			cvLoadHaarClassifierCascade("<default_face_cascade>",
			cvSize(ORIG_WIN_SIZE, ORIG_WIN_SIZE));
	hid_cascade = cvCreateHidHaarClassifierCascade(cascade, 0, 0, 0, 1);
	cvReleaseHaarClassifierCascade(&cascade);

	storage = cvCreateMemStorage(0);

//	IplImage* image = pDoc->m_Image->GetImage();
	
	IplImage* temp = cvCreateImage(cvSize(image->width/2,image->height/2), 8, 3);
	if(image)
	{
		cvFlip(image, image, 0);
		image->origin = IPL_ORIGIN_BL;

		int scale = 2;
		CvPoint pt1, pt2;
	
		cvPyrDown(image, temp, CV_GAUSSIAN_5x5 );
#ifdef WIN32
		cvFlip(temp, temp, 0 );
#endif    
		cvClearMemStorage(storage);
		if(hid_cascade)
		{
			CvSeq* faces = cvHaarDetectObjects( temp, hid_cascade, storage,
				1.2, 2, CV_HAAR_DO_CANNY_PRUNING );
			for(int i = 0; i < (faces ? faces->total : 0); i++ )
			{
				CvRect* r = (CvRect*)cvGetSeqElem( faces, i, 0 );
				pt1.x = r->x * scale;
				pt2.x = (r->x+r->width) * scale;
#ifdef WIN32            
				pt1.y = image->height - r->y * scale;
				pt2.y = image->height - (r->y+r->height) * scale;
#else
				pt1.y = r->y*scale;
				pt2.y = (r->y+r->height) * scale;
#endif            
				

//////////////////////////////////////////////////////////////////////////
				// Display the faces in the image
				{
					CvRect region; 
					region.x = pt1.x;
					region.y = r->y*scale;
					region.width = r->width * scale;
					region.height = r->height * scale;

					///zzl
					m_rFaceArea.top = pt1.y;
					m_rFaceArea.bottom = pt2.y;
					m_rFaceArea.left = pt1.x;
					m_rFaceArea.right = pt2.x;
					
			
					cvFlip(image, image, 0);
					image->origin = IPL_ORIGIN_TL;
					cvSetImageROI(image, region);

					IplImage* image1 = cvCreateImage(cvSize(r->width*scale,
						r->height*scale), image->depth, image->nChannels);

					cvCopy(image, image1);

					cvResetImageROI(image);
//					cvNamedWindow("face", 1); 
				
//					cvShowImage("face", image1);
					cvWaitKey(0);
					cvDestroyWindow("face");
					cvReleaseImage(&image1);
					
//					Invalidate();

					cvFlip(image, image, 0);
					image->origin = IPL_ORIGIN_BL;
					
				}
				
//////////////////////////////////////////////////////////////////////////

//				cvRectangle( image, pt1, pt2, CV_RGB(255,255,0), 3 );

			}
		
		}
		
        cvReleaseImage( &temp );

	int top,bottom,left,right,nFaceWidth;
	nFaceWidth = m_rFaceArea.right - m_rFaceArea.left;
	top = m_nBmpHeigh - m_rFaceArea.top;
	bottom = m_nBmpHeigh - m_rFaceArea.bottom;
	left = m_rFaceArea.left + nFaceWidth/8;
	right = m_rFaceArea.right - nFaceWidth/8;
	m_rAdaFaceArea = CRect(left-nFaceWidth/8,top,right+nFaceWidth/8,bottom);


/*
	for (int i=top; i<=bottom; i++)
	{
		m_tPixelOfRefBmpArray[i][left].rgbBlue = 0;
		m_tPixelOfRefBmpArray[i][left].rgbGreen = 0;
		m_tPixelOfRefBmpArray[i][left].rgbRed = 0;
		m_tPixelOfRefBmpArray[i][right].rgbBlue = 0;
		m_tPixelOfRefBmpArray[i][right].rgbGreen = 0;
		m_tPixelOfRefBmpArray[i][right].rgbRed = 0;
		m_tPixelOfRefBmpArray[i][(int)((m_rFaceArea.left +m_rFaceArea.right)/2)].rgbBlue = 0;
	}
*/
	
/*	for (j=left; j<=right; j++)
	{
		m_tPixelOfRefBmpArray[top - 5][j].rgbBlue = 0;
		m_tPixelOfRefBmpArray[top - 5][j].rgbGreen = 0;
		m_tPixelOfRefBmpArray[top - 5][j].rgbRed = 0;
		m_tPixelOfRefBmpArray[bottom][j].rgbBlue = 0;
		m_tPixelOfRefBmpArray[bottom][j].rgbGreen = 0;
		m_tPixelOfRefBmpArray[bottom][j].rgbRed = 0;
//		m_tPixelOfRefBmpArray[(int)(2*(m_rFaceArea.bottom - m_rFaceArea.top)/3) + m_rFaceArea.top][j].rgbRed = 0;
//		m_tPixelOfRefBmpArray[(int)((m_rFaceArea.bottom - m_rFaceArea.top)/3) + m_rFaceArea.top][j].rgbGreen = 0;

	}
*/
	//重新调整脸部区域的参数,方便进行特征的检测与定位


	CRect rect(left,top,right,bottom);
	m_rFaceArea = rect;
	m_bFaceOK = true;
	m_bShowFace = true;

	CreateBitMap();
	}
	
//	Invalidate();

}

void CFacialFeatureDlg::ConverFromDib()
{
	CvSize ImgSize;
	ImgSize.width = m_nBmpWidth;
	ImgSize.height = m_nBmpHeigh;
	image = cvCreateImage(ImgSize, IPL_DEPTH_8U, 3);
	
	BYTE* IplImg = (BYTE*)(image->imageData);
	for(int i = 0; i < m_nBmpHeigh; i++)
	for(int j = 0; j < m_nBmpWidth; j++)
	{
		IplImg[3*(j + i*m_nBmpWidth)]     = m_tPixelOfRefBmpArray[i][j].rgbBlue;
		IplImg[3*(j + i*m_nBmpWidth) + 1] = m_tPixelOfRefBmpArray[i][j].rgbGreen;
		IplImg[3*(j + i*m_nBmpWidth) + 2] = m_tPixelOfRefBmpArray[i][j].rgbRed;

	}

}

void CFacialFeatureDlg::OnEyeCenter() 
{
	// TODO: Add your control notification handler code here
	if (!(m_bFaceOK && m_bShowFace)) {
		AfxMessageBox("Please detect face first!");
		return;
	}
	int top,bottom,left,right,nFaceWidth;
	nFaceWidth = m_rFaceArea.right - m_rFaceArea.left;
	top = m_nBmpHeigh - m_rFaceArea.top;
	bottom = m_nBmpHeigh - m_rFaceArea.bottom;
	left = m_rFaceArea.left + nFaceWidth/8;
	right = m_rFaceArea.right - nFaceWidth/8;

	CPoint LeftEyeArea(-1,-1), RightEyeAre(-1,-1);
	//人脸区域参数的进一步细化
	int nLeft,nRight,nTop,nBottom;
	nLeft = m_rFaceArea.left + 2;
	nRight = m_rFaceArea.right - 2;
	nBottom = m_rFaceArea.bottom -2;
	nTop = m_rFaceArea.top + 2;
	//眼睛参数的大致估计:三庭五眼
	int nEyeWidth = 0.28*(nRight - nLeft);//0.28是一个经验数值,可以修改
	int nEyeHeigh = nEyeWidth/3;
	int nFaceCerH = (m_rFaceArea.right + m_rFaceArea.left)/2;
	int nFaceCerV = (m_rFaceArea.bottom + m_rFaceArea.top)/2;
	SetPixelValArray(m_tPixelOfRefBmpArray, 0);
	//将人脸区域转换为灰度
	for(int i=nTop; i<nBottom; i++)
	{
		for(int j=nLeft; j<nRight; j++)
		{
			m_tPixelOfRefBmpArray[i][j].rgbBlue = (unsigned char)(0.2989*m_tPixelOfOriBmpArray[i][j].rgbRed
				                                + 0.5870*m_tPixelOfOriBmpArray[i][j].rgbGreen
												+ 0.1140*m_tPixelOfOriBmpArray[i][j].rgbBlue);
		}
	}
	//在水平区域的1/2到1/3处、nLeft到face中线区域计算9×9区域的象素均值
	//lefteye
	int regionH = m_rFaceArea.top + (m_rFaceArea.bottom - m_rFaceArea.top)/3;
	double Lcomval = 255.0;
	for(int row=regionH+4; row<nFaceCerV-4; row++)
	{
		for(int col=nLeft+(nRight-nLeft)/8; col<nFaceCerH-(nRight-nLeft)/8; col++)
		{
			double meanpixel = 0;

			for(int p=-4; p<=4; p++)
			{
				for(int q=-4;q<=4;q++)
				{
					meanpixel += m_tPixelOfRefBmpArray[row+p][col+q].rgbBlue;
				}
			}
			meanpixel = meanpixel/81;
			if (meanpixel<Lcomval) 
			{
				Lcomval = meanpixel;
				LeftEyeArea.x = col;
				LeftEyeArea.y = row;
			}

		}
	}
//  righteye
	double Rcomval = 255.0;
	for(row=regionH+4; row<nFaceCerV-4; row++)
	{
		for(int col=nFaceCerH+(nRight-nLeft)/8; col<nRight-(nRight-nLeft)/8; col++)
		{
			double meanpixel = 0;

			for(int p=-4; p<=4; p++)
			{
				for(int q=-4;q<=4;q++)
				{
					meanpixel += m_tPixelOfRefBmpArray[row+p][col+q].rgbBlue;
				}
			}
			meanpixel = meanpixel/81;
			if (meanpixel<Rcomval) 
			{
				Rcomval = meanpixel;
				RightEyeAre.x = col;
				RightEyeAre.y = row;
			}

		}
	}
	//to detect eyecorners using canny
	grayimg = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U,1);
	edgeimg = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
	cvCvtColor(image,grayimg,CV_BGR2GRAY);
	cvCanny(grayimg,edgeimg,0,128,3);//0,128是经验值,程序死掉的地方之一
	cvFlip(edgeimg,edgeimg,0);
	BYTE* IplEdge = (BYTE*)edgeimg->imageData;
	SetPixelValArray(m_tPixelOfRefBmpArray,0);
	float zzl = 0;
	for(i=0; i<m_nBmpHeigh; i++)
	{
		for(INT j=0; j<m_nBmpWidth; j++)
			m_tPixelOfRefBmpArray[i][j].rgbBlue = IplEdge[j + i*m_nBmpWidth];
	}
	//搜索角点
	//左眼右眼角
	bool findcornerLr = false;
//	for(i=LeftEyeArea.x+nEyeWidth/2-2; i>LeftEyeArea.x-nEyeWidth/2; i--)
	for(i=LeftEyeArea.x+1.1*nEyeHeigh; i>LeftEyeArea.x+nEyeHeigh/2; i--)
	{
		for(int j=LeftEyeArea.y+nEyeWidth/4; j>LeftEyeArea.y; j--)
		{
			if (m_tPixelOfRefBmpArray[j][i].rgbBlue == 255) 
			{	
				findcornerLr = true;
				m_LeftEyeRightCorner.x=i;
				m_LeftEyeRightCorner.y=j;
				break;
			}
		}
		if (findcornerLr) {m_bLeftEyeRightCornerOK = TRUE; break;}
	}
	
	//左眼左眼角
	bool findcornerLl = false;
//	for(i=LeftEyeArea.x-nEyeWidth/2+5; i<LeftEyeArea.x+nEyeWidth/2; i++)
	for(i=LeftEyeArea.x-1.1*nEyeHeigh; i<LeftEyeArea.x+nEyeHeigh/2; i++)
	{
		for(int j=LeftEyeArea.y; j>LeftEyeArea.y-nEyeWidth/4; j--)
		{
			if (m_tPixelOfRefBmpArray[j][i].rgbBlue == 255) 
			{	
				findcornerLl = true;
				m_LeftEyeLeftCorner.x=i;
				m_LeftEyeLeftCorner.y=j+2;//2是一个经验值
				break;
			}
		}
		if (findcornerLl) {m_bLeftEyeLeftCornerOK = TRUE; break;}
	}
	
	//右眼左眼角
	bool findcornerRl = false;
//	for(i=RightEyeAre.x-nEyeWidth/2+2; i<RightEyeAre.x+nEyeWidth/2; i++)
	for(i=RightEyeAre.x-1.1*nEyeHeigh; i<RightEyeAre.x-nEyeHeigh/2; i++)
	{
		for(int j=RightEyeAre.y+nEyeWidth/4; j>RightEyeAre.y; j--)
		{
			if (m_tPixelOfRefBmpArray[j][i].rgbBlue == 255) 
			{	
				findcornerRl = true;
				m_RightEyeLeftCorner.x=i;
				m_RightEyeLeftCorner.y=j;
				break;
			}
		}
		if (findcornerRl) {m_bRightEyeLeftCornerOK = TRUE; break;}
	}
	
	//右眼右眼角
	bool findcornerRr = false;
//	for(i=RightEyeAre.x+nEyeWidth/2-2; i>RightEyeAre.x-nEyeWidth/2; i--)
	for(i=RightEyeAre.x+1.1*nEyeHeigh; i>RightEyeAre.x-nEyeHeigh/2; i--)

⌨️ 快捷键说明

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