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

📄 dib.cpp

📁 完成对运动图像的识别和跟踪
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	long lOffset;
	lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x,wBytesPerLine);
	if(*(lpDIBBits+lOffset)!=0)
		return false;

	if(CurrentPoint.y!=0)
	{
		lOffset = this->PixelOffset(CurrentPoint.y-1,CurrentPoint.x,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==255)
		return true;
	}

	if(CurrentPoint.x!=this->width-1)
	{
		lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x+1,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==255)
		return true;
	}

	if(CurrentPoint.y!=this->height-1)
	{
		lOffset = this->PixelOffset(CurrentPoint.y+1,CurrentPoint.x,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==255)
		return true;
	}


	if(CurrentPoint.x!=0)
	{
		lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x-1,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==255)
		return true;
	}

	return false;
}



CPoint DIB::SearchInteriorPoint(CPoint Point,LPBYTE lpDIBBits,WORD wBytesPerLine)
{
	long lOffset;
	CPoint Pointtmp;
	Pointtmp.x=Pointtmp.y=-1;
	if((Point.x!=0)&&(Point.y!=this->height-1))
	{
		lOffset = this->PixelOffset(Point.y+1,Point.x-1,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==0)
		{
			Pointtmp.x=Point.x-1;
			Pointtmp.y=Point.y+1;
			return Pointtmp;
		}
	}

	if(Point.y!=this->height-1)
	{
		lOffset = this->PixelOffset(Point.y+1,Point.x,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==0)
		{
			Pointtmp.x=Point.x;
			Pointtmp.y=Point.y+1;
			return Pointtmp;
		}
	}

	if((Point.x!=this->width-1)&&(Point.y!=this->height-1))
	{
		lOffset = this->PixelOffset(Point.y+1,Point.x+1,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==0)
		{
			Pointtmp.x=Point.x+1;
			Pointtmp.y=Point.y+1;
			return Pointtmp;
		}
	}

	if(Point.x!=this->width-1)
	{
		lOffset=this->PixelOffset(Point.y,Point.x+1,wBytesPerLine);
		if(*(lpDIBBits+lOffset)==0)
		{
			Pointtmp.x=Point.x+1;
			Pointtmp.y=Point.y;
			return Pointtmp;
		}
	}
	return Pointtmp;
}

//对图片中的图形进行细化操作
void DIB::ThinningDIB(HANDLE hDIB)
{
	
	LPBITMAPINFOHEADER lpbi;
	WORD wBytesPerLine;
	LPBYTE lpDIBBits;
	long lOffset;
	int width,height;
	//细化查询表
	static int erasetable[256]={
								0,0,1,1,0,0,1,1,
								1,1,0,1,1,1,0,1,
								1,1,0,0,1,1,1,1,
								0,0,0,0,0,0,0,1,
								
								0,0,1,1,0,0,1,1,
								1,1,0,1,1,1,0,1,
								1,1,0,0,1,1,1,1,
								0,0,0,0,0,0,0,1,
								
								1,1,0,0,1,1,0,0,
								0,0,0,0,0,0,0,0,
								0,0,0,0,0,0,0,0,
								0,0,0,0,0,0,0,0,
								
								1,1,0,0,1,1,0,0,
								1,1,0,1,1,1,0,1,
								0,0,0,0,0,0,0,0,
								0,0,0,0,0,0,0,0,

								0,0,1,1,0,0,1,1,
								1,1,0,1,1,1,0,1,
								1,1,0,0,1,1,1,1,
								0,0,0,0,0,0,0,1,
								
								0,0,1,1,0,0,1,1,
								1,1,0,1,1,1,0,1,
								1,1,0,0,1,1,1,1,
								0,0,0,0,0,0,0,0,
								
								1,1,0,0,1,1,0,0,
								0,0,0,0,0,0,0,0,
								1,1,0,0,1,1,1,1,
								0,0,0,0,0,0,0,0,

								1,1,0,0,1,1,0,0,
								1,1,0,1,1,1,0,0,
								1,1,0,0,1,1,1,0,
								1,1,0,0,1,0,0,0
						  };
	
		lpbi=(LPBITMAPINFOHEADER)GlobalLock(hDIB);
		//得到图片的长宽信息
		width = lpbi->biWidth;
		height = lpbi->biHeight;
		lpDIBBits = this->FindDIBBits(hDIB);
	
		wBytesPerLine = this->BytePerLine(hDIB);
		//执行细化,直到没有点可以被去掉为止
		int end =0;
		while(!end)
		{
			end =1;
			//扫描整个图片,从上往下
		for(int i=1;i<height-1;i++)
			for(int j=1;j<width-1;j++)
			{	
				//判定当前点的颜色
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				if(*(lpDIBBits+lOffset)==0)
					continue;//如果是黑色的,直接考虑下一个点
				else
				{
					int colorleft,colorright;
					lOffset =this->PixelOffset(i,j-1,wBytesPerLine);
					colorleft = *(lpDIBBits+lOffset);
					lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
					colorright = *(lpDIBBits+lOffset);
					//如果当前点的的左边和右边的点的颜色都是白色
					if((colorleft==255)&&(colorright==255))
						continue;//直接进行下一个点的处理
					else
					{	
						//下面的一段代码考察当前点的周围八个方向上的点的颜色
						//并根据颜色设置标志位
						int k1,k2,k3,k4,k5,k6,k7,k8;
						//左下
						lOffset = this->PixelOffset(i+1,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k1=1;
						else
							k1 =0;
						//正下
						lOffset = this->PixelOffset(i+1,j,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k2=1;
						else
							k2 =0;
						//右下
						lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k3=1;
						else
							k3 =0;
						//正左
						lOffset = this->PixelOffset(i,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k4=1;
						else
							k4 =0;
                        //正右
						lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k5=1;
						else
							k5 =0;
                        //左上
						lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k6=1;
						else
							k6 =0;
                        //正上
						lOffset = this->PixelOffset(i-1,j,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k7=1;
						else
							k7 =0;
						//右上
						lOffset = this->PixelOffset(i-1,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k8=1;
						else
							k8 =0;
						int judge;
						//计算得到细化查询表中的位置
						judge = k1+k2*2+k3*4+k4*8+k5*16+k6*32+k7*64+k8*128;
						if(erasetable[judge]==1)
						{   //删除
							lOffset = this->PixelOffset(i,j,wBytesPerLine);
							*(lpDIBBits+lOffset++)=0;
							*(lpDIBBits+lOffset++)=0;
							*(lpDIBBits+lOffset++)=0;
							j++;
							end =0;//继续循环
						}
					}
				}
			}
   //扫描整个图片,从左到右,代码类似
	for(int j=1;j<width-1;j++)
		for(int i=1;i<height-1;i++)
			{
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				if(*(lpDIBBits+lOffset)==0)
					continue;
				else
				{
					int colorleft,colorright;
					lOffset =this->PixelOffset(i,j-1,wBytesPerLine);
					colorleft = *(lpDIBBits+lOffset);
					lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
					colorright = *(lpDIBBits+lOffset);
					if((colorleft==255)&&(colorright==255))
						continue;
					else
					{
						int k1,k2,k3,k4,k5,k6,k7,k8;
						lOffset = this->PixelOffset(i+1,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k1=1;
						else
							k1 =0;

						lOffset = this->PixelOffset(i+1,j,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k2=1;
						else
							k2 =0;
						
						lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k3=1;
						else
							k3 =0;

						lOffset = this->PixelOffset(i,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k4=1;
						else
							k4 =0;

						lOffset = this->PixelOffset(i,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k5=1;
						else
							k5 =0;

						lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k6=1;
						else
							k6 =0;

						lOffset = this->PixelOffset(i-1,j,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k7=1;
						else
							k7 =0;
						lOffset = this->PixelOffset(i-1,j+1,wBytesPerLine);
						if(*(lpDIBBits+lOffset)==0)
							k8=1;
						else
							k8 =0;
						int judge;
						judge = k1+k2*2+k3*4+k4*8+k5*16+k6*32+k7*64+k8*128;
						if(erasetable[judge]==1)
						{
							lOffset = this->PixelOffset(i,j,wBytesPerLine);
							*(lpDIBBits+lOffset++)=0;
							*(lpDIBBits+lOffset++)=0;
							*(lpDIBBits+lOffset++)=0;
							j++;
							end =0;
						}
					}
				}
			}

		}

}





BOOL DIB:: SaveDIB(HANDLE hDib, CFile& file)
{
	// Bitmap文件头
	BITMAPFILEHEADER bmfHdr;
	
	// 指向BITMAPINFOHEADER的指针
	LPBITMAPINFOHEADER lpBI;
	
	// DIB大小
	DWORD dwDIBSize =0;

	if (hDib == NULL)
	{
		// 如果DIB为空,返回FALSE
		return FALSE;
	}

	// 读取BITMAPINFO结构,并锁定
	lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
	
	if (lpBI == NULL)
	{
		// 为空,返回FALSE
		return FALSE;
	}
	
	// 判断是否是WIN3.0 DIB
//	if (!IS_WIN30_DIB(lpBI))
//	{
		// 不支持其它类型的DIB保存
		
		// 解除锁定
	//	::GlobalUnlock((HGLOBAL) hDib);
		
		// 返回FALSE
	//	return FALSE;
//	}

	// 填充文件头

	// 文件类型"BM"
	bmfHdr.bfType =  0x4d42; //DIB_HEADER_MARKER;

	// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
	// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
	
	// 文件头大小+颜色表大小
	// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
//	dwDIBSize = *(LPDWORD)lpBI; //+ ::PaletteSize((LPSTR)lpBI);
	dwDIBSize = sizeof(BITMAPINFOHEADER);//+lpBI->biSizeImage;	
	// 计算图像大小
	if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
	{
		// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
		dwDIBSize += lpBI->biSizeImage;
	}
	else
	{
		// 象素的大小
		DWORD dwBmBitsSize;

		// 大小为Width * Height
		dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*24) * lpBI->biHeight;
		
		// 计算出DIB真正的大小
		dwDIBSize += dwBmBitsSize;

		// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
		lpBI->biSizeImage = dwBmBitsSize;
	}


	// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
	bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
	
	// 两个保留字
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;

	// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
											 // + PaletteSize((LPSTR)lpBI);
	// 尝试写文件
//	TRY
	{
		// 写文件头
		file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
		
		// 写DIB头和象素
		file.WriteHuge(lpBI, dwDIBSize);
	}
//	CATCH (CFileException, e)
//	{
		// 解除锁定
	//	::GlobalUnlock((HGLOBAL) hDib);
		
		// 抛出异常
///		THROW_LAST();
//	}
//	END_CATCH
	
	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDib);
	
	// 返回TRUE
	return TRUE;
}




HANDLE DIB::ScaleDIB(HANDLE hDIB, float scal_x, float scal_y)
{
	if(scal_x<0 || scal_y <0)
		return NULL;

	LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
	int w = lpbi->biWidth;
	int h = lpbi->biHeight;
	BYTE  tempmess[40];
	LPBYTE Src = this->FindDIBBits(hDIB);
	memcpy(tempmess,(LPBYTE)lpbi,40);
	int wid = ((int)(w*scal_x+0.5f)*24+31)/32*4;
	int imgsize =(int) (wid*(int)(h*scal_y+0.5f));
	
	HDIB hDIB2 = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)+imgsize));
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
	memcpy((LPBYTE)lpbi,tempmess,40);
	lpbi->biWidth =(int)(w*scal_x+0.5f);
	lpbi->biHeight = (int)(h*scal_y+0.5f);
	lpbi->biSizeImage = imgsize;
	LPBYTE lpData = this->FindDIBBits(hDIB2);
	int srcWidth = w;
	int srcHeight = h;
	int dstWidth = (int)(w*scal_x+0.5f);
	int dstHeight = (int)(h*scal_y+0.5f);

	for(int i=0; i<dstHeight;i++)
	{
		float y_inverse_map = (float)i/scal_y;
		int y_lt = (int)y_inverse_map;
		float v=y_inverse_map - y_lt;
		int indexBase = i *wid;
		for(int j=0;j<dstWidth;j++)
		{
			float x_inverse_map = (float)j/scal_x;
			int x_lt = (int) x_inverse_map;
			float u=x_inverse_map - x_lt;
			int index = indexBase + j*3;
			*(lpData+index) = Src[y_lt*((w*24+31)/32*4)+x_lt*3];
			*(lpData+index+1) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+1];
			*(lpData+index+2) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+2];
		//	int r,g,b;
			//((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b))) ;
		//	*(lpData+temp)   = b;
			//*(lpData+index++)   = (BYTE)((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight)>>16)) & 0x000000ff;
		//	(interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
		//	*(lpData+temp+1)   = g;
		  //  (interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
		//	 *(lpData+temp+2)   =r;
			
		}
	}
	GlobalUnlock(hDIB);
	GlobalUnlock(hDIB2);
	return hDIB2;

}

//cwh 01.6.20
/*****************************************
卷积核心算法
*****************************************/
void DIB::interPolate(LPBYTE Src,int x,int y, float u,float v, int scanw, int scanh,int *r,int *g,int *b)
{
//	UINT r11,g11,b11;
	//r=g=b=0;
		int red1[2][2];
		int green1[2][2];
		int blue1[2][2];
		int xx1[2];
		int yy1[2];
		xx1[0]=x*3;xx1[1]=x*3+3;
		yy1[0]=y;yy1[1]=y+1;
		if(xx1[1]>scanw-1)
			xx1[1] = scanw-1;
		if(yy1[1]>scanh-1)
			yy1[1] = scanh-1;

		for(int i=0;i<2;i++)
		{
			int indexBase1 = yy1[i]*((scanw*24+31)/32*4);
			for(int j=0;j<2;j++)
			{
				int index1 = indexBase1 + xx1[j];
				blue1[j][i] = (*(Src+index1));
			    green1[j][i] = (*(Src+index1+1));
			    red1[j][i] =  (*(Src+index1+2));

			}
		}

		//r11 = ((1-u)*(1-v)*red1[0][0]+(1-u)*v*red1[0][1]+u*(1-v)*red1[1][0]+u*v*red1[1][1]);
	//	g11 = ((1-u)*(1-v)*green1[0][0]+(1-u)*v*green1[0][1]+u*(1-v)*green1[1][0]+u*v*green1[1][1]);
		//b11 = ((1-u)*(1-v)*blue1[0][0]+(1-u)*v*blue1[0][1]+u*(1-v)*blue1[1][0]+u*v*blue1[1][1]);

⌨️ 快捷键说明

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