2017-09-05 26 views
3

我需要從簡單的遊戲Chrome Dyno中檢測圖像上的對象。我使用Python和Selenium開始遊戲,並加載畫布圖像。主要拍打,它檢測這個圖像上的物體,並找到Dyno和Dyno Barriers。Python - 解決圖像上的對象

enter image description here

我使用此代碼,使用OpenCV的,cv2庫解析畫面上的所有對象。 下面的代碼(兩個主要功能),需要大約80 - 200毫秒(基於障礙大小)來識別所有對象。

`

# Finding only dino object based on Template. 
# This might be optimized later with searching by contours 

def find_dino__(self, cv2_image): 
    result = cv2.matchTemplate(cv2_image.astype(np.uint8), self.dino_image, cv2.TM_CCOEFF) 
    _, _, _, dino_top_left = cv2.minMaxLoc(result) 
    dino_bottom_right = (dino_top_left[0] + self.dino_width, dino_top_left[1] + self.dino_height) 
    return GenericGameObject(dino_top_left, dino_bottom_right) 

# Find other Barrier Objects, based on position, and except 
# that, which behind Dino location. Use Dino position. 
def find_dino_barriers__(self, cv2_image, dino_object): 
    img_fil = cv2.medianBlur(cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY), 13) 
    img_th = cv2.adaptiveThreshold(img_fil, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) 
    im2, contours, hierarchy = cv2.findContours(img_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 

    objects = [] 
    for i in range(len(contours)): 
     x, y, w, h = cv2.boundingRect(contours[i]) 
     if y < Settings.DINO_WORKING_Y_AREA[0] \ 
       or y > Settings.DINO_WORKING_Y_AREA[1]: 
      continue 
     if x <= dino_object.top_right_point[0]\ 
       and y <= dino_object.top_right_point[1]: 
      continue 
     objects.append(GenericGameObject((x, y), (x + w, y + h))) 

    return objects 

`

我的目標,這是縮短這個時間,就像它可能使遊戲可玩的其他腳本。順便說一句,我啓發了IAMDinosaur項目,使用JS和Robot JS這個任務做得非常好。

+0

如果你的機器上有GPU,一個簡單的步驟就是使用OpenCV和Cuda/OpenCL。 – zindarod

+0

@Zindarod我打開了所有的建議,並可能在稍後使用OpenCL進行檢查。我甚至考慮在對象識別期間暫停遊戲(拋出激活/關閉窗口)以節省時間。 – GensaGames

+0

幾個月前我正在做一個類似的項目,在opencv的幫助下使用Pyautogui玩t rex bot。該程序可以獲得500左右的分數,但隨後屏幕截圖技術的緩慢過程導致機器人死亡。這裏是回購,如果它以某種方式幫助你:https://github.com/arsho/t_rex_bot – arsho

回答

1

三個有助於提高速度的重要建議都歸結爲同一件事情:爲處理管線的不同部分分割圖像的不同部分。通過查找不同的對象可以獲得更多的加速。兩個目標是找到恐龍位置,並找到圖像中新對象的位置。

加速比1

刪除其中T-雷克斯和對象不在坐的圖像的部分。我的意思是該幀的上半部分(ISH)。對象不在這裏,這大大減少了搜索空間。

提速2

我在您的文章評論提到了這一點。不要在整個畫面中尋找T-Rex。你知道T-Rex粘在框架的一些水平邊界內,只能垂直移動。模板匹配絕對是一個緩慢的過程,所以你會通過減少搜索區域來獲得大的加速。您可以通過使用更小的模板和更小的搜索區域來進一步優化。再一次,你知道霸王龍會在一定的部分,這意味着你知道T-Rex 頭部尾部將在某個較小的區域---所以尋找頭部或尾部或任何東西在那個地區。您可以通過將搜索區域縮小到最後一幀的位置來再次優化。我做了這個,而tracking Mario例如;你可以看到白色的搜索區域框在馬里奧的頭部位於最後一幀的位置。

提速3

請注意,您只需要找到新對象 ......你知道滾動的速度有多快,所以你知道的對象,一旦你發現它們移動的速度和在那裏他們將結束在下一幀中。對象不是整個框架的寬度,它們一次只填充框架的某個百分比。所以實際上你只需要從屏幕右側進入時搜索新對象。然後你可以標記它們(它們的寬度,高度,位置),然後計算它們在那之後的位置,而不是在每一幀中再次找到它們。現在,輪廓搜索只發生在幀的較小子集中(更快),並且輪廓較少(更快)。

提速4

請注意,您可以簡單地通過它們的底部「地」線下檢測仙人掌。似乎相似高度的仙人掌具有相似的寬度,所以如果你發現一個塊的寬度爲4像素,那麼你知道仙人掌實際上延伸出超出雙方的8個像素,並且高度爲30像素,或者實際值是什麼。這將您的問題轉化爲檢測仙人掌的基礎而不是完整的仙人掌,並減少仙人掌的搜索區域。此外,您甚至不需要使用此方法查找輪廓!您可以簡單地在圖像底部查找塊,並在它們距預定義距離小於一定距離時將它們組合在一起。這應該是的方式更快。如果你這樣做,你可能不需要擔心只檢測右邊界的物體,然後在新的框架中計算出他們的新位置......如果你只是在爲他們看一個4px寬的條帶,可能不會比僅僅每幀找到它們快得多。

其他建議

我真的不明白模糊和做自適應閾值的點。圖像已經幾乎是二元的;黑色或非黑色像素。也許這是將多個單獨的對象(如個體仙人掌)組合在一起的一種方式?無論哪種方式可能會有更好(更快)的方式來做到這一點;例如,如果你腐蝕了圖像(這會擴大暗像素),那麼仙人掌會合並。我認爲這會更快,但你需要測試。如果你這樣做了,那麼你的輪廓會比它們的實際寬度大一點,但是你可以通過使得邊界框更小,而不管你擴展的像素是多少。當然,如果你實現加速4,這並不重要,但是需要考慮。