1. 程式人生 > >Opencv Python版學習筆記(三)模板匹配

Opencv Python版學習筆記(三)模板匹配

模板匹配:模板匹配是通過目標圖片在待匹配圖片進行遍歷,通過選擇一定的匹配方式能夠得到每個起始畫素點的匹配值,最終匹配值最大的位置就是候選匹配位置,也就達到了匹配查詢的效果

本例是通過滑鼠選取影象中的一塊矩形區域,遍歷原影象後得到一個匹配值矩陣,將矩陣轉換成0-255的灰度影象形式顯示出來,實驗結果圖如下

圖中最亮的點即為最佳的匹配位置,從中也可以看出即為原圖中矩形區域中心點

程式和註釋如下:

#decoding:utf-8
#!/usr/bin/env python
''' 
mouse_and_match.py [-i path | --input path: default ./]

Demonstrate using a mouse to interact with an image:
 Read in the images in a directory one by one
 Allow the user to select parts of an image with a mouse
 When they let go of the mouse, it correlates (using matchTemplate) that patch with the image.
 ESC to exit
'''
import numpy as np
from math import *
import sys
import os
import glob
import argparse
import cv2 as cv

drag_start = None#全域性變數取方塊滑鼠拖拽時使用
sel = (0,0,0,0)#全域性變數 長方形左上頜右下定點座標儲存

def onmouse(event, x, y, flags, param):#滑鼠事件響應函式
    global drag_start, sel 
    if event == cv.EVENT_LBUTTONDOWN:#左鍵按下時記錄當前初始座標,並初始化矩形sel
        drag_start = x, y
        sel = 0,0,0,0
    elif event == cv.EVENT_LBUTTONUP:#滑鼠左鍵嘆彈起時響應
        if sel[2] > sel[0] and sel[3] > sel[1]:#判斷右下角座標是否大於左上角
            patch = gray[sel[1]:sel[3],sel[0]:sel[2]]#取矩形區域內畫素作為patch影象
            result = cv.matchTemplate(gray,patch,cv.TM_CCOEFF_NORMED)#返回遍歷後匹配值矩陣,這裡選擇歸一化相關係數匹配
            result = np.abs(result)**3
            val, result = cv.threshold(result, 0.01, 0, cv.THRESH_TOZERO)#將低於0。01的值賦值為0
            result8 = cv.normalize(result,None,0,255,cv.NORM_MINMAX,cv.CV_8U)#將result轉化到0-255區間
            cv.imshow("result", result8)
        drag_start = None
    elif drag_start:
        #print flags
        if flags & cv.EVENT_FLAG_LBUTTON:#取當前座標與初始座標較小的為矩形座標左上,較大的為右下
            minpos = min(drag_start[0], x), min(drag_start[1], y)
            maxpos = max(drag_start[0], x), max(drag_start[1], y)
            sel = minpos[0], minpos[1], maxpos[0], maxpos[1]
            img = cv.cvtColor(gray, cv.COLOR_GRAY2BGR)
            cv.rectangle(img, (sel[0], sel[1]), (sel[2], sel[3]), (0,255,255), 1)
            cv.imshow("gray", img)
        else:
            print "selection is complete"
            drag_start = None
            
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Demonstrate mouse interaction with images')
    #命令列輸入引數 mouse_and_match.py -i 輸入影象路徑  預設為E:/imagetest
    parser.add_argument("-i","--input", default='E:/imagetest', help="Input directory.")
    args = parser.parse_args()
    path = args.input#獲取影象路徑引數
 
    cv.namedWindow("gray",1)
    cv.setMouseCallback("gray", onmouse)
    '''Loop through all the images in the directory'''
    for infile in glob.glob( os.path.join(path, '*.*') ):#遍歷資料夾下的圖片檔案
        ext = os.path.splitext(infile)[1][1:] #get the filename extenstion
        if ext == "png" or ext == "jpg" or ext == "bmp" or ext == "tiff" or ext == "pbm":
            print infile
            
            img=cv.imread(infile,1)
            if img == None:
                continue
            sel = (0,0,0,0)
            drag_start = None
            gray=cv.cvtColor(img, cv.COLOR_BGR2GRAY)
            cv.imshow("gray",gray)
            if (cv.waitKey() & 255) == 27:
                break
    cv.destroyAllWindows()