Python OpenCV - 模板匹配的一个功能

时间:2018-03-31 16:50:09

标签: python opencv image-recognition template-matching

我已经查看了模板匹配,我理解了这个概念并且已经为我的案例实现了它,并且它有效。这是documentation

中给出的代码
import cv2 as cv
import numpy as np

img_rgb = cv.imread('mario.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('mario_coin.png',0)
w, h = template.shape[::-1]

res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)

for pt in zip(*loc[::-1]):
    cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv.imwrite('res.png',img_rgb)

基本上这里发生的是它需要一个源图像和一个模板,读取模板并在源图像上查找匹配项。如果找到匹配项,则会在源图像上绘制一个矩形。

这适用于一个图像,但在我的情况下,我将在源代码中查找多个模板,据我所知,我需要复制上面的所有代码我的每个模板我正在寻找,这似乎并不合适。

所以我正在寻找的是将所有这些放入一个函数中的方法,这样它就可以用一个命令将所有内容写入我的源代码。如果我在这里看不到明显的东西,我很抱歉,但是我无法想办法正确地做到这一点。你会怎么做?

2 个答案:

答案 0 :(得分:0)

首先,我将列出所有图像文件。然后,我将遍历列表中的所有元素。现在你的代码将是 -

import cv2 as cv
import numpy as np

img_rgb = cv.imread('mario.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)

list = ['file1.png','file2.png','file3.png']

for image in list:
    template = cv.imread(image,0)
    w, h = template.shape[::-1]

    res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
    threshold = 0.8
    loc = np.where( res >= threshold)

    for pt in zip(*loc[::-1]):
        cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv.imwrite('res.png',img_rgb)

但是如果你想为每个图像使用不同的阈值和比较方法进行模板匹配,那么你可以将循环中的所有内容放在一个新函数中,并通过传递你的阈值和方法来调用该函数。

答案 1 :(得分:0)

如果我必须针对单个图像源测试多个模板,我会为模板文件夹创建一个目录(而不是像VIVEK建议的那样制作列表)

在此模板文件夹中,我将保留所有模板。

另外,我将为源图像创建一个文件夹,我将保留所有源图像。

最后,我将创建一个结果文件夹,我将在测试后存储所有源图像(带有红色矩形的图像)

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import os, errno



threshold = 0.8 #set threshold
resultsDirectory = 'results'
sourceDirectory = os.fsencode('sourceImages')
templateDirectory = os.fsencode('templates')
detectedCount = 0


for file in os.listdir(sourceDirectory):
    filename = os.fsdecode(file)
    if filename.endswith(".jpg") or filename.endswith(".png"): 

        print (filename)

        img_rgb = cv2.imread('sourceImages/'+filename)
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

        for templateFile in os.listdir(templateDirectory):
            templateFilename = os.fsdecode(templateFile)

            if filename.endswith(".jpg") or filename.endswith(".png"):
                template = cv2.imread('templates/'+templateFilename,0)
                w, h = template.shape[::-1]
                res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
                loc = np.where( res >= threshold)

                if (len(loc[0])):
                    detectedCount = detectedCount + 1
                    for pt in zip(*loc[::-1]):
                        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
                    cv2.imwrite(resultsDirectory+'/res_'+filename+'.png',img_rgb)
                    print ('/res_'+filename+'.png'+' saved')
                    # break

        print ('detected positive ' + str(detectedCount))
        continue
    else:
        continue

所以,将上面的代码放在template_matching.py中 其他文件夹将位于具有此文件的根目录中。 制作如下文件夹结构。

Template_Matching
-template_matching.py

-results

-sourceImages
 -source_image.png

-templates
 -template_1.png
 -template_2.png
 -template_3.png

您还可以使用它来针对多个模板检查多个源图像。 只需运行py template_matching.py即可看到魔力。