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

📄 dib.cpp

📁 一个简单的基于肤色模型的人脸检测程序。基于DSPTMSP6711;
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			//判断Cr分量的数值,并修改标志
			 cmap =  cr- 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 DIB::EyeMapb(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 = PixelOffset(i, j, wBytesPerLine);
			cb = *(lpYcc + lOffset +2);
		

			*(lpRgb + lOffset++) = cb;
			*(lpRgb + lOffset++) = cb;
			*(lpRgb + lOffset++) = cb;
		}
	
}

void DIB::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 = PixelOffset(i, j, wBytesPerLine);
			cr = *(lpYcc + lOffset +1);
			cb = *(lpYcc + lOffset +2);
		
			
			*(lpRgb + lOffset++) = cr;
			*(lpRgb + lOffset++) = cr;
			*(lpRgb + lOffset++) = cr;
		}
	
}

void DIB::ErasionFalseArea(HANDLE hDIB)
{
	int PixelNum[255];
	LPBITMAPINFOHEADER lpbi;
	int width;
	int height;
	LPBYTE lpData;
	WORD wBytesPerLine;
	long lOffset;
	//得到长宽信息
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	height = lpbi->biHeight;
	width  = lpbi->biWidth;
	//得到数据区指针和每行字节数
	lpData = FindDIBBits(hDIB);
	wBytesPerLine = BytePerLine(hDIB);
	//初始化象素累计数组
	for (int i=0; i<255; i++)
	{
		PixelNum[i] = 0;
	}
	
	int calNum =1;
	for (i=0; i<height; i++)
		for (int j=0; j<width; j++)
		{
			lOffset = PixelOffset(i,j,wBytesPerLine);
			//如果象素为白色
			if (*(lpData + lOffset)==255)
			{	
				//递归统计该区域连续的白色点象素点个数
				RecursiveCal(lpData, i,j,wBytesPerLine, PixelNum[calNum],calNum);
				calNum++;
			}
		}
		
		for (i=0; i<calNum; i++)
		{	
			//如果象素点个数小于一定数目则把这个标志设置为0
			if (PixelNum[i] < AREAPIXEL)
			{
				PixelNum[i] = 0;
			}
		}
		//下面的循环根据标志数组来最终设定图象的颜色
		for(i=0; i<height; i++)
			for (int j=0; j<width; j++)
			{
				lOffset = PixelOffset( i,j,wBytesPerLine);
				int num = *(lpData + lOffset);
				//如果当前点不是黑色点
				if(num != 0)
				{	
					//如果标志数组为0,则设置为黑色
					if(PixelNum[num] == 0)
					{
						*(lpData+lOffset++) =0;
						*(lpData+lOffset++) =0;
						*(lpData+lOffset++) =0;
					}
					//否则设置为白色
					else
					{
						*(lpData+lOffset++) =255;
						*(lpData+lOffset++) =255;
						*(lpData+lOffset++) =255;
					}
				}
			}
}


void DIB::RecursiveCal(LPBYTE lpData, int y, int x, WORD wBytesPerLine, int &pixelNum, int num)
{	
	long lOffset;
	
	lOffset = PixelOffset(y,x,wBytesPerLine);
	//如果当前点为白色点
	if(*(lpData+lOffset) == 255)
	{	
		//把当前点大小设置成为序号值
		*(lpData+lOffset++) = num;
		*(lpData+lOffset++) = num;
		*(lpData+lOffset++) = num;
		//象素个数加一
		pixelNum++;
	
	int tempx;
	int tempy;
	
	//递归当前点上面的点
	tempy = y-1;
	tempx = x;
	RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
	
	//下面的点
	tempy = y+1;
	tempx = x;
	RecursiveCal(lpData,tempy,tempx,wBytesPerLine,pixelNum,num);
	
	//左边的点
	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 DIB::eyeMap(LPBYTE lpResult, bool eyemapc[][ImgRange], bool eyemapl[][ImgRange], bool lab[][ImgRange], WORD wBytesPerLine, CRect faceLocation)
{	
	long lOffset;
	//根据得到的亮度和色度信息对眼睛进行综合匹配
	for(int i=faceLocation.top; i<=faceLocation.bottom; i++)
		for (int j=faceLocation.left; j<faceLocation.right; j++)
		{
			lOffset = PixelOffset(i, j, wBytesPerLine);
			//如果当前点的亮度和色度匹配都为真,并且在人脸区域内
			//就设置为白色,否则设置为黑色
			if((eyemapc[i][j]) && (eyemapl[i][j]) && lab[i][j])
			{
				*(lpResult + lOffset++) = 255;
				*(lpResult + lOffset++) = 255;
				*(lpResult + lOffset++) = 255;
			}

			else
			{
				*(lpResult + lOffset++) = 0;
				*(lpResult + lOffset++) = 0;
				*(lpResult + lOffset++) = 0;
			}
		}
}

void DIB::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 = PixelOffset(i, j, wBytesPerLine);
			//得到rgb值
			b = *(lpRgb + lOffset);
			g = *(lpRgb + lOffset+1);
			r = *(lpRgb + lOffset+2);
			//计算得到灰度
			gray = (r*10+g*30+b*60)/100;
			//根据眼睛的亮度区域来设定图象的数值
			if(100<gray && 125>gray)
				gray =255;
			else
				gray = 0;
			*(lpRgb + lOffset++) = gray;
			*(lpRgb + lOffset++) = gray;
			*(lpRgb + lOffset++) = gray;
		}
}

void  DIB::RgbtoYcb(HANDLE hDIB, LPBYTE lpYcb)
{
	LPBITMAPINFOHEADER lpbi;
	int width,height;
	WORD wBytesPerLine;
	LPBYTE lpData;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	//得到图象的基本信息
	width = lpbi->biWidth;
	height = lpbi->biHeight;
	lpData = FindDIBBits(hDIB);
	wBytesPerLine = BytePerLine(hDIB);

	long lOffset;
	//下面的循环实现从rgb到ycc的转化
	for(int i=0;i<height;i++)
		for(int j=0;j<width;j++)
		{
				lOffset = PixelOffset(i,j,wBytesPerLine);
				//得到rgb数值
				int b = *(lpData + lOffset);
				int g = *(lpData + lOffset+1);
				int r = *(lpData + lOffset+2);
				//计算得到y,cr,cb的数值
				int Y = (257*r+504*g+98*b)/1000+16;
				int Cr = (439*r-368*g-71*b)/1000+128;
				int Cb = (-148*r-291*g+439*b)/1000+128;
				//保存计算得到的数值
				*(lpYcb+lOffset++) = Y;
				*(lpYcb+lOffset++) = Cr;
				*(lpYcb+lOffset++) = Cb;

		}
		GlobalUnlock(hDIB);

}

void DIB::Erasion(HANDLE hDIB)
{
	LPBITMAPINFOHEADER lpbi;
	LPBYTE lpData;
	WORD wBytesPerLine;
	long lOffset;
	long lOffsetJudge;
	int height;
	int width;
	
	//得到基本数据
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	height = lpbi->biHeight;
	width = lpbi->biWidth;
	wBytesPerLine = BytePerLine(hDIB);
	lpData = FindDIBBits(hDIB);
	
	HANDLE hTempDIB;
	LPBYTE lpTemp;
	//申请同样大小的内存
	hTempDIB =   GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
	//判断内存情况
	if(!hTempDIB)
	{	
		GlobalFree(hTempDIB);
		GlobalFree(hDIB);
		return;
	}
	lpTemp = (LPBYTE)GlobalLock(hTempDIB);
	lpTemp+= sizeof(BITMAPINFOHEADER);
	//下面的循环实现腐蚀功能
	for (int i=1; i<height-1; i++)
		for (int j=1; j<width-1; j++)
		{
			lOffset = PixelOffset(i,j,wBytesPerLine);
			//如果为白色点
			if (*(lpData+lOffset) == 255)
			{	
				//考察上面的点
				lOffsetJudge = PixelOffset(i-1, j, wBytesPerLine);
				//如果是黑色就把原来的点设置为黑色,并接着循环
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}
				//考察下面的点
				lOffsetJudge = PixelOffset(i+1, j, wBytesPerLine);
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}
				//左面的点
				lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}
				//右面的点
				lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}
				//如果上下左右四个点都是白色,则设置为白色
				lOffset = this->PixelOffset(i, j, wBytesPerLine);
				*(lpTemp + lOffset)   = 255;
				*(lpTemp + lOffset+1) = 255;
				*(lpTemp + lOffset+2) = 255;
				
			}
			//如果当前点为黑色,则在暂时的目标区域中设置为黑色
			else
			{
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;
			}
		}
		
		//把图象周边的点全部设置为黑色
		for(i=0; i<height; i++)
		{
			lOffset = PixelOffset(i, 0, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
		
		for(i=0; i<height; i++)
		{
			lOffset = PixelOffset(i, width-1, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}

	for (i=0; i<width; i++)
		{
			lOffset = PixelOffset(0, i, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
	
	for (i=0; i<width; i++)
		{
			lOffset = PixelOffset(height-1, i, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
	//把暂时区域的数值拷贝到原来的句柄下面
	memcpy(lpData,lpTemp,wBytesPerLine*height);
	GlobalUnlock(hDIB);
	GlobalUnlock(hTempDIB);
	GlobalFree(hTempDIB);

}


void DIB::Erasion2(HANDLE hDIB)
{
	LPBITMAPINFOHEADER lpbi;
	LPBYTE lpData;
	WORD wBytesPerLine;
	long lOffset;
	long lOffsetJudge;
	int height;
	int width;

	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	height = lpbi->biHeight;
	width = lpbi->biWidth;
	wBytesPerLine = BytePerLine(hDIB);
	lpData = FindDIBBits(hDIB);
	
	HANDLE hTempDIB;
	LPBYTE lpTemp;
	//申请相同大小的内存
	hTempDIB =   GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
	if(!hTempDIB)
	{	
		GlobalFree(hTempDIB);
		GlobalFree(hDIB);
		return;
	}
	lpTemp = (LPBYTE)GlobalLock(hTempDIB);
	lpTemp+= sizeof(BITMAPINFOHEADER);
	//下面的代码实现腐蚀功能
	for (int i=1; i<height-1; i++)
		for (int j=1; j<width-1; j++)
		{	
			//如果当前点为白色
			lOffset = PixelOffset(i,j,wBytesPerLine);
			if (*(lpData+lOffset) == 255)
			{
				
				//判断左边的带你,如果是黑色的就把暂时区域中的对应点设置为黑色
				lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}
				//考察右边的点
				lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
				if (*(lpData + lOffsetJudge) ==0)
				{
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					*(lpTemp + lOffset++) = 0;
					continue;
				}

				//如果左右两边的点都是白色把点设置为白色
				lOffset = this->PixelOffset(i, j, wBytesPerLine);
				*(lpTemp + lOffset)   = 255;
				*(lpTemp + lOffset+1) = 255;
				*(lpTemp + lOffset+2) = 255;
				
			}
			//如果当前点为黑色,则把暂时区域中对应点设置为黑色
			else
			{
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;
			}
		}
		//把图象四周的点设置为黑色
		for(i=0; i<height; i++)
		{
			lOffset = PixelOffset(i, 0, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
		
		for(i=0; i<height; i++)
		{
			lOffset = PixelOffset(i, width-1, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}

	for (i=0; i<width; i++)
		{
			lOffset = PixelOffset(0, i, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
	
	for (i=0; i<width; i++)
		{
			lOffset = PixelOffset(height-1, i, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

		}
	//把暂时区域的点拷贝到原句柄下
	memcpy(lpData,lpTemp,wBytesPerLine*height);
	GlobalUnlock(hDIB);
	GlobalUnlock(hTempDIB);

⌨️ 快捷键说明

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