2016-08-21 21 views
-1

我嘗試在屏幕上使用opencv作爲搜索按鈕位置。如果按鈕存在於屏幕上,opencv工作完美,但它返回一些!= 0 x,y即使圖像不存在。如何解決它?Opencv發現在屏幕上不存在的圖像

import cv2 
def buttonlocation(image): 
    im = ImageGrab.grab() 
    im.save('screenshot.png') 
    img = cv2.imread(image,0) 
    img2 = img.copy() 
    template = cv2.imread('screenshot.png',0) 
    w,h = template.shape[::-1] 
    meth = 'cv2.TM_SQDIFF' 
    img = img2.copy() 
    method = eval(meth) 
    res = cv2.matchTemplate(img,template,method) 
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 
    top_left = min_loc 
    x,y = top_left 
    return x,y 
+1

A [mcve]會很好... – Julien

回答

0

documentation of opencv詳細說明模板匹配程序的兩個步驟。

  1. R=cv2.matchTemplate(I,T,method)計算圖像R。該圖像的每個像素x,y表示取決於模板T與開始於x,yI的子圖像之間的相似性的標記。舉例來說,如果應用所述方法cv.TM_SQDIFF,標記被計算爲:

enter image description here

如果R[x,y]爲空,則所述子圖像I[x:x+sxT,y:y+syT]是完全相同的模板T。較小的R[x,y]是,子圖像越靠近模板。

  1. cv2.minMaxLoc(R)適用於查找最小值R。預計I的相應子圖像比I的任何其他子圖像更接近模板。

如果圖像I不包含模板,對應於最小的RI子圖像可以是來自T很大的不同。但最低價值體現了這一點! 實際上,R上的閾值可用作決定模板是否在圖像中的方式。

選擇閾值是一項棘手的任務。它可能是R的最大值的一部分或R的平均值的一部分。模板的大小的影響可以通過將R除以sxT*syT而放棄。例如,最大值R取決於模板大小和圖像的類型。例如,對於CV_8UC3(無符號字符,3個通道),最大值R255*3*sxT*syT

下面是一個例子:

import cv2 

img = cv2.imread('image.jpg',eval('cv2.CV_LOAD_IMAGE_COLOR')) 
template = cv2.imread('template.jpg',eval('cv2.CV_LOAD_IMAGE_COLOR')) 

cv2.imshow('image',img) 
#cv2.waitKey(0) 
#cv2.destroyAllWindows() 

meth = 'cv2.TM_SQDIFF' 
method = eval(meth) 
res = cv2.matchTemplate(img,template,method) 
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 
top_left = min_loc 
x,y = top_left 
h,w,c=template.shape 

print 'R='+str(min_val) 
if min_val< h*w*3*(20*20): 
    cv2.rectangle(img,min_loc,(min_loc[0] + w,min_loc[1] + h),(0,255,0),3) 
else: 
    print 'first template not found' 

template = cv2.imread('template2.jpg',eval('cv2.CV_LOAD_IMAGE_COLOR')) 
res = cv2.matchTemplate(img,template,method) 
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 
top_left = min_loc 
x,y = top_left 
h,w,c=template.shape 

print 'R='+str(min_val) 
if min_val< h*w*3*(20*20): 
    cv2.rectangle(img,min_loc,(min_loc[0] + w,min_loc[1] + h),(0,0,255),3) 
else: 
    print 'second template not found' 

cv2.imwrite("result.jpg", img); 

cv2.namedWindow('res',0) 
cv2.imshow('res',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

圖像: enter image description here

第一個模板將被找到: enter image description here

第二模板不被發現: enter image description here

結果: enter image description here