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

📄 dib.cpp

📁 完成对运动图像的识别和跟踪
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  
	//	*r=r11;
		//*g=g11;
	//	*b=b11;
//	return (0x00ffffff&((b<<16)|(g<<8)|r));
}

HANDLE DIB::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;

}
HANDLE  DIB::  Gradient(HANDLE hDIB)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	int width = lpbi->biWidth;
	int height = lpbi->biHeight;
	long lOffset;
	LPBYTE lpS,lpD;
	WORD wBytesPerLine = this->BytePerLine(hDIB);
	HANDLE hNewDIB;
	hNewDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(lpbi->biSize+lpbi->biSizeImage));
	if(!hNewDIB)
	{
		AfxMessageBox("分配内存失败");
		return NULL;
	}
	lpS = (LPBYTE)lpbi;
	lpD =(LPBYTE) GlobalLock(hNewDIB);
	memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
	lpS = this->FindDIBBits(hDIB);
	lpD = this->FindDIBBits(hNewDIB);
	int color1,color2;
	for(int i=1;i<height-1;i++)
		for(int j=1;j<width-1;j++)
		{
			lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
			color1 = *(lpS+lOffset);
			lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
			color2 = *(lpS+lOffset);
			lOffset = this->PixelOffset(i,j,wBytesPerLine);
			*(lpD+lOffset++) = abs(color2-color1)*3;
			*(lpD+lOffset++) = abs(color2-color1)*3;
			*(lpD+lOffset++) = abs(color2-color1)*3;

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

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

		GlobalUnlock(hNewDIB);
		GlobalUnlock(hDIB);
		return hNewDIB;
}

//函数寻找图片中的特征区域的中心点
void DIB::LocateImporntPoint(HANDLE hDIB, int Radius, CPoint *pPoint)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	int width ,height;
	width = lpbi->biWidth;
	height = lpbi->biHeight;
	WORD wBytesPerLine;
	wBytesPerLine = this->BytePerLine(hDIB);
	LPBYTE lpData;
	lpData = this->FindDIBBits(hDIB);
	int tempsum=0,sum=0;//定义两个变量用来记数
	long lOffset;
	//扫描整个图片(边缘点除外)寻找特征区域
	for(int i=Radius;i<height-Radius;i++)
		for(int j= Radius;j<width-Radius;j++)
		{	tempsum =0;
			//扫描以Radius×2+1为边长的正方形区域
			for(int k1=-Radius;k1<=Radius;k1++)
				for(int k2 =-Radius;k2<=Radius;k2++)
				{	
					lOffset = this->PixelOffset(i+k1,j+k2,wBytesPerLine);
					int color = *(lpData+lOffset);
					tempsum +=color;//累加象素值
				}
				if(tempsum>sum)//如果得到的累计象素值大于已经得到的最大值
				{	
					//更改累计象素值大小
					sum = tempsum;
					//更改特征区域中心点
					(pPoint->x) = j;
					(pPoint->y) = i;
				   

				}
		}
	//下面的代码把特征区域的边框设置成白色
	for( i = -Radius;i<=Radius;i++)
	{
		lOffset = this->PixelOffset(pPoint->y-Radius,pPoint->x +i,wBytesPerLine);
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
	}
	for( i = -Radius;i<=Radius;i++)
	{
		lOffset = this->PixelOffset(pPoint->y+Radius,pPoint->x +i,wBytesPerLine);
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
	}
	for( i = -Radius;i<=Radius;i++)
	{
		lOffset = this->PixelOffset(pPoint->y+i,pPoint->x-Radius ,wBytesPerLine);
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
	}
	for( i = -Radius;i<=Radius;i++)
	{
		lOffset = this->PixelOffset(pPoint->y+i,pPoint->x+Radius,wBytesPerLine);
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 255;
	}
	lOffset = this->PixelOffset(pPoint->y,pPoint->x ,wBytesPerLine);
	*(lpData+lOffset++) = 0;
	*(lpData+lOffset++) = 255;
	*(lpData+lOffset++) = 0;

		GlobalUnlock(hDIB);
}


#define THRESHOLD (RADIUS*2+1)*(RADIUS*2+1)*15
//函数在一幅图片中寻找匹配的中心点
BOOL DIB::MatchImportantPoint(HANDLE hDIB,int CharaterInfo[RADIUS*2+1][RADIUS*2+1][3],CPoint *ImPoint)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	int width = lpbi->biWidth;
	int height = lpbi->biHeight;
	LPBYTE lpData = this->FindDIBBits(hDIB);
    WORD wBytesPerLine = this->BytePerLine(hDIB);
	long lOffset;
	long sum =100000,tempsum;
	//扫描整个图片(边缘点)除外
	for(int i=RADIUS ;i<height-RADIUS;i++)
		for(int j=RADIUS;j<width-RADIUS;j++)
		{	
			tempsum =0;
			//扫描以RADIUS*2+1为边长的正方形区域
			for(int k=-RADIUS;k<=RADIUS;k++)
				for(int kk=-RADIUS;kk<=RADIUS;kk++)
				{
					//计算当前正方形和已知特征区域的颜色差值

				lOffset = this->PixelOffset(i+k,j+kk,wBytesPerLine);
				int colorblue = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][0]);
				int colorgreen = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][1]);
				int colorred = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][2]);
				tempsum +=colorgreen+colorblue+colorred;
				}
				if(tempsum<sum)
				{  //更新差值
					sum = tempsum;
					//更改特征坐标点
					ImPoint->x = j;
					ImPoint->y = i;
				}
		}

		if(sum <THRESHOLD){//找到满足条件的区域
		//下面的代码把找到的区域的边框设置成为白色
		for(i =-RADIUS;i<=RADIUS;i++)
		{
			lOffset = this->PixelOffset(ImPoint->y-RADIUS,ImPoint->x+i,wBytesPerLine);
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;

		}

		for(i =-RADIUS;i<=RADIUS;i++)
		{
			lOffset = this->PixelOffset(ImPoint->y+RADIUS,ImPoint->x+i,wBytesPerLine);
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;

		}
		for(i =-RADIUS;i<=RADIUS;i++)
		{
			lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x+RADIUS,wBytesPerLine);
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;

		}
		for(i =-RADIUS;i<=RADIUS;i++)
		{
			lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x-RADIUS,wBytesPerLine);
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;
			*(lpData+lOffset++) = 255;

		}
		GlobalUnlock(hDIB);
		return true;
		}
		else AfxMessageBox("Can't find the corresponding point!");
	GlobalUnlock(hDIB);
	return false;
}
//比较两张图片的相似度
BOOL DIB::ComPareImg(HANDLE hDIB1, HANDLE hDIB2 ,CPoint pt1,CPoint pt2)
{
	if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)//图象偏差过大
	{	
		AfxMessageBox("Imgs Offset are too big");
		return false;
	}
	LPBITMAPINFOHEADER lpbi1,lpbi2;
	lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIB1);
	int width1 = lpbi1->biWidth;
	int height1 = lpbi1->biHeight;
	lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
	int width2 = lpbi2->biWidth;
	int height2 = lpbi2->biHeight;
	if(width1 != width2 || height1 != height2)//图象长宽尺寸不同
	{
		GlobalUnlock(hDIB1);
		GlobalUnlock(hDIB2);
		AfxMessageBox("Img is not same size");
		return false;
	}
	LPBYTE lpData1,lpData2;
	lpData1 = this->FindDIBBits(hDIB1);
	lpData2 = this->FindDIBBits(hDIB2);
	WORD wBytesPerLine = this->BytePerLine(hDIB1);
	int xleft,xright,ytop,ybottom;
	//下面的一段代码实现图象对齐
	if(pt1.x>=pt2.x)//第一幅图得特征中心点比第二幅图偏右
	{	
	
		xleft = pt2.x;//要处理得左边得象素点个数
		xright =width-pt1.x-1;//要处理得右边得象素点个数
	}
			
	else//第一幅图得特征中心点比第二幅图偏左
	{	
	
		xleft = pt1.x;
		xright = width1-pt2.x-1;
	}
	
	if(pt1.y >=pt2.y)//第一幅图得特征中心点得位置偏上
	{	
	
		ytop = pt2.y;//要处理得中心点上面得象素个数
		ybottom = height1-pt1.y-1;//要处理得中心点下面得象素个数

	}

	else//第一幅图得特征中心点得位置偏下
	{	
		
		ytop = pt1.y;
		ybottom = height1-pt2.y-1;
	}
	long sum=0;
	long lOffset;
	//计算两幅图片交叉区域得象素差值
	for(int i=-ytop;i<=ybottom;i++)
		for(int j=-xleft;j<=xright;j++)
		{	
			//第一幅图
			lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
			int c11 = *(lpData1+lOffset++);
			int c12 = *(lpData1+lOffset++);
			int c13 = *(lpData1+lOffset++);
			//第二幅图
			lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
			int c21 = *(lpData2+lOffset++);
			int c22 = *(lpData2+lOffset++);
			int c23 = *(lpData2+lOffset++);
			//计算差值
			sum += abs(c11-c21)+abs(c12-c22)+abs(c13-c23);
		}
		GlobalUnlock(hDIB1);
		GlobalUnlock(hDIB2);
	if(sum>width1*height1*3*2)//判断是否相似
		return false;
	else 
		return true;

}

BOOL DIB::  CompareImg2(HANDLE hDIBBK,HANDLE hDIBCurrent,CPoint pt1,CPoint pt2)
{
	if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)
	{	
		AfxMessageBox("Imgs Offset are too big");
		return false;
	}
	LPBITMAPINFOHEADER lpbi1,lpbi2;
	lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIBBK);
	int width1 = lpbi1->biWidth;
	int height1 = lpbi1->biHeight;
	lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIBCurrent);
	int width2 = lpbi2->biWidth;
	int height2 = lpbi2->biHeight;
	if(width1 != width2 || height1 != height2)
	{
		GlobalUnlock(hDIBBK);
		GlobalUnlock(hDIBCurrent);
		AfxMessageBox("Img is not same size");
		return false;
	}
	LPBYTE lpData1,lpData2;
	lpData1 = this->FindDIBBits(hDIBBK);
	lpData2 = this->FindDIBBits(hDIBCurrent);
	WORD wBytesPerLine = this->BytePerLine(hDIBBK);
	int xleft,xright,ytop,ybottom;

	if(pt1.x>=pt2.x)
	{	
	
		xleft = pt2.x;
		xright =width1-pt1.x-1;
	}
			
	else
	{	
	
		xleft = pt1.x;
		xright = width1-pt2.x-1;
	}
	
	if(pt1.y >=pt2.y)
	{	
	
		ytop = pt2.y;
		ybottom = height1-pt1.y-1;

	}

	else
	{	
		
		ytop = pt1.y;
		ybottom = height1-pt2.y-1;
	}
	long sum=0;
	long lOffset;
	


	for(int i=-ytop;i<=ybottom;i++)
		for(int j=-xleft;j<=xright;j++)
		{	
		
			lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
			int c11 = *(lpData1+lOffset++);
			int c12 = *(lpData1+lOffset++);
			int c13 = *(lpData1+lOffset++);
			lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
			int c21 = *(lpData2+lOffset++);
			int c22 = *(lpData2+lOffset++);
			int c23 = *(lpData2+lOffset++);
			lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
			*(lpData2+lOffset++) = abs(c11-c21);
			*(lpData2+lOffset++) = abs(c12-c22);
			*(lpData2+lOffset++) = abs(c13-c23);
		}
		for(i =0;i<height1;i++)
			for(int j=0;j<width1;j++)
			{
			if(i<pt2.y-ytop || i>pt2.y+ybottom||j<pt2.x-xleft || j >pt2.x+xright)
			{
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				*(lpData2+lOffset++) = 0;
				*(lpData2+lOffset++) = 0;
				*(lpData2+lOffset++) = 0;
			}
			}
		
		GlobalUnlock(hDIBBK);
		GlobalUnlock(hDIBCurrent);
		return true;
	
}



BOOL DIB::IsScaterPoint(int x, int y, int width, int height, LPBYTE lpData,WORD wBytesPerLine,  int threshold,bool lab[m_HEIGHT][m_WIDTH])
{
	long lOffset;
	lOffset = this->PixelOffset(y,x,wBytesPerLine);
	if(*(lpData+lOffset) == 255 && lab[y][x] == false)
	{
		this->lenth++;
		lab[y][x] = true;
	if(this->lenth >= threshold)
		return true;
	if(x+1<width && lab[y][x+1] == false)
	{	IsScaterPoint(x+1,y,width,height,lpData,wBytesPerLine,threshold,lab);
		if(this->lenth>=threshold)
			return true;
		
	}
	if(x-1>=0 && lab[y][x-1] == false)
	{
		(IsScaterPoint(x-1,y,width,height,lpData,wBytesPerLine,threshold,lab));
		if(this->lenth>=threshold)
			return true;
		
	}
	
	if(y-1>=0 && lab[y-1][x]==false)
	{
		(IsScaterPoint(x,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
		if(this->lenth>=threshold)
			return true;
		
	}
	if(y+1<height && lab[y+1][x]==false)
	{	(IsScaterPoint(x,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
			if(this->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(this->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(this->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(this->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(this->lenth>=threshold)
			return true;
			
	}
	}
		return false;
}
//函数得到边界得中心点
CPoint DIB:: GetEdgeCenter(HANDLE hDIB)
{
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	int width = lpbi->biWidth;
	int height = lpbi->biHeight;
	WORD wBytesPerLine = this->BytePerLine(hDIB);
	LPBYTE lpData = this->FindDIBBits(hDIB);
	long lOffset;
	int x =0,y =0,num =0;
	//对整幅图片进行扫描
	for(int i=0;i<height;i++)
		for(int j=0;j<width;j++)
		{
			lOffset = this->PixelOffset(i,j,wBytesPerLine);
			if(*(lpData+lOffset) ==255)//如果是白色象素
			{
				x +=j;//中心点得横坐标和纵坐标加上当前得横坐标和纵坐标
				y +=i;
				num++;
			}
		}
		//得到结果坐标点
		CPoint result;
		result.x = x/num;
		result.y = y/num;
		//把中心点设置为绿色
		lOffset = this->PixelOffset(result.y,result.x,wBytesPerLine);
		*(lpData+lOffset++) = 0;
		*(lpData+lOffset++) = 255;
		*(lpData+lOffset++) = 0;
		return result;
}

⌨️ 快捷键说明

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