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

📄 dib.cpp

📁 完成对运动图像的识别和跟踪
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// DIB.cpp: implementation of the DIB class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DIB.h"
#include"math.h"
#define WIDTHBYTES(bits)  ((bits+31)/32*4)
#define RECTWIDTH(x) (x->right-x->left)
#define RECTHEIGHT(x) (x->bottom-x->top)
#define THRESHOLDCONTRAST  40
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define PI 3.1415926
extern int locax,locay;
#define m_WIDTH 600
#define m_HEIGHT 600

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////////////////////////////////
HDIB DIB::ReadDIBFile(HANDLE hFile)
{
	BITMAPFILEHEADER bmfHeader;
	DWORD dwBitsSize;
	HANDLE hDIB;
	HANDLE hDIBtmp;
	LPBITMAPINFOHEADER lpbi;
	DWORD dwRead;
    //得到文件大小
	dwBitsSize = GetFileSize(hFile,NULL);
	hDIB =  GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));

	if(!hDIB)
		return NULL;

	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	if(!lpbi)
	{
		GlobalFree(hDIB);
		return NULL;
	}
	
	if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
		goto ErrExit;
	if(sizeof(BITMAPFILEHEADER)!=dwRead)//读取文件出错
		goto ErrExit;
	if(bmfHeader.bfType != 0x4d42)//文件类型不匹配
		goto ErrExit;
	if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
		goto ErrExit;
	if(sizeof(BITMAPINFOHEADER)!= dwRead)//读取数据出错
		goto ErrExit;
	
	GlobalUnlock(hDIB);
	if(lpbi->biSizeImage==0)
		lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;
	hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
	if(!hDIBtmp)
		goto ErrExitNoUnlock;
	else
		hDIB = hDIBtmp;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	//根据情况设定文件指针
	if(bmfHeader.bfOffBits != 0L)
		SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
    //读取文件的象素颜色数据
	if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
			goto OKExit;
	
	ErrExit:
		GlobalUnlock(hDIB);
	
	ErrExitNoUnlock:
		GlobalFree(hDIB); //释放内存
		return NULL;

	OKExit:
		GlobalUnlock(hDIB);
		return hDIB;
		
}

HDIB DIB::LoadDIB(LPCTSTR lpFileName)
{
	HANDLE hDIB;
	HANDLE hFile;
	//创建文件句柄
	if((hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
	{  
		//读取数据
		hDIB = ReadDIBFile(hFile);
		//关闭文件句柄
		CloseHandle(hFile);
		return hDIB;
	}
	return NULL;
}

BOOL DIB::PaintDIBTrue(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
{
	LPBYTE lpDIBHdr;
	LPBYTE lpDIBBits;
	BOOL bSuccess = FALSE;

	if(!hDIB)
		return FALSE;
	lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
	lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
	bSuccess = StretchDIBits(hDC,lpDCRect->left,
								 lpDCRect->top,
								 RECTWIDTH(lpDCRect),
								 RECTHEIGHT(lpDCRect),
								 lpDIBRect->left,
								 ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
								 RECTWIDTH(lpDIBRect),
								 RECTHEIGHT(lpDIBRect),
								 lpDIBBits,
								 (LPBITMAPINFO)lpDIBHdr,
								 DIB_RGB_COLORS,
								 SRCCOPY);
	GlobalUnlock(hDIB);
	return bSuccess;
}

WORD DIB::BytePerLine(HANDLE hDIB)
{	
	WORD i;
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	i = WIDTHBYTES((lpbi->biWidth)*24);
	GlobalUnlock(hDIB);
	return i;	
}


//函数实现图片从彩色到黑白的转换
HDIB DIB::ToGray(HANDLE hDIB)
{
	HDIB hNewDIB = NULL;
	LPBITMAPINFOHEADER lpSrc,lpDest;
	LPBYTE lpS,lpD;
	DWORD dwBytesPerLine;
	DWORD dwImgSize;
	WORD wBytesPerLine;
	unsigned i ,j,height,width;
	if(!hDIB)
		return NULL;
	
	lpSrc = (LPBITMAPINFOHEADER)GlobalLock(hDIB);

	dwBytesPerLine = WIDTHBYTES(24*(lpSrc->biWidth));
	dwImgSize = lpSrc->biHeight * dwBytesPerLine;
	//申请新的内存,大小等于原来图象的大小
	hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);

	lpDest = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
	//保存图片的长宽、颜色深度等信息
	memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
	DWORD dwSBytesPerLine;
	dwSBytesPerLine = (24*(lpSrc->biWidth)+31)/32*4;
	height = lpDest->biHeight;
	width = lpDest->biWidth;
	lpS = (LPBYTE)lpSrc;
	wBytesPerLine = this->BytePerLine(hDIB);
	lpD = (LPBYTE)lpDest;	
	lpS = lpS + sizeof(BITMAPINFOHEADER);
	lpD = lpD + sizeof(BITMAPINFOHEADER);
	unsigned  r , g ,b,gray ;
	//扫描整个图片,实现灰度化
	for(i = 0 ;i<height; i++)
	{
		for(j = 0 ;j<(unsigned )lpDest->biWidth;j++)
		{
	        //获得原来图片的颜色值
			r = *(lpS++);
			g = *(lpS++);
			b  = *(lpS++);
			//计算灰度值
			gray = (g*50+r*39+b*11)/100;
			//保存灰度值到目标图片
			*(lpD++)=gray;
			*(lpD++) = gray;
			*(lpD++) = gray;

			
		}
		//处理四字节对齐问题
	unsigned  k ;
		for(k=0;k<dwSBytesPerLine-lpSrc->biWidth*3;k++)
		{
			lpS++;
			lpD++;
		}
		
	}

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

}



LPBYTE  DIB::FindDIBBits(HANDLE hDIB)
{
	LPBYTE lpDIB,lpDIBtmp;
	LPBITMAPINFOHEADER lpbi;
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	lpDIBtmp = (LPBYTE)lpbi;
	lpDIB = lpDIBtmp + sizeof(BITMAPINFOHEADER);
	GlobalUnlock(hDIB);
	return lpDIB;
}

long DIB::PixelOffset(int i,int j,WORD wBytePerLine)
{
	long   Offset;
	Offset = i*wBytePerLine + j*3;
	return Offset;
}





int DIB::BOUND(int a ,int b ,int rgb)
{
	if(rgb<0)
		return BOUND(a,b,abs(rgb));
	if(rgb>b)
		return b;
	return rgb;
}
//函数实现对图片的中值滤波处理
void DIB::MedianFilterDIB(HANDLE hDIB)
{
	
	HDIB hNewDIB;
	LPBYTE  lpS,lpD;
	LPBITMAPINFOHEADER lpbi;
	int r,g,b;
	DWORD width,height;
	WORD wBytesPerLine;
	long lOffset;
	if(!hDIB)
		return;
	SetCursor(LoadCursor(NULL,IDC_WAIT));
	wBytesPerLine = this->BytePerLine(hDIB);
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
	width = lpbi->biWidth;
	height = lpbi->biHeight;
	 //申请一块新的内存
	hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+lpbi->biSizeImage);
	lpD = (LPBYTE)GlobalLock(hNewDIB);
	lpS = (LPBYTE)lpbi;
	memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
	lpS = lpS+sizeof(BITMAPINFOHEADER);
	lpD = lpD+sizeof(BITMAPINFOHEADER);
	//扫描整个图片
	for(WORD i=1;i<height-1;i++)
		for(WORD j=1;j<width-1;j++)
		{	//中值滤波
			this->DoMedianFilterDIB(&r,&g,&b,i,j,wBytesPerLine,lpS);
			lOffset = this->PixelOffset(i,j,wBytesPerLine);
			*(lpD+lOffset++) = r;
			*(lpD+lOffset++) = g;
			*(lpD+lOffset)   = b;

		}
		//把信息拷贝回原来的句柄
		for( i = 1;i<height-1;i++)
			for(WORD j = 1;j<width-1;j++)
			{
				lOffset = this->PixelOffset(i,j,wBytesPerLine);
				//活得新图片的颜色
				int color1 = *(lpD+lOffset++);
				int color2 = *(lpD+lOffset++);
				int color3 = *(lpD+lOffset++);
				//拷贝到原来图片中
						*(lpS+lOffset++) = color1;
						*(lpS+lOffset++) = color2;
						*(lpS+lOffset++) = color3;
			}
	SetCursor(LoadCursor(NULL,IDC_ARROW));
	GlobalUnlock(hDIB);
	GlobalUnlock(hNewDIB);
	GlobalFree(hNewDIB);
	
}



void DIB::DoMedianFilterDIB(int *r,int *g,int*b,WORD i,WORD j,WORD wBytesPerLine,LPBYTE lpDIBBits)
{
	long lOffset;
	int rgb[9][3];
	//把八个方位和当前位置得rgb值保存到数组rgb[9][3]中
	lOffset = this->PixelOffset( i-1, j-1, wBytesPerLine); 
	rgb[0][0] = *(lpDIBBits+lOffset++);
	rgb[0][1] = *(lpDIBBits+lOffset++);
	rgb[0][2] = *(lpDIBBits+lOffset++);

	lOffset = this->PixelOffset( i-1, j, wBytesPerLine);
	rgb[1][0] = *(lpDIBBits+lOffset++);
	rgb[1][1] = *(lpDIBBits+lOffset++);
	rgb[1][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i-1, j+1, wBytesPerLine);
	rgb[2][0] = *(lpDIBBits+lOffset++);
	rgb[2][1] = *(lpDIBBits+lOffset++);
	rgb[2][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i, j-1, wBytesPerLine);
	rgb[3][0] = *(lpDIBBits+lOffset++);
	rgb[3][1] = *(lpDIBBits+lOffset++);
	rgb[3][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i, j, wBytesPerLine);
	rgb[4][0] = *(lpDIBBits+lOffset++);
	rgb[4][1] = *(lpDIBBits+lOffset++);
	rgb[4][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i, j+1, wBytesPerLine);
	rgb[5][0] = *(lpDIBBits+lOffset++);
	rgb[5][1] = *(lpDIBBits+lOffset++);
	rgb[5][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i+1, j-1, wBytesPerLine);
	rgb[6][0] = *(lpDIBBits+lOffset++);
	rgb[6][1] = *(lpDIBBits+lOffset++);
	rgb[6][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i+1, j, wBytesPerLine);
	rgb[7][0] = *(lpDIBBits+lOffset++);
	rgb[7][1] = *(lpDIBBits+lOffset++);
	rgb[7][2] = *(lpDIBBits+lOffset++);
	lOffset = this->PixelOffset( i+1, j+1, wBytesPerLine);
	rgb[8][0] = *(lpDIBBits+lOffset++);
	rgb[8][1] = *(lpDIBBits+lOffset++);
	rgb[8][2] = *(lpDIBBits+lOffset++);
	 this->MedianSearch( rgb,9,b,g,r);
	

}


int DIB::MedianSearch(int a[9][3],int n,int *r,int *g,int *b)
{
	int result,i,j,temp;
	//冒泡法排序,找出rgb中间值
	for(i=0;i<9;i++)
		for(j = 0 ;j<n-i-1;j++)
		{	
			if(a[j][0]>a[j+1][0])
			{
				temp = a[j][0];
				a[j][0] = a[j+1][0];
				a[j+1][0]=temp;
			}
			if(a[j][1]>a[j+1][1])
			{
				temp = a[j][1];
				a[j][1] = a[j+1][1];
				a[j+1][1]=temp;
			}

			if(a[j][2]>a[j+1][2])
			{
				temp = a[j][2];
				a[j][2] = a[j+1][2];
				a[j+1][2]=temp;
			}


		}
		//得到rgb得中间值
		*b = a[5][0];
		*g = a[5][1];
		*r = a[5][2];
		//根据需要也可以选用灰度值
		result = (a[5][0]*39 +a[5][1]*50 + a[5][2]*11)/100;
		return result;
}
//实现图片的黑白二值化
void DIB::WhiteBlack(HANDLE hDIB,unsigned n)
{

	LPBITMAPINFOHEADER  lpbi;
	LPBYTE				lpS;
	int					width,height;
	long				lOffset;
	WORD                wBytesPerLine;

	if(!hDIB)
		return ;
	wBytesPerLine = this->BytePerLine(hDIB);
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
    //得到图片的长宽信息
	width = lpbi->biWidth;
	height = lpbi->biHeight;

	lpS = (LPBYTE)lpbi;
	//lps指向数据区
	lpS = lpS + sizeof(BITMAPINFOHEADER);
  	//扫描整个图片,实现二值化
	for(int i = 0;i<height;i++)
		for(int j = 0 ;j<width;j++)
		{   //得到象素数据在数据区中的偏移
			lOffset = this->PixelOffset(i,j,wBytesPerLine);
			if(*(lpS+lOffset)<n)//象素值小于临界值
			{   //把象素填充为黑色
				*(lpS+lOffset++) = 0;
				*(lpS+lOffset++) = 0;
				*(lpS+lOffset)   = 0;
			}
			else //象素值大于临界值
			{   
				//把象素填充为白色
				*(lpS+lOffset++) = 255;
				*(lpS+lOffset++) = 255;
				*(lpS+lOffset)   = 255;
			}
		}

		GlobalUnlock(hDIB);
		
}














DIB::DIB()
{	


}
DIB::~DIB()
{

}

CPoint DIB::NextBorderPoint(CPoint CurrentPoint,LPBYTE lpDIBBits,WORD wBytesPerLine)
{
	CPoint Pointtmp;
/*	Pointtmp.x=-1;
	Pointtmp.y=-1;
	

	if(CurrentPoint.x!=this->width-1)
	{
		Pointtmp.x=CurrentPoint.x+1;
		Pointtmp.y=CurrentPoint.y;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	if((CurrentPoint.y!=this->height-1)&&(CurrentPoint.x!=this->width-1))
	{
		Pointtmp.x=CurrentPoint.x+1;
		Pointtmp.y=CurrentPoint.y+1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	if(CurrentPoint.y!=this->height-1)
	{
		Pointtmp.x=CurrentPoint.x;
		Pointtmp.y=CurrentPoint.y+1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	if((CurrentPoint.x!=0)&&(CurrentPoint.y!=this->height-1))
	{
		Pointtmp.x=CurrentPoint.x-1;
		Pointtmp.y=CurrentPoint.y+1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	if(CurrentPoint.x!=0)
	{
		Pointtmp.x=CurrentPoint.x-1;
		Pointtmp.y=CurrentPoint.y;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	if((CurrentPoint.x!=0)&&(CurrentPoint.y!=0))
	{
		Pointtmp.x=CurrentPoint.x-1;
		Pointtmp.y=CurrentPoint.y-1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	
	if(CurrentPoint.y != 0)
	{
		Pointtmp.x = CurrentPoint.x;
		Pointtmp.y = CurrentPoint.y-1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
			return Pointtmp;
	}
   	if((CurrentPoint.y!=0)&&(CurrentPoint.x!=this->width-1))
	{
		Pointtmp.y=CurrentPoint.y-1;
		Pointtmp.x=CurrentPoint.x+1;
	
		if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
		return Pointtmp;
	}
	CPoint errorPoint;
	errorPoint.x=errorPoint.y=-2;
	return errorPoint;
	*/
	return Pointtmp;
}

BOOL DIB::IsBorderPoint(CPoint CurrentPoint ,LPBYTE lpDIBBits,WORD wBytesPerLine)
{

⌨️ 快捷键说明

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