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

📄 zxdib.cpp

📁 利用web camera对目标进行特征跟踪的程序 对于初学机器视觉的有些帮助
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
	DWORD i,j;
	DWORD max=pBitmap[0];
	DWORD min=pBitmap[0];
	DWORD temp;

	if(pResult) delete pResult;
	pResult = new BYTE[dwHeight*dwWidth];

	for(i=0; i<dwHeight;i++)
	for(j=0; j<dwWidth; j++)
		if(pBitmap[i*dwWidth+j]>max) max = pBitmap[i*dwWidth+j];
		else
		if(pBitmap[i*dwWidth+j]<min) min = pBitmap[i*dwWidth+j];

	max -= min;

	for(i=0; i<dwHeight;i++)
	for(j=0; j<dwWidth; j++)
	{
		temp = (pBitmap[i*dwWidth+j]-min)*255.0/max;
		pResult[i*dwWidth+j] = (BYTE) temp;
	}

	return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
//  归一化到灰度图像的范围内
//
///////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::RegularToGrayLevel(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth,BYTE*& pResult)
{
	DWORD i,j;
	DWORD max=pBitmap[0];
	DWORD min=pBitmap[0];
	DWORD temp;

	if(pResult) delete pResult;
	pResult = new BYTE[dwHeight*dwWidth];

	for(i=0; i<dwHeight;i++)
	for(j=0; j<dwWidth; j++)
		if(pBitmap[i*dwWidth+j]>max) max = pBitmap[i*dwWidth+j];
		else
		if(pBitmap[i*dwWidth+j]<min) min = pBitmap[i*dwWidth+j];

	max -= min;

	for(i=0; i<dwHeight;i++)
	for(j=0; j<dwWidth; j++)
	{
		temp = (pBitmap[i*dwWidth+j]-min)*255/max;
		pResult[i*dwWidth+j] = (BYTE) temp;
	}

	return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  求图像的均值图像
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::MeanImage(BYTE **pBitmap, DWORD dwHeight, DWORD dwWidth, int nNumber, BYTE *&pResult,WORD flag)
{
	DWORD i,j,counter,position;
	int k;
	if(flag == 24) dwWidth*=3;

	if(pResult) delete pResult;
	pResult = (BYTE*) new BYTE[dwHeight*dwWidth];

	position = 0;
	for(i=0; i<dwHeight; i++)
	for(j=0; j<dwWidth; j++)
	{
		counter = 0;
		for(k=0; k<nNumber; k++)
			counter += pBitmap[k][position];
		counter /= nNumber;
		if(counter>255) counter = 255;
		pResult[position] =(BYTE) counter;
		position ++;
	}
	return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  求多个图像的方差图像:给定均值图像:
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::VarianceImage(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth, BYTE *pMeanImage, BYTE *&pResultImage,WORD flag)
{
	DWORD i,j;
	int k;
	int counter;
	int temp;

	if(pResultImage) delete pResultImage;
	if(flag==8)
		pResultImage = new BYTE [dwHeight*dwWidth];
	else
		if(flag==24)
			pResultImage = new BYTE [dwHeight*dwWidth*3];

	if(flag ==8)
	{
		for(i=0;i<dwHeight; i++)
		for(j=0; j<dwWidth; j++)
		{
			counter = pBitmap[i*dwWidth+j];
			counter -= pMeanImage[i*dwWidth+j];
			if(counter<0)
				counter = 0-counter;
			if(counter>255) counter = 255;
			/*counter *= 360;
			counter /= 255;
			if(counter>180) counter = 360-counter;
			counter *=255;
			counter /=360;
			*/

			pResultImage[i*dwWidth+j] = (BYTE) counter;
		}
	}
	else
	if(flag==24)
	{
		for(i=0;i<dwHeight; i++)
		for(j=0; j<dwWidth; j++)
		{
			counter = 0;
			for(k=0;k<2;k++)
			{
				temp = (int)(pBitmap[(i*dwWidth+j)*3+k]) - (int)(pMeanImage[(i*dwWidth+j)*3+k]);
				if(k==0)
				{
					temp *= 360;
					temp /= 255;
				    if(temp>180) temp= 360-temp;
					temp*=255;
					temp/=360;
					temp *= 0.0;
				}
				else
					temp *=1.0;
				if(temp<0) temp = 0-temp;
				if(counter<temp) counter = temp;
				//temp *= temp;
				//counter += temp;
			}
			//counter /= 3;
			//counter = (int) sqrt((double)counter);
			//if(counter>255) counter = 255;

			pResultImage[i*dwWidth+j] = (BYTE) counter;
		}
	}

	return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  求多个图像的方差图像:给定均值图像:
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::VarianceImage(BYTE **ppBitmap, DWORD dwHeight, DWORD dwWidth,int nFileNumber, BYTE *pMeanImage, BYTE *&pResultImage,WORD flag)
{
	DWORD i,j;
	int k,l;
	int counter,counter1;
	int temp;

	if(pResultImage) delete pResultImage;
	if(flag==8)
		pResultImage = new BYTE [dwHeight*dwWidth];
	else
		if(flag==24)
			pResultImage = new BYTE [dwHeight*dwWidth*3];

	if(flag ==8)
	{
		for(i=0;i<dwHeight; i++)
		for(j=0; j<dwWidth; j++)
		{
			counter = 0;
			for(k=0;k<nFileNumber;k++)
			{
				temp =  ppBitmap[k][i*dwWidth+j];
			    temp -= pMeanImage[i*dwWidth+j];
				temp *= temp;
				counter += temp;
			}
			counter /= nFileNumber;
			counter = (int) sqrt((double)counter);
			if(counter>255) counter = 255;
			pResultImage[i*dwWidth+j] = (BYTE) counter;
		}
	}
	else
	if(flag==24)
	{
		for(i=0;i<dwHeight; i++)
		for(j=0; j<dwWidth; j++)
		{
			counter = 0;
			counter1 = 0;
			for(l=0;l<nFileNumber;l++)
			{
				for(k=0;k<3;k++)
				{
					temp = (int)(ppBitmap[l][(i*dwWidth+j)*3+k]) - (int)(pMeanImage[(i*dwWidth+j)*3+k]);
					temp *= temp;
					counter += temp;
				}
				counter /= 3;
				counter = (int) sqrt((double)counter);
				counter1 += counter;
			}

			counter1/=nFileNumber;
			counter1 = (int) sqrt((double)counter1);

			if(counter1>255) counter1 = 255;

			pResultImage[i*dwWidth+j] = (BYTE) counter1;
		}
	}

	return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 粗定位,通过多张背景图像和多张目标图像求目标图像到背景图像的均值背景图像的方差图像:
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::CoarsePositionByMeanAndVariance(BYTE **pBKImage, DWORD dwHeight, DWORD dwWidth, int nNumberBK, BYTE *pInputImage,RECT &rect,WORD flag)
{
	DWORD i,j;
	BYTE* pMean=NULL;

	//求均值:
	MeanImage(pBKImage,dwHeight,dwWidth,nNumberBK,pMean,flag);

	//转化为HSI空间:
	BYTE* pBKHSI=NULL;
	GetHSIFromRGB(pMean,dwHeight,dwWidth,pBKHSI);
	BYTE* pTGHSI=NULL;
	GetHSIFromRGB(pInputImage,dwHeight,dwWidth,pTGHSI);
	//求图像的方差:
	BYTE* pVariance=NULL;
//  VarianceImage(pInputImage,dwHeight,dwWidth,pMean,pVariance,flag);
	VarianceByRGB2thColor(pTGHSI,dwHeight,dwWidth,pBKHSI,pVariance);

	//直方图:
//	BYTE* pHg=NULL;
//	Histogram(pVariance,dwHeight,dwWidth,pHg);

	//直方图平滑
//	for(i=0;i<18;i++)
//  	  HistogramSmoothBy5Points(pHg);

	//找到一个门限点,并二值化:
//	j = 1;
//	for(i=255; i>1 && j; i--)
//		if(pHg[i]<=4 && pHg[i-1]>4  ) j=0;
//	BlackAndWhite(pVariance,dwHeight,dwWidth,(BYTE)i);
	SegmentByDownHill(pVariance,dwHeight,dwWidth);
    //SegmentByOTSU(pVariance,dwHeight,dwWidth);

    //用小矩形来过滤输入图像
//	Cover2ValueImageByRect(pVariance,dwHeight,dwWidth,6,6);

	//得到目标矩形框
	ProjectAndFindTargetRegion(pVariance,dwHeight,dwWidth,rect);

//	delete pHg;
	delete pVariance;
	delete pMean;

	return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////
//
//  基于彩色的图像分割
//
////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::ColorBasedSegment(BYTE *pColorBitmap, DWORD dwHeight, DWORD dwWidth, BYTE *&pResult)
{
	if(pResult) delete pResult;
	pResult = new BYTE[dwWidth*dwHeight];

	double r,g,b;
	double x;
	DWORD i,j;
	double S,H,I;

	DWORD position=0;
	for(i=0; i<dwHeight; i++)
	for(j=0; j<dwWidth; j++)
	{ 
		b = (double)(pColorBitmap[position])/255.0;
		g = (double)(pColorBitmap[position+1])/255.0;
		r = (double)(pColorBitmap[position+2])/255.0;
		
		I = (r+g+b)/3;
		x = r;
		if( x>g ) x = g;
		if( x>b ) x = b;
		if(I<0.000001)
			S = 0;
		else
			S = 1-x/I;
		if(S<0.000001)
			H = 0;
		else
		{
			x = (r-g+r-b)/(2*sqrt((r-g)*(r-g)+(r-b)*(g-b)));
			if(x>=1.0) 
				H = 0;
			else 
			  H = (acos(x)/3.1415926)*180; 
		}
		if(g<b) H=360-H;

		if((H<36)&&(H>5)||(H>340))
			pResult[position/3] = 255;
		else 
			pResult[position/3] = 0;

		position += 3;
	}

	return true;
}
////////////////////////////////////////////////////////////////////////
// 生成一个BITMAPINFO结构
////////////////////////////////////////////////////////////////////////
bool CZXDib::CreateBITMAPINFO(BITMAPINFO *&pbi,DWORD dwHeight, DWORD dwWidth,WORD flag)
{
	if(flag==24) dwWidth *= 3;
	DWORD dwWriteSize  = dwHeight * ((dwWidth+3)/4*4);

	if(pbi) delete pbi;	
	if(flag == 24) 
		pbi = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFO)];
	else 
		pbi = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)];
	pbi->bmiHeader.biSize = sizeof(BITMAPINFO)-4;//无论是黑白图还是彩图都是40
	pbi->bmiHeader.biBitCount = flag;
	pbi->bmiHeader.biHeight = dwHeight;

	if(flag ==24) 
		pbi->bmiHeader.biWidth = dwWidth/3;
	else 
		pbi->bmiHeader.biWidth = dwWidth;

	pbi->bmiHeader.biSizeImage = dwWriteSize;
    pbi->bmiHeader.biCompression= 0;
	pbi->bmiHeader.biPlanes = 1;
	pbi->bmiHeader.biClrImportant = 0;
	pbi->bmiHeader.biClrUsed = 0;
	pbi->bmiHeader.biXPelsPerMeter = 
		pbi->bmiHeader.biYPelsPerMeter=0;
	pbi->bmiColors[0].rgbBlue = 
		pbi->bmiColors[0].rgbGreen=
		pbi->bmiColors[0].rgbRed=
		pbi->bmiColors[0].rgbReserved=0;
	
	//若是256色图像则,写调色板
	if( flag==8 )
	{
		for(int i=1; i<256; i++)
		{
			BYTE temp = (BYTE) i;
			pbi->bmiColors[i].rgbRed =
				pbi->bmiColors[i].rgbGreen=
				pbi->bmiColors[i].rgbBlue = (BYTE) i;
			pbi->bmiColors[i].rgbReserved = 0;

		}
	}
	
	return true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//pBitmap为灰度图象,flag为目标的灰度值
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CZXDib::GetRidOfSmallBlock(BYTE *pBitmap, DWORD dwHeight, DWORD dwWidth,BYTE flag,DWORD dwMinBlockSize)
{
	DWORD temp = 0;
	BYTE colorarray[1000]; //设最大有1000个区域:
	WORD color_area = 0;   //设当前用到了多少个
	DWORD i,j,k,temp_color,m,n;
	DWORD Number;
	WORD  Delete;
	BYTE egg;			   //中间颜色:
	bool modify;		   //修改标志
	
	for(i=0;i<260; i++)
		colorarray[i] = 0;
	
	DWORD position=0;
	DWORD position_l;
	for( i=0;i<dwHeight; i++)
	for(j=0; j<dwWidth; j++)
	{
		if(pBitmap[position]==flag)
		{
			Number=0;
			egg = 250;
			Delete = color_area+1;
			SeedGrow(i,j,pBitmap,dwHeight,dwWidth,Number,flag,egg,Delete,colorarray);
			modify = false;
			k=1;
			temp_color=0;
			for(k=1;(k<=color_area) && (!modify);k++)
			{  
				if( colorarray[k]==2 )
				{
					modify = TRUE;
					temp_color = k;
					colorarray[k]=1;
					position_l=0;
					for(m=0; m<dwHeight; m++)
					for(n=0; n<dwWidth; n++)
					{
						if(pBitmap[position_l] == egg)
							pBitmap[position_l] = (BYTE) k;
						position_l++;
					}
				}
			}
			while((k<=color_area) && (colorarray[k]!=2))
				k++;
			if (k<=color_area)  //处理多区域杂交的情况
			{
				position_l=0;
				for(m=0; m<dwHeight; m++)
				for(n=0; n<dwWidth; n++)
				{   
					k = temp_color;
					while ((k<=color_area)&&(pBitmap[position_l]))
					{
						if(colorarray[k] == 2)
						{
							if(pBitmap[position_l] == k)
								pBitmap[position_l] = (BYTE) temp_color;
						}
						k++;
					}
					position_l++;
				}
				k=temp_color;
				while (k<=color_area)
				{
					if( colorarray[k] ==2 ) 
						colorarray[k] = 0;
					k++;
				}
			}

			if((!modify)&&(Number<dwMinBlockSize))
			{  //如果该区域的总数比较小,则将之删除
				DWORD position_l = 0;
				for(DWORD m=0; m<dwHeight; m++)
				for(DWORD n=0; n<dwWidth; n++)
				{
					if(pBitmap[position_l] == 250)

⌨️ 快捷键说明

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