[opencv-python] cv2.matchtemplate(...)模板匹配-多尺度的模板匹配算法

多尺度的模板匹配算法-基于(OpenCV-python-matchTemplate)

在传统的图像算法领域,模板匹配作为一种目标检测的算法有着自己的适用空间。opencv实现了模板检测的函数:
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF)
image为待检测图像,template为模板图像,cv2.TM_CCOEFF为匹配检测的方法
matchTemplate()操作相当于template对image步长为1的卷积,返回值result为二维矩阵存储着每一块区域的匹配度大小为(伪代码):
result.cols = image.cols - template.cols + 1
result.rows = image.rows - template.rows + 1

但是matchTemplate()只能检测和模板图像大小一样的目标,对于不同大小的目标,或者稍有差异的目标检测不行。
针对这样的情况,通过对模板图像和待检测图像提取轮廓图像(减少干扰),改变待检测图像的大小来实现多尺度的模板匹配算法。

#建议用最小的目标来充当模板,再放大可以出去很多噪音(博主(如下代码)就是这么做的)
template = cv2.imread("./asset/object/yourImage.jpg")
h1, w1 = template.shape[:2]
template = cv2.resize(template, (h1 * 3, w1 * 3))
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 100, 200)
(tH, tW) = template.shape[:2]

# 循环检测指定文件夹内所有bmp图片 改为自己图像存放的路径 读取文件夹下所以jpg文件
for imagePath in glob.glob("./asset/" + "/*.jpg"):
    # 加载图像,转为灰度图
    image = cv2.imread(imagePath)
    image2 = copy.deepcopy(image)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 保存最大
    found = None

    # 循环改变被检测图像的大小 以适应多尺度的模板检测 
    for scale in np.linspace(3.0, 0.0, 100):
        # 改变被检测图像大小,记录比例
        # resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
        (H, W) = gray.shape[:2]
        resized = cv2.resize(gray, (int(W*scale), int(H*scale)))
        r = gray.shape[1] / float(resized.shape[1])

        # 如果图像小于模板图像 就应当停止
        if resized.shape[0] < tH or resized.shape[1] < tW:
            break
        # 获得被检测图像边缘信息 与模板进行匹配
        edged = cv2.Canny(resized, 100, 200)
        result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
        # print(f'result,{result.shape}')

        # 获取最大值 以及对应坐标
        (_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)

        # 与之前的结果比较
        if found is None or maxVal > found[0]:
            found = (maxVal, maxLoc, r)



    # 依据比例r确定真实被检测图像中模板位置的左上角坐标以及大小
    (_, maxLoc, r) = found
    (startX, startY) = (int(maxLoc[0] * r * 1), int(maxLoc[1] * r * 1))
    (endX, endY) = (int((maxLoc[0] + tW) * r * 1), int((maxLoc[1] + tH) * r * 1))
    cv2.rectangle(image2, (startX, startY), (endX, endY), (0, 0, 255), 2)
	cv2.imshow("image2", image2)
	cv2.waitKey(0)

你可能感兴趣的:(图像算法,opencv,python,计算机视觉)