最近看朋友玩QQ找茬( QQ找茬主要是比較2張圖片的不同之處,然后雙擊即可 ) 我也去玩了把,結(jié)果高手如云,淪為近視眼(等級(jí))打算寫個(gè)程序讓程序自動(dòng)去識(shí)別,自動(dòng)去點(diǎn)擊鼠標(biāo)。
實(shí)現(xiàn)方法很簡(jiǎn)單,先得到2張需要比較的圖片(可以通過QQ找茬窗口句柄,得到當(dāng)前HITMAP,然后得到其像素點(diǎn)),建立一個(gè)一張表的數(shù)組,然后比較其對(duì)應(yīng)像素點(diǎn)的值是否相同,不同為1,相同為0.
這樣就可以在內(nèi)存中得到不同的區(qū)域,但這個(gè)區(qū)域是離心的,也就是不完全對(duì),必須對(duì)其進(jìn)行處理,可以通過對(duì)這些數(shù)組值為1的點(diǎn)進(jìn)行腐蝕(關(guān)于腐蝕算法主要讓一些區(qū)域膨脹一圈)
其中腐蝕算法:
對(duì)Z中的集合A和B,B對(duì)A進(jìn)行腐蝕的整個(gè)過程如下: 是以得到B的相對(duì)與它自身原點(diǎn)的映像并且由z對(duì)映像進(jìn)行移位為基礎(chǔ)的。A被B膨脹是所有位移z的集合,這樣, 和A至少有一個(gè)元素是重疊的。我們可以把上式改寫為: 結(jié)構(gòu)元素B可以看作一個(gè)卷積模板,區(qū)別在于膨脹是以集合運(yùn)算為基礎(chǔ)的,卷積是以算術(shù)運(yùn)算為基礎(chǔ)的,但兩者的處理過程是相似的。
⑴ 用結(jié)構(gòu)元素B,掃描圖像A的每一個(gè)像素
⑵ 用結(jié)構(gòu)元素與其覆蓋的二值圖像做“與”操作
⑶ 如果都為0,結(jié)果圖像的該像素為0。否則為1
通過腐蝕過后可以基本上得到我們需要找的區(qū)域,然后利用BFS得到其Rect,說明如果用DFS的話可能會(huì)出現(xiàn)棧溢出,因?yàn)橛行﹨^(qū)域太大。
得到Rect后可以SetCursorPos設(shè)置鼠標(biāo)位置(注意 : Rect是相對(duì)于窗口句柄, SetCursorPos是設(shè)置的位置是相對(duì)桌面的坐標(biāo)),最后可以
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
相應(yīng)事件。
后記:就是在做這個(gè)的時(shí)候有時(shí)候會(huì)出現(xiàn)本來是一個(gè)區(qū)域,程序會(huì)統(tǒng)計(jì)出2個(gè)區(qū)域,其實(shí)就是在腐蝕算法的時(shí)候未處理好,還有一個(gè)就是可以通過網(wǎng)絡(luò)抓包獲取原始圖片。
因?yàn)樵陬A(yù)處理的時(shí)候,復(fù)雜度還是較高,所以在找完一張完整的圖片需要5秒左右的時(shí)間。