1. 程式人生 > >Python 打造微信小程式-加減大師輔助程式

Python 打造微信小程式-加減大師輔助程式

寫在前面:

      主要運用python進行簡單的影象處理,不得不說python用起來是真的爽,各種庫的學習使得開發變得越來越簡單...

     其實玩過這個小程式的應該知道實現起來也不是很難,很適合新手練手。第一次到了500多題不知道是因為被檢測了還是網掉了分數沒提交。。。結果以後到200分就手動停了,發現提交是正常的......

   話不多說先上效果:(gif太麻煩了將就著看吧......)


首先說一下思路:

       1.運用投屏軟體將手機螢幕投屏到電腦。(實際上也可以運用adb截圖再處理,但是adb太慢到200題後速度會變得相對很快,所以運用投屏,我這裡用的是:vysor,自行下載安裝就好了)

       2.圖片處理。截圖+識別(影象處理這裡用的是PIL庫,運用感知雜湊演算法、漢明距離進行圖片匹配)

       3.得到結果並點選。

**-***---**-**-*-**-*-*亂而華麗的分割線*--*--**-*--*--*****--*-

那就開始我們的程式碼吧:

        ok很快!我們安裝好了PIL。

        我這這裡主要用了其中的Image:

from PIL import Image

        2.圖片處理,我們需要得到圖片的雜湊值(dHash值),並運用漢明距離在我們自己做的列表中匹配最接近的。

截圖:
from PIL import ImageGrab
img = ImageGrab.grab((left,top, right, bottom))#截圖幕

        介紹一下我們這裡用的感知雜湊演算法

                一張圖片有很多個畫素點構成,每個畫素點都是一個rgb,例如:


                是一個440*300的圖片,其中的畫素點達到了13萬...都計算的話顯然有點吃力,所以我們縮小他的大小,把它縮小到15*20(當然你可以縮到其他的數字...主要是讓他足夠小並能比較準確的被識別)。然後的得到他的rgb,當然這裡我們可以先對其進行二值化,然後在得到他的黑白圖片,這樣我們可以直接得到它的一個有 1,0組成的陣列。那這個陣列對於這個圖片來說就是他的dHash。

                 這裡又有一個問題就是每個圖片都是不同的,不過這似乎很簡單就可以解決,我們可以裁剪出其中每個數字並將其dHash然後對我們預先處理(首先得到一遍1-9以及'-','+',='的dHash儲存陣列)的dHash值進行比較就可以了。

         再來介紹一下我們的漢明距離

                實際上很簡單,物件a變成物件b需要改變幾個元素,例如:字串"1235"變成"1257"需要改變的是2,2就是它們的漢明距離。我們可以運用其匹配兩個dHash,一般兩個相同數字圖片的漢明距離在5以內。

        開始我們的主要函式:
img = Image.open(path)  # 開啟一張圖片
img = img.convert('L')  # 灰度轉化
re_img = img.point(table, mode)  # table可以為陣列 在將灰度影象轉換為點陣圖影象(模式”1“)時,所有非零值都設定為255(白色)
newimg = img.crop(left, up, right, bottom)  # 裁剪
small_img = re_img.resize((width, height), mode)  # 縮小圖片這裡用 mode=Image.LANCZOS
        我們可以運用上面的某些函式將普通的img,轉換為黑白圖片。當然這裡point中的table可能有點問題,我們直接上程式碼:
table = []
for i in range(256):
    if i > threshold:
        table.append(0)
    else:
        table.append(1)
bin_img = img.point(table, '1')

        然後我們要對其進行裁剪,分為兩部分:橫向,縱向。我們不難看出上面圖片中每個數字之間是背景色的,轉為黑白圖片後就是白色的。

        我們呼叫:

import numpy
num_img = numpy.array(re_img)#將其轉換為二維陣列形式,其黑為1,白為0。

當然這還不足以讓方便我們識別我們該剪下那一部分,我們需要將其每一列每一行求和分別得到兩個一維陣列。

list(numpy.sum(numpy.array(img) == 0, axis=1)) #axis為0為列求和,1為行求和 返回一維陣列。(我也不太確定到底是0,1對應的是誰)

得到了他們求和的陣列之後我們判斷一下那一塊是大於零的並用crop裁減出來就可以了。

別忘記將其縮小!別忘記將其縮小!別忘記將其縮小!

橫豎裁剪完成後我們的到了每一個數字的縮小版,下面我們就要對其進漢明距離的匹配了。這裡也很簡單我們只要判斷一下兩個的dHash有哪些不同就好了,這裡的dHash很明顯就是我們轉換每個縮小版數字的陣列。找出最小的漢明距離然後返回它對應的值(這個應該是你已經初始化完成的,我們先找幾個樣例然後得到其dHash,手動輸入他對應的數字是多少並儲存)。

#如果有問題可以去下面程式碼借鑑一下。

運算:

 上面我們終於就完成了,下面的是運算,這個其實對於學過演算法的其實不難,但是python好就好在給你提供了你意想不到的庫。比如說得到字串中運算結果,例如

eval("2+5")==7

我們可以直接呼叫eval運算出結果並於結果對比。

3.點選:

        點選還是比較容易實現的,python庫如此強大!

import win32api, win32gui, win32con
win32gui.GetCursorPos()#得到滑鼠位置
win32api.SetCursorPos(x, y)#改變滑鼠位置到x,y
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0, 0)#點選。0,0為偏移量具體百度

------------------------------------------不亂但是不華麗的分割線-------------------------------------------------

注意點:我們還需要初始化獲取'44'這兩個數字的dHash,因為44之間是連著的所以不會被我們程式分開然後就會得到錯誤結果。算是個坑點吧。

這一隻有影象處理與匹配的函式,具體的其他的還是蠻簡單的。