You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改OpenCV-Python的Template Matching代码以检测计数图片右下角星星?

OpenCV模板匹配检测星星失败的修改方案

针对你的星星检测代码无法识别目标图中星星的问题,可以从以下几个方向调整:

  • 降低匹配阈值
    你当前设置的threshold = 0.8可能过高,实际匹配得分达不到这个标准。可以先尝试调低阈值(比如0.6),再根据输出的res值调整到合适的数值,确保能覆盖真实匹配结果。

  • 添加多尺度匹配逻辑
    如果目标图中的星星和模板图尺寸不一致,单尺度模板匹配会失效。可以通过缩放模板或目标图,在不同尺度下执行匹配:

    # 多尺度匹配示例片段
    scales = [0.8, 1.0, 1.2]  # 根据实际情况调整缩放比例
    for scale in scales:
        resized_template = cv.resize(template, None, fx=scale, fy=scale, interpolation=cv.INTER_AREA)
        w, h = resized_template.shape[::-1]
        res = cv.matchTemplate(img_gray, resized_template, cv.TM_CCOEFF_NORMED)
        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)
    
  • 增加图像预处理步骤
    对目标图和模板做预处理,突出星星特征、减少噪声:

    # 示例:二值化处理
    _, img_gray_bin = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY_INV)  # 根据星星颜色调整阈值和反转参数
    _, template_bin = cv.threshold(template, 127, 255, cv.THRESH_BINARY_INV)
    # 用二值化后的图像做匹配
    res = cv.matchTemplate(img_gray_bin, template_bin, cv.TM_CCOEFF_NORMED)
    
  • 尝试不同的匹配方法
    不同匹配算法的适配场景不同,比如TM_SQDIFF_NORMED的匹配得分越低越接近匹配,你可以替换方法测试:

    res = cv.matchTemplate(img_gray, template, cv.TM_SQDIFF_NORMED)
    threshold = 0.2  # 注意这个方法的阈值逻辑相反,需要调低
    loc = np.where(res <= threshold)
    
  • 验证图像加载正确性
    检查img_rgb和template是否成功加载,避免路径错误或图像损坏:

    if img_rgb is None:
        print("目标图加载失败")
    if template is None:
        print("模板图加载失败")
    

修改后的完整示例代码(结合多尺度+预处理):

import cv2 as cv
import numpy as np

img_rgb = cv.imread('page.png')
if img_rgb is None:
    print("目标图加载失败")
    exit()
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
# 二值化预处理
_, img_gray_bin = cv.threshold(img_gray, 150, 255, cv.THRESH_BINARY_INV)

template = cv.imread('star_temp.png', 0)
if template is None:
    print("模板图加载失败")
    exit()
_, template_bin = cv.threshold(template, 150, 255, cv.THRESH_BINARY_INV)

threshold = 0.6
scales = [0.9, 1.0, 1.1]
star_count = 0

for scale in scales:
    resized_template = cv.resize(template_bin, None, fx=scale, fy=scale, interpolation=cv.INTER_AREA)
    w, h = resized_template.shape[::-1]
    # 避免缩放后模板尺寸大于目标图
    if w > img_gray_bin.shape[1] or h > img_gray_bin.shape[0]:
        continue
    res = cv.matchTemplate(img_gray_bin, resized_template, cv.TM_CCOEFF_NORMED)
    loc = np.where(res >= threshold)
    star_count += len(loc[0])
    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)
print(f"检测到星星数量:{star_count}")

内容的提问来源于stack exchange,提问作者Ekoar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:05:42