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

📄 facedetectiondoc.cpp

📁 人脸识别,希望对大家有所帮助!它的应用将扩展到教育、培训和娱乐等新的领域。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	//左边的点
	tempy = y;
	tempx = x-1;
	RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
	//右边的点
	tempy = y;
	tempx = x+1;
	RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
	
	}

}

void  CFaceDetectionDoc::FaceLocate(CRect faceLocation[10], int &faceNum)
{	

	HANDLE  hDIBTemp;
	hDIBTemp = CopyHandle(m_hDIB);
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	//保存当前数据
	int width,height;
	LPBYTE lpData;
	long wBytesPerLine;
	wBytesPerLine = lLineBytesMulspec;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	//得到图片每行的象素所占字节个数
	long lOffset;
	//人脸数目初始化为0
	faceNum =0;
	for(int k=0; k<10; k++)
	{	
		//初始化区域
		faceLocation[k].bottom = -1;
		faceLocation[k].top = height;
		faceLocation[k].right = -1;
		faceLocation[k].left = width;
	}

	for(int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{	
			//偏移
			lOffset = i*wBytesPerLine + j*3;
			int num;
			//当前点的数值
			num = *(lpData + lOffset);
			if (num !=0)//不是黑色
			{	
				//递归计算
				RecursiveLocateRect(lpData, wBytesPerLine, i, j, num, faceLocation[faceNum]);
				faceNum++;
			}
		}
	::GlobalUnlock((HGLOBAL) m_hDIB);
	::GlobalFree((HGLOBAL) m_hDIB);
	//数值还原 
	m_hDIB = (HDIB)CopyHandle(hDIBTemp);
	LPSTR lpDIB2 = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
	lpData = (unsigned char*)::FindDIBBits(lpDIB2);
	for (i=0; i<faceNum; i++)
		for (int j=faceLocation[i].top; j<faceLocation[i].bottom; j++)
		{	
			//把得到的人脸区域用绿色矩形标注,处理竖直的两条边
			lOffset = j*wBytesPerLine + faceLocation[i].left*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;
			lOffset = j*wBytesPerLine + faceLocation[i].right*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;

		}

		for (i=0; i<faceNum; i++)
		for (int j=faceLocation[i].left; j<faceLocation[i].right; j++)
		{	
			//处理水平的两天矩形边
			lOffset = faceLocation[i].top*wBytesPerLine + j*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;
			lOffset = faceLocation[i].bottom*wBytesPerLine + j*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;

		}
	
		::GlobalFree((HGLOBAL)hDIBTemp);	
		::GlobalUnlock((HGLOBAL) m_hDIB);
}

HANDLE CFaceDetectionDoc::CopyHandle( HANDLE  hSrc)
{	
	HANDLE  hDst;
	LPBITMAPINFOHEADER lpbi;
	int width,height;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock(hSrc);
	width = lpbi->biWidth;
	height = lpbi->biHeight;
	hDst = ::GlobalAlloc(GMEM_MOVEABLE,lpbi->biSize+lpbi->biSizeImage);
	if(!hDst)
		return NULL;
	LPBYTE lpDest;
	lpDest = (LPBYTE)::GlobalLock(hDst);
	memcpy(lpDest,(LPBYTE)lpbi,lpbi->biSize+lpbi->biSizeImage);
	::GlobalUnlock(hSrc);
	::GlobalUnlock(hDst);
	return hDst;
}
void CFaceDetectionDoc::RecursiveLocateRect(LPBYTE lpData,WORD wBytesPerLine, int y, int x, int num, CRect &faceRect)
{	
	long lOffset;
	//得到偏移
	lOffset = y*wBytesPerLine + x*3;
	//数值判断
	if(*(lpData + lOffset) == num)
	{	
		//更改颜色为黑色
		*(lpData + lOffset++) = 0;
		*(lpData + lOffset++) = 0;
		*(lpData + lOffset++) = 0;
		//修改矩形的上下左右四个点位置
		if(faceRect.bottom < y)
		{
			faceRect.bottom = y;
		}

		if(faceRect.top > y)
		{
			faceRect.top = y;
		}

		if(faceRect.right < x)
		{
			faceRect.right = x;
		}

		if(faceRect.left > x)
		{
			faceRect.left = x;
		}
		//上下左右调用本函数进行区域判定
		RecursiveLocateRect(lpData, wBytesPerLine, y-1, x, num,faceRect);
		RecursiveLocateRect(lpData, wBytesPerLine, y+1, x, num, faceRect);
		RecursiveLocateRect(lpData, wBytesPerLine, y, x-1, num, faceRect);
		RecursiveLocateRect(lpData, wBytesPerLine, y, x+1, num, faceRect);
	}
	
}
void CFaceDetectionDoc::EyeMapR(LPBYTE lpRgb, const LPBYTE lpYcc,  WORD wBytesPerLine, CRect faceLocation)
{
	long lOffset;
	int cr;
	int cb;

	for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<=faceLocation.right; j++)
		{
			lOffset =i*wBytesPerLine + j*3;
			cr = *(lpYcc + lOffset +1);
			cb = *(lpYcc + lOffset +2);
			*(lpRgb + lOffset++) = cr;
			*(lpRgb + lOffset++) = cr;
			*(lpRgb + lOffset++) = cr;
		}
	
}
void CFaceDetectionDoc::Crmap()
{
	LPBYTE lpRB;
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	LPBYTE lpData;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	lpRB = new BYTE[wBytesPerLine * height];
	RgbtoYcb(m_hDIB,lpRB);
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	EyeMapR(lpData,lpRB,wBytesPerLine,CRect(0,0,width-1,height-1));
	::GlobalUnlock((HGLOBAL) m_hDIB);
}
void CFaceDetectionDoc::EyeMapC(LPBYTE lpRgb, const LPBYTE lpYcc,  WORD wBytesPerLine, CRect faceLocation)
{
	long lOffset;
	int cr;
	int cb;
	//根据传进来的矩形区域进行眼睛的色度匹配
	for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<=faceLocation.right; j++)
		{	
			//得到Cr,Cb数值
			lOffset = i*wBytesPerLine + j*3;
			cr = *(lpYcc + lOffset +1);
			cb = *(lpYcc + lOffset +2);
			//标志
			bool lab;
			//判断Cb分量的数值,并修改标志
			int cmap = cb -120;//116 ;
			if(cmap >-1 && cmap <4)
				lab = true;
			else
				lab = false;
			//判断Cr分量的数值,并修改标志
			 cmap =  cr- 143;//144  ;
			if(cmap <=-2 || cmap>= 2)
			{
				lab = false;
				
			}
			//根据标志设定图像颜色
			if(lab)
				cmap = 255;
			else
				cmap = 0;
			//保存图象颜色
			*(lpRgb + lOffset++) = cmap;
			*(lpRgb + lOffset++) = cmap;
			*(lpRgb + lOffset++) = cmap;
		}	
}
void CFaceDetectionDoc::EyeMappingC()//调用EyeMapC函数进行眼睛的色度匹配
{
	LPBYTE lpYcc2;
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	LPBYTE lpData;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	lpYcc2 = new BYTE[wBytesPerLine * height];
	RgbtoYcb( m_hDIBtemp,lpYcc2);//转化为YCC空间
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	//memcpy(lpData,gDib.YcctoRgb(lpYcc,gwBytesPerLine,gheight,gwidth),gwBytesPerLine*gheight);
	EyeMapC(lpData,lpYcc2,wBytesPerLine,CRect(0,0,width-1,height-1));
	for(int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{
			long lOffset;
			lOffset = i*wBytesPerLine + j*3;
			if(*(lpData + lOffset) == 255)
			{
				emymapc[i][j] = true;
			}
		}
	::GlobalUnlock((HGLOBAL) m_hDIB);
}

void CFaceDetectionDoc::EyeMapL(LPBYTE lpRgb, WORD wBytesPerLine, CRect faceLocation)
{
	int r;
	int g;
	int b;
	int gray ;
	long lOffset;
	//下面的循环实现眼睛的亮度匹配
	for (int i=faceLocation.top; i<=faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<=faceLocation.right; j++)
		{
			lOffset = i*wBytesPerLine + j*3;
			//得到rgb值
			b = *(lpRgb + lOffset);
			g = *(lpRgb + lOffset+1);
			r = *(lpRgb + lOffset+2);
			//计算得到灰度
			gray = (r*10+g*30+b*60)/100;
			//根据眼睛的亮度区域来设定图象的数值
			if(/*100*/120<gray && /*125*/160>gray)
				gray =255;
			else
				gray = 0;
			*(lpRgb + lOffset++) = gray;
			*(lpRgb + lOffset++) = gray;
			*(lpRgb + lOffset++) = gray;
		}
}
void CFaceDetectionDoc::EyeMappingL()//调用EyeMapC函数进行眼睛的色度匹配
{
	LPBYTE lpYcc2;
	LPBYTE lpDataR,lpDataD;
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	LPBYTE lpData;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
	LPSTR lpDIBtemp = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIBtemp);
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	lpYcc2 = new BYTE[wBytesPerLine * height];
	lpDataR = (unsigned char*)::FindDIBBits(lpDIBtemp);
	RgbtoYcb(m_hDIBtemp,lpYcc2);
	lpDataD = (unsigned char*)::FindDIBBits(lpDIB);
	memcpy(lpDataD,lpDataR,wBytesPerLine*height);
	EyeMapL(lpDataD,wBytesPerLine, CRect(0,0,width-1,height-1));
	for (int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{
			long lOffset;
			lOffset =  i*wBytesPerLine + j*3;
			if(*(lpDataD + lOffset) == 255)
			{
				emymapl[i][j] = true;
			}
		}
	::GlobalUnlock((HGLOBAL) m_hDIB);
	::GlobalUnlock((HGLOBAL) m_hDIBtemp);
}

void CFaceDetectionDoc::Eyemap() 
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	LPBYTE lpData;
	long lOffset;
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	for (int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{
			lOffset =  i*wBytesPerLine + j*3;
			if( emymapc[i][j] && emymapl[i][j])
			{
				*(lpData + lOffset++) = 255;
				*(lpData + lOffset++) = 255;
				*(lpData + lOffset++) = 255;
			}

			else
			{
				*(lpData + lOffset++) = 0;
				*(lpData + lOffset++) = 0;
				*(lpData + lOffset++) = 0;
			}
		}
}
void CFaceDetectionDoc::DeleteFasleEye(CRect facelocation)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	LPBYTE lpData;
	long lOffset;
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	for (int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{
			lOffset =  i*wBytesPerLine + j*3;
			if(*(lpData + lOffset) == 255)
			{
				if(i<(facelocation.bottom+facelocation.top)/2)
				{
					*(lpData + lOffset++) = 0;
					*(lpData + lOffset++) = 0;
					*(lpData + lOffset++) = 0;
				}
			}
		}
	::GlobalUnlock((HGLOBAL) m_hDIB);
}

void CFaceDetectionDoc::EyeCenter(CPoint &eye1, CPoint &eye2)
{
	
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIB);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIB);
	int width,height;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	LPBYTE lpData;
	long lOffset;
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	
	int pixelnum =0;
	int num =0;
	CRect faceLocation(0,0,width-1,height-1);
	//考察人脸区域
	for(int i=faceLocation.top; i<faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<faceLocation.right; j++)
		{
			lOffset =  i*wBytesPerLine + j*3;
			//白色点
			if(*(lpData + lOffset) == 255)
				//递归统计象素并修改象素值
				RecursiveCal(lpData,i,j,wBytesPerLine,pixelnum,++num);
		}
		//初始化眼睛的坐标
		eye1.x =0;
		eye1.y =0;
		eye2.x =0;
		eye2.y =0;
		//初始化象素点个数
		int eye1count=0;
		int eye2count =0;
		for (i=faceLocation.top; i<faceLocation.bottom; i++)
			for (int j=faceLocation.left; j<faceLocation.right; j++)
			{
				lOffset =  i*wBytesPerLine + j*3;
				//如果象素点的数值为1
				if(*(lpData + lOffset) == 1)
				{	
					//眼睛1的横坐标和纵坐标加上当前点的坐标值
					eye1.x +=j;
					eye1.y +=i;

⌨️ 快捷键说明

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