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

📄 dib.cpp

📁 本课题的主要内容是图像预处理,它主要从摄像头中获取人脸图像然后进行处理,以便提高定位和识别的准确率.该模块主要包含光线补偿、图像灰度化、高斯平滑、均衡直方图、图像对比度增强
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

LONG DIB::GetHeight()
{
	return	((BITMAPINFOHEADER *)m_pDib)->biHeight;
}

//////////////////////光线补偿//////////////////////////////
////////////////////////////////////////////////////////////
BOOL DIB::LightingCompensate(HANDLE hDIB)
{
	if(!hDIB)
		return FALSE;
	LPBITMAPINFOHEADER lpbi;
	int width,height;
	LPBYTE lpData;
	WORD wBytesPerLine;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	//得到图片宽和高
	width = lpbi->biWidth;
	height = lpbi->biHeight;
	//得到图片数据区
	lpData = this->FindDIBBits(hDIB);
	//得到图片每行的象素所占字节个数
	wBytesPerLine = this->BytePerLine(hDIB);
	//比例系数
	const float thresholdco = 0.05;
	//象素个数的临界常数
	const int thresholdnum = 100;
	//灰度级数组
	int histogram[256];
	for(int i =0;i<256;i++)
		histogram[i] = 0;
	//对于过于小的图片的判断
	if(width*height*thresholdco < thresholdnum)
		return false;
	int colorr,colorg,colorb;
	long lOffset;
	//考察整个图片
	
	for( i=0;i<height;i++)
		for(int j=0;j<width;j++)
		{	
			//得到象素数据的偏移
			lOffset = this->PixelOffset(i,j,wBytesPerLine);
			//得到rgb值
			colorb = *(lpData+lOffset++);
			colorg = *(lpData+lOffset++);
			colorr = *(lpData+lOffset++);
			//计算灰度值
			int gray = (colorr * 299 + colorg * 587 + colorb * 114)/1000;
			histogram[gray]++;
		}
		int calnum =0;
		int total = width*height;
		int num;
		//下面的循环得到满足系数thresholdco的临界灰度级
		for(i =0;i<256;i++)
		{
			if((float)calnum/total < thresholdco)
			{
				calnum+= histogram[255-i];
				num = i;
			}
			else
				break;
		}
		int averagegray = 0;
		calnum =0;
		//得到满足条件的象素总的灰度值
		for(i = 255;i>=255-num;i--)
		{
			averagegray += histogram[i]*i;
			calnum += histogram[i];
		}
		averagegray /=calnum;
		//得到光线补偿的系数
		float co = 255.0/(float)averagegray;
		//下面的循环对图象进行光线补偿
		for(i =0;i<height;i++)
			for(int j=0;j<width;j++)
			{	
				//得到数据偏移
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				//得到蓝色分量
				colorb = *(lpData+lOffset);
				//调整
				colorb *=co;
				//临界判断
				if(colorb >255)
					colorb = 255;
				//保存
				*(lpData+lOffset) = colorb;
				//绿色分量
				colorb = *(lpData+lOffset+1);
				colorb *=co;
				if(colorb >255)
					colorb = 255;
				*(lpData+lOffset+1) = colorb;
				//红色分量
				colorb = *(lpData+lOffset+2);
				colorb *=co;
				if(colorb >255)
					colorb = 255;
				*(lpData+lOffset+2) = colorb;

			}

			return TRUE;
}
//////////////////////////////////////膨胀////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
void DIB::Dilation(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
{
LPBITMAPINFOHEADER lpbi;
	int height;
	int width;
	WORD wBytesPerLine;
	LPBYTE lpData;
	LPBYTE lpTemp;
	long lOffset;
	//得到图象的基本信息
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	height = m_top;
	width = m_right;
	wBytesPerLine = this->BytePerLine(hDIB);
	lpData = this->FindDIBBits(hDIB);
	//申请一块和数据区大小相同的内存
	lpTemp = (LPBYTE) new BYTE[wBytesPerLine * height];
	
	
	long lOffsetJudge;
	for (int i=1+m_bottom; i<height-1; i++)
		for (int j=1+m_left; j<width-1; j++)
		{	
			lOffset = this->PixelOffset(i, j, wBytesPerLine);
			//如果当前点为白色,接着循环
			if(*(lpData + lOffset) == 255)
			{
				*(lpTemp + lOffset++) = 255;
				*(lpTemp + lOffset++) = 255;
				*(lpTemp + lOffset++) = 255;
				continue;
			}
			//否则考察上下左右四个点
			else
			{	
				lOffsetJudge = this->PixelOffset(i-1, j, wBytesPerLine);
				//如果上面的点为白色
				if(*(lpData + lOffsetJudge) == 255)
				{	//设置为白色,并继续循环
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					continue;
				}

				//考察下面的点
				lOffsetJudge = this->PixelOffset(i+1,j, wBytesPerLine);
				if(*(lpData + lOffsetJudge) == 255)
				{
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					continue;
				}
				
				//考察左边的点
				lOffsetJudge = this->PixelOffset(i,j-1, wBytesPerLine);
				if(*(lpData + lOffsetJudge) == 255)
				{
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					continue;
				}
				//考察右边的点
				lOffsetJudge = this->PixelOffset(i,j+1, wBytesPerLine);
				if(*(lpData + lOffsetJudge) == 255)
				{
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					*(lpTemp + lOffset++) = 255;
					continue;
				}
				//如果上下左右都是黑色点,则把暂时区域的点设置为黑色
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;

			}
				
		}
		//处理图象四周的点,设置为黑色
		for(i=m_bottom; i<height; i++)
		{
			lOffset = this->PixelOffset(i, 0, wBytesPerLine);
			{
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
			}
		}

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

		for(i=m_left; i<width; i++)
		{
			lOffset = this->PixelOffset(0, i, wBytesPerLine);
			{
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
			}
		}

		for(i=m_left; i<width; i++)
		{
			lOffset = this->PixelOffset(height-1, i, wBytesPerLine);
			{
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
				*(lpTemp + lOffset++) = 0;
			}
		}
		//把暂时区域的点拷贝到原句柄区域下面
		memcpy(lpData, lpTemp, wBytesPerLine*height);
		delete [] lpTemp;
		GlobalUnlock(hDIB);
	
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////腐蚀///////////////////////////////////////
void DIB::Erasion(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
{

	LPBITMAPINFOHEADER lpbi;
	LPBYTE lpData;
	WORD wBytesPerLine;
	long lOffset;
	long lOffsetJudge;
	int height;
	int width;
	
	//得到基本数据
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	height = m_top;
	width = m_right;
	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+m_bottom; i<height-1; i++)
		for (int j=1+m_left; 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=m_bottom; i<height; i++)
		{
			lOffset = PixelOffset(i, 0, wBytesPerLine);
				*(lpTemp + lOffset)   = 0;
				*(lpTemp + lOffset+1) = 0;
				*(lpTemp + lOffset+2) = 0;

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

		}

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

		}
	
	for (i=m_left; 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);
}

⌨️ 快捷键说明

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