OpenCV(python)在一张图上进行多种模板多个方向匹配

 今天Franpper给大家带来的是在一张图像上进行多种模板的匹配

首先展示一下原图、模板,与匹配结果

原图如下:

44804cf90c7946148f09c96cd4c44234.jpeg

这里Franpper共设置了两种模板,分别是眼睛和手,如下:

                                 517cf5b6b5fb450aaa3ed88d2362caf1.png                           31d47195ccad4e3d890d0270cfd4df4a.png

匹配结果如下:

 cb489e3b7d5f49a8a98dda8000135657.jpeg

话不多说,上代码!(如果对大家有帮助的话求个关注!!!公众号是:Franpper的知识铺,谢谢大家!!!)

import cv2
import numpy as np
import os
from PIL import Image

"""
主要功能:多类模板匹配
实现原理:遍历模板文件夹,每次取出一张模板,进行旋转操作,分别以0°、90°、180°、270°在原图上进行匹配操作
"""

img_path = r'E:\pythonProject\PROJECT\matchTemplate\img'    # 存放原图像的文件夹
save_path = r'E:\pythonProject\PROJECT\matchTemplate\save'  # 匹配后图像储存路径
path = r'E:\pythonProject\PROJECT\matchTemplate\template'   # 存放模板的文件夹

file_dir = []  # 模板列表
classname = []  # 模板类别名称列表
file_name = os.listdir(path)
# 添加模板列表、模板类别名称列表
for i in range(len(file_name)):
    classname.append(file_name[i].split('.')[0])
    file_dir.append(os.path.join(path, file_name[i]))

# 进行匹配
for file in os.listdir(img_path):
    img_dir = os.path.join(img_path, file)
    print('识别', img_dir)
    img_ori = cv2.imread(img_dir, 0)
    img_w, img_h = img_ori.shape[::-1]
    for i in range(len(file_dir)):
        class_name = classname[i]
        print('图元' + class_name + '匹配中')
        trans = [0, Image.ROTATE_90, Image.ROTATE_180, Image.ROTATE_270]  # 创建用于旋转的角度列表
        for operate in trans:
            if operate == 0:  # 为0时表示不进行任何操作,即以原图进行匹配
                template = cv2.imread(file_dir[i], 0)
                w, h = template.shape[::-1]
                if w > img_w or h > img_h:  # 进行一下过滤,防止模板比原始图片大而导致无法匹配
                    break
                else:
                    res = cv2.matchTemplate(img_ori, template, cv2.TM_CCOEFF_NORMED)  # 进行匹配
                    threshold = 0.95  # 阈值视匹配结果可调
                    loc = np.where(res >= threshold)
                    for pt in zip(*loc[::-1]):
                        cv2.rectangle(img_ori, pt, (pt[0] + w, pt[1] + h), 0, 1)
                        cv2.putText(img_ori, class_name, (pt[0], pt[1] - 5), cv2.FONT_HERSHEY_TRIPLEX,
                                    (w - h) / 120, 0, 1, bottomLeftOrigin=False)
            else:
                template = cv2.imread(file_dir[i])
                # 这里Franpper因为没找到其他办法,所以用了一个笨办法,旋转的时候用的是PIL格式的图像,大家有什么好办法可以留言讨论一下!!!
                # 在PIL格式下进行transpose操作
                # cv格式转为PIL格式
                template_pil = Image.fromarray(cv2.cvtColor(template, cv2.COLOR_BGR2RGB))
                template_trans = template_pil.transpose(operate)
                # 旋转之后将PIL格式转为cv格式
                template_cv = cv2.cvtColor(np.asarray(template_trans), cv2.COLOR_RGB2BGR)
                template_cv_gray = cv2.cvtColor(np.asarray(template_cv), cv2.COLOR_BGR2GRAY)
                w, h = template_cv_gray.shape[::-1]
                if w > img_w or h > img_h:
                    break
                else:
                    res = cv2.matchTemplate(img_ori, template_cv_gray, cv2.TM_CCOEFF_NORMED)
                    threshold = 0.85
                    loc = np.where(res >= threshold)
                    for pt in zip(*loc[::-1]):
                        cv2.rectangle(img_ori, pt, (pt[0] + w, pt[1] + h), 0, 1)
                        cv2.putText(img_ori, class_name, (pt[0], pt[1] - 5), cv2.FONT_HERSHEY_TRIPLEX,
                                    (w - h) / 120, 0, 1, bottomLeftOrigin=False)
    cv2.imwrite(os.path.join(save_path, file.split('.')[0] + '_temp.jpg'), img_ori)

猜你喜欢

转载自blog.csdn.net/weixin_58283091/article/details/128217413