读书人

用VC实现屏幕上图像比对的原理多谢大

发布时间: 2012-01-07 21:41:55 作者: rapoo

求助用VC实现屏幕上图像比对的原理,谢谢大家进来给予指点或参与讨论。
我现在的情况是学会用VC和MFC没有多久,也大致看过Windows图形基础(包括GDI结构和一些绘制函数),有过Win32 SDK开发经历,来这里请教下大家关于如何进行屏幕上图像比对的原理和具体的方法,我总结了一下基本就是以下两个方面的问题。

第一种情况是要对屏幕上某个区域进行截图,得到图像后再和事先存在本地的一个图象数据比较,当然肯定事先存放的这个图象和屏幕上取得的这个图像,大小,内容这些都是完全一致的,问下这个实现原理是怎么样的,实现过程的话,是把屏幕上获得的内存数据保存为图片文件再和本地的图片文件比较好?还是把本地的图片文件加载到内存中去和屏幕上取的内存数据进行比较好?


第二种情况,针对屏幕上的某些图像比如前景是数字,样式颜色等都是固定不变的,但是图象背景有可能是动态变化的,这样的情况又应该怎样进行比对了?


先在这里谢谢来回复提供帮忙的朋友了,提供实现原理,具体实现代码和相关资料的都非常感谢。

[解决办法]
截取图像代码很多我就不帖了,http://blog.csdn.net/zhanghulin/archive/2008/09/16/2935659.aspx 你看看,或者自己去搜索。

BitBlt()函数有位图异或功能
将一个位图用BitBlt的异或方式画到另一个位图上,结果就是异或的。如果两幅图像是完全一样的,异或出来则是一个空的BYTE数组,图标被使用BYTE的数组方式进行比较

C/C++ code
          BYTE   *lpDib;             BYTE   *lpBase;                       BITMAPINFOHEADER   bi;                     DWORD     dwLen;             DibInfo   (Orghdib,   &bi);             dwLen       =   GlobalSize   (Orghdib);     lpDib       =   (BYTE   *)GlobalLock(Orghdib);             lpDib     +=   (DWORD)bi.biSize   +   PaletteSize((LPSTR)&bi);     lpBase     =   (BYTE   *)GlobalLock   (Tarhdib);             lpBase   +=   (DWORD)bi.biSize   +   PaletteSize((LPSTR)&bi);     dwLen       =   dwLen   -   bi.biSize   -   PaletteSize((LPSTR)&bi);             while   (dwLen--)       {/*             if(   *lpDib   >=   (int)(debasehow*(*lpBase))   )             *lpDib   -=   (int)(debasehow*(*lpBase));             else             *lpDib   =   0; */     在本处加入异或操作:   *lpDig   ^=   lpBase;             lpDib   ++;             lpBase   ++;             }             GlobalUnlock   (Orghdib);             GlobalUnlock   (Tarhdib);
[解决办法]
楼上的很好


截取图像代码很多我就不帖了,http://blog.csdn.net/zhanghulin/archive/2008/09/16/2935659.aspx 你看看,或者自己去搜索。

BitBlt()函数有位图异或功能
将一个位图用BitBlt的异或方式画到另一个位图上,结果就是异或的。如果两幅图像是完全一样的,异或出来则是一个空的BYTE数组,图标被使用BYTE的数组方式进行比较


C/C++ code
[解决办法]
楼上的很好


截取图像代码很多我就不帖了,http://blog.csdn.net/zhanghulin/archive/2008/09/16/2935659.aspx 你看看,或者自己去搜索。

BitBlt()函数有位图异或功能
将一个位图用BitBlt的异或方式画到另一个位图上,结果就是异或的。如果两幅图像是完全一样的,异或出来则是一个空的BYTE数组,图标被使用BYTE的数组方式进行比较


C/C++ code
[解决办法]
做毕设,有会用VC++编程实现地图的路径规划的吗?CAD格式的地图已经有了,现在要用VC++编写一个程序,实现这张地图的路径规划,就是最后做出一个程序,来实现这样一个东西:点地图一点 然后再点地图另一点,形成一个两点间的最优路径。最好是用 A-star算法 或者 蚁群算法或者 遗传 算法 来实现,其他的也可以,能实现就好,主要是地图已经定了,希望哪位大虾会帮帮忙啊,报酬什么的在议,有意的加我QQ:48028064,热心提供一些资料的也欢迎啊~谢谢各位了~
[解决办法]
刚刚才写的blog,希望对你有所帮助。

http://blog.csdn.net/greatws/archive/2009/05/06/4153247.aspx
[解决办法]
这么多人回帖,我也说说
看起来你像是做一个游戏外挂
如果是对两幅图像进行相似性比较,那么方法有很多,我们常用的是差方和,比如你可以把一个图像当做一个窗口,然后在另一幅图像上逐点移动,计算两幅图像的每一个位置的差方和,最小的差方和就是匹配到的位置。当然,如果图像比较大,那么你可以先把图像缩小,比如高宽变成原来的 1/4 这样搜索速度提升 16 倍。在搜索到的位置,把两幅图像相减,得到一个 Blob 图,然后你可以进行 Blob 统计。

不知道你有没有图像相关的知识,如果有,看我上面说的应该不难理解
[解决办法]
先准备一个前景数字纯白背景纯黑的图片

我刚刚弄了一个动态生成BMP的类,你可能用的上,已经上传,“动态生成BMP";如果不行,请来我的论坛:http://groups.google.com/group/direct3d_Game/web/%E5%8A%A8%E6%80%81%E7%94%9F%E6%88%90bmp?hl=zh-CN&msg=ns
[解决办法]
图像就是像素点,就是数字
是数字就可以进行比较
看你怎么处理了
LZ说的应该类似于人脸识别的技术,有一个匹配度的问题
要是鼠标屏幕截图的话很难精确的吧
截取的图像信息跟本地保存的图像很难100%一致的
人脸识别也不是精确到100%
只要图像特征符合一定的范围就算一致的


找找人脸识别和指纹识别的资料看看应该有收获


[解决办法]
楼主要看是什么途径获取的图像,如果是计算机生成的,那两幅图可以做到90%-100%的吻合,如果是摄像头或其他成像设备输出的图像的话吻合率是很低的,估计也就30%-60%,用BitBlt和memcmp是根本无法比较得到正确结果的,用前面的兄弟说的差方和是一个很好的办法,对需要比较的图像区域像素点的差异值进行统计,当差异值最小的时候可以认为图片范围已经找到,借助人工给定的阀值就可以判定图像是不是一致,根据阀值的范围还可以断定相似程度。你的3个问题都可以用这样的方法解决,建议你先将图像进行二值化处理(如果不需要比较色彩的话),然后对灰度差进行统计,统计公式可以用:

统计结果 = ∑[(图像1xy点-图像2xy点)*(图像1xy点-图像2xy点)]。

求和范围x,y越大速度越慢,需要效率的话可以取一部分点来求和,找出最小的值,不过准确度会随着降低,效率和准确度间就靠自己把握了。
[解决办法]
楼主,关于问题一,最优化的方式是用CRC算法

(1)源图像的数据作CRC运算(比如CRC32),得到一个数值A
(2)要比对的图像也作相同的CRC运算,得到数值B
只要数值A=B,那这两个图像就是一致的。

好处有二:源图像只被访问一次;判断速度最快


PS:每次都逐字节比较两个图像数据,是很低效的实现方式。


[解决办法]
如果想得到每一个像素点完全一致的话。是有一定的难度 。
图片的大小,分辨率,颜色,深度。
如果是一样的话。
我想可以用
GetPixel 获取指定点像素的RGB颜色值
SetPixel 设置指定点像素为最接近指定色的近似值
这样对RGB颜色进行比较。

[解决办法]
模式识别中模版匹配、BP算法
或者采用图像相似度公式,相似度公式网络上可以查找到。

读书人网 >VC/MFC

热点推荐