我采用的比较标准是:比较2幅图片,如果屏幕上颜色不同的象素点少于20个,认为测试通过,否则为不通过。
另外象素点颜色不同的标准为:如果象素点的RGB颜色差值小于20,则认为2个象素点颜色相同,否则为不同。
写了段程序如下,明明是两个不同的图片,比较的结果却是相同。请达人帮我看下哪里出现问题了,谢谢!int CmpBmp(HBITMAP hBitmap1, HBITMAP hBitmap2)
{
UINT diff_num, h, w;
BITMAP bm1,bm2;
int r1, g1, b1, r2, g2, b2;
COLORREF col1, col2; GetObject(hBitmap1,sizeof(BITMAP),(LPVOID)&bm1);//获取位图尺寸
GetObject(hBitmap2,sizeof(BITMAP),(LPVOID)&bm2);//获取位图尺寸 if((bm1.bmHeight != bm2.bmHeight) || (bm1.bmWidth != bm2.bmWidth))
{
return 10;
} diff_num = 0; for(h = 0; h < bm1.bmHeight; h++)
{
if(diff_num > 20) break;
for(w = 0; w < bm2.bmWidth; w++)
{
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap1); //将位图选入内存设备环境中
col1 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap1); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap2); //将位图选入内存设备环境中
col2 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap2); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
if(col1 != col2)
{
r1 = GetRValue(col1);
r2 = GetRValue(col2);
g1 = GetGValue(col1);
g2 = GetGValue(col2);
b1 = GetBValue(col1);
b2 = GetBValue(col2);
if((abs(r1 - r2) > 20) || (abs(g1 - g2) > 20) || (abs(b1 - b2) > 20))
{
diff_num ++;
}
if(diff_num > 20) break;
}
}
}
if(diff_num > 20)
{
return 11;
}
else
{
return 12;
}
}
另外象素点颜色不同的标准为:如果象素点的RGB颜色差值小于20,则认为2个象素点颜色相同,否则为不同。
写了段程序如下,明明是两个不同的图片,比较的结果却是相同。请达人帮我看下哪里出现问题了,谢谢!int CmpBmp(HBITMAP hBitmap1, HBITMAP hBitmap2)
{
UINT diff_num, h, w;
BITMAP bm1,bm2;
int r1, g1, b1, r2, g2, b2;
COLORREF col1, col2; GetObject(hBitmap1,sizeof(BITMAP),(LPVOID)&bm1);//获取位图尺寸
GetObject(hBitmap2,sizeof(BITMAP),(LPVOID)&bm2);//获取位图尺寸 if((bm1.bmHeight != bm2.bmHeight) || (bm1.bmWidth != bm2.bmWidth))
{
return 10;
} diff_num = 0; for(h = 0; h < bm1.bmHeight; h++)
{
if(diff_num > 20) break;
for(w = 0; w < bm2.bmWidth; w++)
{
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap1); //将位图选入内存设备环境中
col1 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap1); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap2); //将位图选入内存设备环境中
col2 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap2); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
if(col1 != col2)
{
r1 = GetRValue(col1);
r2 = GetRValue(col2);
g1 = GetGValue(col1);
g2 = GetGValue(col2);
b1 = GetBValue(col1);
b2 = GetBValue(col2);
if((abs(r1 - r2) > 20) || (abs(g1 - g2) > 20) || (abs(b1 - b2) > 20))
{
diff_num ++;
}
if(diff_num > 20) break;
}
}
}
if(diff_num > 20)
{
return 11;
}
else
{
return 12;
}
}
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap1); //将位图选入内存设备环境中
col1 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap1); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap2); //将位图选入内存设备环境中
col2 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap2); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap1); //将位图选入内存设备环境中
col1 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap1); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap2); //将位图选入内存设备环境中
col2 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap2); //释放位图
ReleaseDC(NULL,hdc); //释放设备环境句柄
不过有个疑问
// hdc1 hdc2 在哪声明的?int CmpBmp(HBITMAP hBitmap1, HBITMAP hBitmap2)
{
UINT diff_num, h, w;
BITMAP bm1,bm2;
int r1, g1, b1, r2, g2, b2;
COLORREF col1, col2; GetObject(hBitmap1,sizeof(BITMAP),(LPVOID)&bm1);//获取位图尺寸
GetObject(hBitmap2,sizeof(BITMAP),(LPVOID)&bm2);//获取位图尺寸 if((bm1.bmHeight != bm2.bmHeight) || (bm1.bmWidth != bm2.bmWidth))
{
return 10;
} // hdc1 hdc2 在
hdc1=GetDC(NULL); //获取设备环境句柄
hdcmem1=CreateCompatibleDC(hdc1); //获取内存设备环境句柄
SelectObject(hdcmem1,hBitmap1); //将位图选入内存设备环境中
hdc2=GetDC(NULL); //获取设备环境句柄
hdcmem2=CreateCompatibleDC(hdc2); //获取内存设备环境句柄
SelectObject(hdcmem2,hBitmap2); //将位图选入内存设备环境中
diff_num = 0; for(h = 0; h < bm1.bmHeight; h++)
{
if(diff_num > 20) break;
for(w = 0; w < bm2.bmWidth; w++)
{
col1 = ::GetPixel(hdcmem,w, h);
col2 = ::GetPixel(hdcmem,w, h);
if(col1 != col2)
{
r1 = GetRValue(col1);
r2 = GetRValue(col2);
g1 = GetGValue(col1);
g2 = GetGValue(col2);
b1 = GetBValue(col1);
b2 = GetBValue(col2);
if((abs(r1 - r2) > 20) || (abs(g1 - g2) > 20) || (abs(b1 - b2) > 20))
{
diff_num ++;
}
if(diff_num > 20) break;
}
}
}
if(diff_num > 20)
{
return 11;
}
else
{
return 12;
} DeleteObject(hBitmap1); //释放位图
ReleaseDC(NULL,hdc1); //释放设备环境句柄 DeleteObject(hBitmap2); //释放位图
ReleaseDC(NULL,hdc2); //释放设备环境句柄
}
col2 = ::GetPixel(hdcmem2,w, h);
那个需要2个阈值,我以前是这样设置的:1.对应像素(灰度8bit)差>30算该像素有变化2.(变化像素数/总像素)>0.0001算有运动,晚上这个值设为0.01红外摄像机要低些
{
if(diff_num > 20) break;
for(w = 0; w < bm2.bmWidth; w++)
{
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
SelectObject(hdcmem,hBitmap1); //将位图选入内存设备环境中
col1 = ::GetPixel(hdcmem,w, h);
DeleteObject(hBitmap1); //释放位图 <<== 把这个Del了还怎么比较呢 -_-".. hBitamp2也惨遭毒手.. haha
ReleaseDC(NULL,hdc); //释放设备环境句柄
hdc=GetDC(NULL); //获取设备环境句柄
hdcmem=CreateCompatibleDC(hdc); //获取内存设备环境句柄
.....
,,
ok..gl`
建议取两个位图的数据缓存直接进行比较。
以24位真彩BMP为例:14字节的BITMAPFILEHEADER,40字节的BITMAPINFOHEADER数据,后面就是像素值,按B、G、R顺序存放。
大家为什么都喜欢这样处理BMP呢?看来书本害人不浅。
CFile f1,f2;
int nFl;
f1.Open(_T("文件1"),CFile::modeRead);
f2.Open(_T("文件2"),CFile::modeRead);
nFl = f1.GetLength();//两个图像缓冲区
BYTE * buf1 = new BYTE[nFl - 54 +1];
BYTE * buf2 = new BYTE[nFl - 54 +1];//文件头和信息头,假设两个文件时是一样的,只留一个文件的就可以
BITMAPFILEHEADER biFileHdr;
BITMAPINFOHEADER biInfoHdr;
f1.Read(&biFileHdr,sizeof(BITMAPFILEHEADER));
f2.Read(&biFileHdr,sizeof(BITMAPFILEHEADER));
f1.Read(&biInfoHdr,sizeof(BITMAPINFOHEADER));
f2.Read(&biInfoHdr,sizeof(BITMAPINFOHEADER));//在biInfoHdr里面找宽度高度等图像信息
f1.Read(buf1,nFl - 54);
f2.Read(buf2,nFl - 54);
f1.Close();
f2.Close();//现在两个BMP文件已经分别在buf1和buf2里面了,3个字节一个像素,按BGR顺序排列
//开始比较吧delete [] buf1;
delete [] buf1;54是 sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)