您好,登錄后才能下訂單哦!
小編給大家分享一下微信跳一跳python輔助軟件思路及圖像識別源碼的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
首先看效果
核心思想
獲取棋子到下一個方塊的中心點的距離
計算觸摸屏幕的時間
點擊屏幕
重要方法
計算棋子到下一個方塊中心點的距離
使用 adb shell screencap -p 命令獲取手機當前屏幕畫面
再通過圖像上的信息找出棋子的坐標和下一個方塊中心點的坐標
然后通過兩點間距離公式計算出距離
計算觸摸屏幕的時間
T=A * S
其中S為上步算出的像素距離,T為按壓時間(ms),A為一個系數這個系數會隨著屏幕分辨率的變化而變化,在1920*1080的屏幕下這個系數為1.35,在2560*1440的屏幕下這個系數為1.475
點擊屏幕
adb shell input swipe x y x y time(ms)
這條命令能夠點擊手機屏幕x,y位置time(ms)
圖像處理部分源碼解析
圖像處理部分代碼都在 find_piece_and_board(im) 方法中
通過輸入的圖像im計算出棋子的坐標點以及下一個方塊中心的坐標點
在find_piece_and_board的方法中一進來就是下面的兩個嵌套在一起的for循環:
for i in range(int(h / 3), int(h * 2 / 3), 50): last_pixel = im_pixel[0, i] for j in range(1, w): pixel = im_pixel[j, i] # 不是純色的線,則記錄 scan_start_y 的值,準備跳出循環 if pixel[0] != last_pixel[0] or pixel[1] != last_pixel[1] or pixel[2] != last_pixel[2]: scan_start_y = i - 50 break if scan_start_y: break
這段代碼的作用就是從屏幕2/3的位置向下尋找不是純色的線。并將找到位置的縱坐標-50作為,尋找棋子和方塊的起始坐標。這樣可以簡化以后搜索的工作量,因為在這個橫坐標以上是沒有東西的。
接下來是查找棋子坐標的代碼
# 查找棋子坐標 # piece_x_sum 橫坐標總量 piece_x_c 點的個數 piece_y_max 縱坐標最大值 # 從 scan_start_y 開始往下掃描,棋子應位于屏幕上半部分,這里暫定不超過 2/3 for i in range(scan_start_y, int(h * 2 / 3)): for j in range(scan_x_border, w - scan_x_border): # 橫坐標方面也減少了一部分掃描開銷 pixel = im_pixel[j, i] # 根據棋子的最低行的顏色判斷,找最后一行那些點的平均值,這個顏色這樣應該 OK,暫時不提出來 if (50 < pixel[0] < 60) and (53 < pixel[1] < 63) and (95 < pixel[2] < 110): piece_x_sum += j piece_x_c += 1 piece_y_max = max(i, piece_y_max) if not all((piece_x_sum, piece_x_c)): return 0, 0, 0, 0 # 平均橫坐標 piece_x = int(piece_x_sum / piece_x_c) # 縱坐標最大值-底座一半的高度 piece_y = piece_y_max - piece_base_height_1_2 # 上移棋子底盤高度的一半
查找棋子的重要依據就是棋子的顏色較為單一并且和方塊的顏色有較大差距。如果一個像素點的RGB像素值在B(50, 60), G(53, 63), R(95, 110)范圍內那么就認為這個像素點是屬于棋子的。根據以上信息就能計算出棋子的平均橫坐標,以及最大的縱坐標值。
所以不難計算出棋子坐標(棋子平均橫坐標, 棋子最大縱坐標 - 底座一半的高度)其中底座一半的高度因手機分辨率而異。需要提前配置好。
最后是查找下一個方塊中心點的坐標的代碼
# 尋找最高的棋盤 # 棋盤不會和棋子在同一側 # 限制棋盤掃描的橫坐標,避免音符 bug if piece_x < w / 2: board_x_start = piece_x board_x_end = w else: board_x_start = 0 board_x_end = piece_x for i in range(int(h / 3), int(h * 2 / 3)): last_pixel = im_pixel[0, i] if board_x or board_y: break board_x_sum = 0 board_x_c = 0 for j in range(int(board_x_start), int(board_x_end)): pixel = im_pixel[j, i] # 下一個棋盤緊貼著棋子 # 修掉腦袋比下一個小格子還高的情況的 bug if abs(j - piece_x) < piece_body_width: continue # 修掉圓頂的時候一條線導致的小 bug,這個顏色判斷應該 OK,暫時不提出來 if abs(pixel[0] - last_pixel[0]) + abs(pixel[1] - last_pixel[1]) + abs(pixel[2] - last_pixel[2]) > 10: board_x_sum += j board_x_c += 1 if board_x_sum: # 最高棋盤的平均橫坐標 board_x = board_x_sum / board_x_c last_pixel = im_pixel[board_x, i]
代碼開頭通過棋子所在的屏幕位置限制搜索的寬度,如果棋子在屏幕左邊那么就在屏幕右邊搜索方塊,反之亦然。因為方塊和棋子不會在屏幕同一側。
然后就是自上而下得搜索方塊的上頂點。
方塊上頂點坐標( 平均橫坐標,當前行的縱坐標)
然后再往下縱坐標+247的位置開始向上找顏色與上頂點一樣的點,為下頂點。
當然此方法有一點局限性對于純色的平面效果很好但是對于非純色的平面。可能會判斷出錯。
如果上一跳命中中間,則下個目標中心會出現 r245 g245 b245 的點,利用這個屬性彌補上一段代碼可能存在的判斷錯誤
若上一跳由于某種原因沒有跳到正中間,而下一跳恰好有無法正確識別花紋,則有可能游戲失敗,由于花紋面積通常比較大,失敗概率較低
可改進方案
首先是目前方案對于多分辨率需要多個配置文件來記錄不同分辨率下的系數以及棋子底盤一半的高度。隨機測試了6臺手機其中有兩臺手機因沒有配飾而無法正常運作
首先是系數A,觀察方程T=A * S,A就是一個可訓練量,利用機器學習框架比如TensorFlow,對這個一元一次方程進行擬合。
觀察棋子底盤一半的高度在代碼中的作用。不難發現是為了求出棋子底盤中心的縱坐標。而棋子底盤中心的位置恰恰是棋子最寬的地方。所以可以通過找出棋子最寬處的縱坐標的方式找到棋子底盤中心的縱坐標。這樣就擺脫了對配置文件的依賴,能讓代碼在任何手機上正常運行。
其次是對于方塊中心坐標位置的判斷方法出錯率較高,雖然有中心白點可以彌補但是在大量跳躍的過程中還是會出現錯誤。3太手機不停運行了一下午,最高分只有2009分。
現方法出錯率高的原因是使用純顏色方法判斷,但是在實際游戲中顏色豐富的方塊也不少。如果想改變就不能依賴顏色方法判斷,而應該通過幾何圖像的形狀來計算方塊的位置。不難發現游戲中方塊只有棱形和圓形兩種形狀。
首先通過canny或其他輪廓查找算子提取出圖像的輪廓,然后通過霍夫變換提取出圓形和棱形的中心坐標。
以上是“微信跳一跳python輔助軟件思路及圖像識別源碼的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。