影像匹配(大圖中找小圖)之新專案findimage

songofhawk發表於2022-01-22

之前分析aircv原始碼的時候,還是有諸多不滿,而且它也不更新維護了,提交PR也沒人理,乾脆做個新專案,目前已經提交PyPi庫,可以用下面的命名安裝:

pip install findimage

findimage不是影像搜尋,不能從一堆圖片中找到相似的那張,而是從一張大圖中定位給定模板小圖的位置。

功能

和原aircv相比,findimage有以下這些改進:

  • 支援直接傳入灰度圖(雖然函式內呼叫opencv的時候,都是使用灰度圖完成的,原aircv專案卻要求傳入的圖片必須包含bgr三個通道,不然會報錯)
  • 支援背景透明的圖片
  • 優化了find_all_template方法的效能,用numpy的切片賦值代替floodFill方法來避免重疊,大概會縮短1/4的總體查詢時間

示例

比如我們對“思否”課程選單截圖如下:
思否課程選單-標準

我們想從中找到#的位置,可以提供一張小模板圖:
思否課程選單-標準

然後呼叫find_template方法:

from cv2 import cv2
from findimage import find_template

image_origin = cv2.imread('seg_course_whole_page.png')
image_template = cv2.imread('seg_sharp.png')

match_result = find_template(image_origin, image_template)

得到的match_result,標識了第一個#在源圖中的中心點位置,矩形區域四角座標 和 匹配度。

{
    "result": (x,y),        #tuple,表示識別結果的中心點
    "rectangle":[            #二位陣列,表示識別結果的矩形四個角
        [left, top],
        [left, bottom],
        [right, top],
        [right, bottom]
    ],
    "confidence": percentage   #識別結果的匹配度,在-1~1之間,越大匹配度越高, 如果為1,表示按畫素嚴格匹配
}

我們可以用這個結果,在源圖上標識出匹配的位置:

img_result = image_origin.copy()
rect = match_result['rectangle']
cv2.rectangle(img_result, (rect[0][0], rect[0][1]), (rect[3][0], rect[3][1]), (0, 0, 220), 2)
cv2.imwrite('result.png', img_result)

結果如下圖所示:
find_template匹配結果

相關文章