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

📄 facedetectiondoc.cpp

📁 人脸识别,希望对大家有所帮助!它的应用将扩展到教育、培训和娱乐等新的领域。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					eye1count++;
					//把当前点改成白色
					*(lpData + lOffset++) = 255;
					*(lpData + lOffset++) = 255;
					*(lpData + lOffset++) = 255;

				}
				//如果当前象素的数值为2
				else if(*(lpData + lOffset) == 2)
				{	
					//眼睛2的横坐标和纵坐标加上当前点的坐标值
					eye2.x +=j;
					eye2.y +=i;
					//象素点个数加一
					eye2count++;
					//把当前点设置为白色
					*(lpData + lOffset++) = 255;
					*(lpData + lOffset++) = 255;
					*(lpData + lOffset++) = 255;
				}
			}
			//计算眼睛的中心点坐标
			eye1.x /=eye1count;
			eye1.y /=eye1count;
			eye2.x /=eye2count;
			eye2.y /=eye2count;
			//把中心点设置为绿色
			lOffset = eye1.y*wBytesPerLine + eye1.x*3; 
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;

			lOffset = eye2.y*wBytesPerLine + eye2.x*3; 
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;
	::GlobalUnlock((HGLOBAL) m_hDIB);
}

void  CFaceDetectionDoc::FunctionMouseMap(LPBYTE lpRgb, const LPBYTE lpYcc,  WORD wBytesPerLine, CRect faceLocation)
{	
	//下面的循环在人脸的区域内实现嘴巴的匹配
	for (int i=faceLocation.top; i<faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<faceLocation.right; j++)
		{	
			//得到偏移
			long lOffset = i*wBytesPerLine + j*3;
			//得到cr,cb的数值
			int cr = *(lpYcc+lOffset+1);
			int cb = *(lpYcc+lOffset+2);
			//标志
			bool lab;
			int mapm;
			//根据cr的数值设定标志
			cr = cr-157;//143;
			if(cr <-6 || cr>6)
			{
				cr = 0;
				
			}
			cr *=cr;
			
			if(cr>16)
				 lab = true;
			else
				lab = false;
			//根据cb的时值设定标志
			cb= cb-118;//120;
			if(cb<-5 || cb >5)
				
			{
				cb = 0;
				if(lab = true)
					lab = false;
			}
			//如果cr,cb两项数值都在设定的范围之内,则设定颜色位白色,否则黑色
			if(lab)
				mapm = 255;
			else
				mapm = 0;
			 
			*(lpRgb + lOffset++) = mapm;
			*(lpRgb + lOffset++) = mapm;
			*(lpRgb + lOffset++) = mapm;

			
		}
}
void  CFaceDetectionDoc::MouseMap()
{
	LPBYTE lpYcc2;
	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);
	lpYcc2 = new BYTE[wBytesPerLine * height];
	RgbtoYcb(m_hDIBtemp,lpYcc2);
	FunctionMouseMap(lpData,lpYcc2,wBytesPerLine,CRect(0,0,width-1,height-1));
	::GlobalUnlock((HGLOBAL) m_hDIB);

}
void CFaceDetectionDoc::DeleteScatePoint()
{	
	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)
			{	
				//设定判断数组
				for(int ii = 0;ii<ImgRange;ii++)
					for (int jj=0; jj<ImgRange; jj++)
						this->lab[ii][jj] = false;
					//设定判断长度
					lenth=0;
					//判断是否为离散点
				bool judge = IsScaterPoint(j, i, width,height,lpData,wBytesPerLine,3,lab);
				if(!judge)
				{	
					//是离散点则把该点设置为黑色
					*(lpData + lOffset++) = 0;
					*(lpData + lOffset++) = 0;
					*(lpData + lOffset++) = 0;
				}
			}
		}
	::GlobalUnlock((HGLOBAL) m_hDIB);
}
BOOL CFaceDetectionDoc::IsScaterPoint(int x, int y, int width, int height, LPBYTE lpData,WORD wBytesPerLine,  int threshold,bool lab[m_HEIGHT][m_WIDTH])
{
	long lOffset;
	//得到数据的偏移
	lOffset = y*wBytesPerLine + x*3;
	//判断该点是否为白色以及是否计算过了
	if(*(lpData+lOffset) == 255 && lab[y][x] == false)
	{	
		//链长度加一
		lenth++;
		//更改标志位
		lab[y][x] = true;
		//如果链长度达到临界值则返回真
	if(lenth >= threshold)
		return true;
	//对右边点的边界判断以及标志位判断
	if(x+1<width && lab[y][x+1] == false)
	{	
		//递归调用本函数,对右边的点进行判断
		IsScaterPoint(x+1,y,width,height,lpData,wBytesPerLine,threshold,lab);
		if(lenth>=threshold)
			return true;
		
	}
	//处理左边的点
	if(x-1>=0 && lab[y][x-1] == false)
	{
		(IsScaterPoint(x-1,y,width,height,lpData,wBytesPerLine,threshold,lab));
		if(lenth>=threshold)
			return true;
		
	}
	//处理上面的点
	if(y-1>=0 && lab[y-1][x]==false)
	{
		(IsScaterPoint(x,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
		if(lenth>=threshold)
			return true;
		
	}
	//处理下面的点
	if(y+1<height && lab[y+1][x]==false)
	{	(IsScaterPoint(x,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(lenth>=threshold)
			return true;
			
	}
	//处理右下的点
	if(y+1<height  && x+1 <width && lab[y+1][x+1]==false)
	{	(IsScaterPoint(x+1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(lenth>=threshold)
			return true;
			
	}
	//处理左下的点
	if(y+1<height && x-1 >=0 && lab[y+1][x-1]==false)
	{	(IsScaterPoint(x-1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(lenth>=threshold)
			return true;
			
	}
	//处理左上的点
	if(y-1>=0 && x-1 >=0 &&lab[y-1][x-1]==false)
	{	(IsScaterPoint(x-1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(lenth>=threshold)
			return true;
			
	}
	//处理右上的点
	if(y-1<height && x+1<width && lab[y+1][x]==false)
	{	(IsScaterPoint(x+1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(lenth>=threshold)
			return true;
			
	}
	}	
		//如果递归结束,长度达不到临界值,返回假
		return false;
}

void CFaceDetectionDoc::MouthCenter(CPoint &mouthLocation)
{
	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);
	
	//下面的三个变量用来累计嘴巴区域的象素的x,y和象素点数
	int xnum = 0 ;
	int ynum = 0 ;
	int count = 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)
			{	
				//x值加
				xnum +=j;
				//y值加
				ynum +=i;
				//点数加
				count++;
			}
		}
		//得到中心点位置
	mouthLocation.x = xnum/count;
	mouthLocation.y = ynum/count;
	
	//把中心点设置位绿色
	lOffset = mouthLocation.y*wBytesPerLine + mouthLocation.x*3;
	*(lpData + lOffset++) =0;
	*(lpData + lOffset++) =255;
	*(lpData + lOffset++) =0;
	::GlobalUnlock((HGLOBAL) m_hDIB);
}
void CFaceDetectionDoc::EllipseFace(CPoint mouth, CPoint eye1, CPoint eye2,CRect faceLocation)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL) m_hDIBtemp);//读取头文件
	lLineBytesMulspec = WIDTHBYTES((lpbi->biWidth)*24);
	::GlobalUnlock((HGLOBAL) m_hDIBtemp);
	int width,height;
	long wBytesPerLine;
	LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIBtemp);	
	// 获取DIB宽度
	width= (int) ::DIBWidth(lpDIB);		
	// 获取DIB高度
	height= (int) ::DIBHeight(lpDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = lLineBytesMulspec;
	LPBYTE lpData;
	long lOffset;
	lpData = (unsigned char*)::FindDIBBits(lpDIB);
	
	//用dda算法画三角形
	DdaLine(mouth,eye1,lpData,wBytesPerLine);
	DdaLine(mouth,eye2,lpData,wBytesPerLine);
	DdaLine(eye1,eye2,lpData,wBytesPerLine);
	/*
	
	//椭圆的中心点和两个焦点坐标
	int ellipsecenter_x;
	int ellipsecenter_y;
	int ellipseFocusTop_x;
	int ellipseFocusTop_y;
	int ellipseFocusBottom_x;
	int ellipseFocusBottom_y;
	
	//根据眼睛和嘴巴的坐标计算椭圆的中心点坐标
	ellipsecenter_x = (eye1.x + eye2.x + mouth.x )/3;
	ellipsecenter_y = (eye1.y + eye2.y)/2 -abs(eye2.x - eye1.x)/2;

	//上面的焦点
	ellipseFocusTop_x = ellipsecenter_x;
	ellipseFocusBottom_x = ellipsecenter_x;

	//下面的焦点
	ellipseFocusTop_y =  ellipsecenter_y + (eye1.y +eye2.y)/2 -mouth.y;
	ellipseFocusBottom_y = ellipsecenter_y - ((eye1.y +eye2.y)/2 -mouth.y)+2;

	//长轴
	int a = (eye1.x-eye2.x)*2-2;
	
	for (int i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{	
			//得到一个点到两个焦点的距离和
			int lenth = sqrt(pow(j-ellipseFocusTop_x,2)+pow(i-ellipseFocusTop_y,2))
				+sqrt(pow(j-ellipseFocusBottom_x,2)+ pow(i-ellipseFocusBottom_y,2));
			//判断距离和与长轴的关系
			if(lenth<2*a+2 && lenth >2*a-2)
			{	
				//把点设置为绿色
				lOffset =i*wBytesPerLine + j*3;
				*(lpData + lOffset++) = 0;
				*(lpData + lOffset++) = 255;
				*(lpData + lOffset++) = 0;
			}
		}*/
		for (int j=faceLocation[0].top; j<faceLocation[0].bottom; j++)
		{	
			//把得到的人脸区域用绿色矩形标注,处理竖直的两条边
			lOffset = j*wBytesPerLine + faceLocation[0].left*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;
			lOffset = j*wBytesPerLine + faceLocation[0].right*3;
			*(lpData + lOffset++) = 0;
			*(lpData + lOffset++) = 255;
			*(lpData + lOffset++) = 0;

		}

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

		}
	

	::GlobalUnlock((HGLOBAL) m_hDIBtemp);
	m_hDIB = (HDIB)CopyHandle(m_hDIBtemp);

}


void CFaceDetectionDoc::DdaLine(CPoint from, CPoint end, LPBYTE lpData, WORD wBytesPerLine)
{	
	//x,y的增量
	float delta_x;
	float delta_y;
	//x,y的坐标
	float x;
	float y;
	//x,y上的差值
	int dx;
	int dy;
	//总的步长
	int steps;
	int k;
	//得到x,y的差值
	dx = end.x - from.x;
	dy = end.y - from.y;
	//判断x,y上的差值大小,确定步长
	if(abs(dx) > abs(dy))
	{
		steps = abs(dx);
	}
	else
	{
		steps = abs(dy);
	}

	//得到每次增量的大小
	delta_x = (float)dx / (float)steps;
	delta_y = (float)dy / (float)steps;
	//设定x,y的起点
	x = (float)from.x;
	y = (float)from.y;

	//设定初始点的颜色为绿色
	long lOffset = y*wBytesPerLine + x*3;
	*(lpData + lOffset++) = 0;
	*(lpData + lOffset++) = 255;
	*(lpData + lOffset++) = 0;

	//根据计算得到的步长,把直线上的点填充成绿色
	for (k=1;k<=steps; k++)
	{	
		//x,y分别加上各自的增量
		x+=delta_x;
		y+=delta_y;
		//设置点的颜色
		lOffset = y*wBytesPerLine + x*3;
		*(lpData + lOffset++) = 0;
		*(lpData + lOffset++) = 255;
		*(lpData + lOffset++) = 0;
	}
	
}

void CFaceDetectionDoc::OnFileSaveAs(LPCTSTR lpszPathName) 
{
	CFile file;
	if(!file.Open(lpszPathName, CFile::modeCreate |// 打开文件
	  CFile::modeReadWrite | CFile::shareExclusive))
	{
		return;// 返回FALSE
	}
	BOOL bSuccess = FALSE;	
	bSuccess = ::SaveDIB(m_hDIB, file);	// 保存图象	
	file.Close();// 关闭文件	
	SetModifiedFlag(FALSE);// 重置胀标记为FALSE
	if (!bSuccess)
	{			
		AfxMessageBox("保存BMP图象时出错");// 提示出错
	}	
	
}

⌨️ 快捷键说明

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