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

Python多目标检测OpenCV报错求助:cv.rectangle参数解析失败

Python OpenCV模板匹配报错解决办法

问题描述

我是编程新手,正在学习Python多目标检测教程,运行代码时出现错误。已尝试查找答案,但不知道如何将解决方案适配到我的场景中,希望能得到帮助。

我的代码:

import cv2 as cv
import numpy as np

haystack_img = cv.imread('pokemon_tempv2.png', cv.IMREAD_UNCHANGED)
needle_img = cv.imread('pokestopv4.png', cv.IMREAD_UNCHANGED)

result = cv.matchTemplate(haystack_img, needle_img, cv.TM_SQDIFF_NORMED)
print(result)

threshold = 25
locations = np.where(result <= threshold)
print(locations)

if locations:
    print('Found needle.')

    needle_w = needle_img.shape[1]
    needle_h = needle_img.shape[0]
    line_color = (0, 255, 0)
    line_type = cv.LINE_4

    # Loop over all the locations and draw their rectangle
    for loc in locations:
        # Determine the box positions
        top_left = loc
        bottom_right = (top_left[0] + needle_w, top_left[1] + needle_h)
        # Draw the box
        cv.rectangle(haystack_img, top_left, bottom_right, line_color, line_type)

    cv.imshow('Matches', haystack_img)
    cv.waitKey()
    #cv.imwrite('result.jpg', haystack_img)

else:
    print('Needle not found.')

报错信息:

错误
Traceback (most recent call last):
  File "C:\Users\Toastys\PycharmProjects\PokemonTraining\venv\main.py", line 31, in <module>
    cv.rectangle(haystack_img, top_left, bottom_right, (line_color == 0, 255, 0), (line_type == cv.LINE_4))
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'rectangle'
> 重载解析失败:
>  - 无法解析'pt1'。预期序列长度为2,实际得到142970
>  - 无法解析'pt1'。预期序列长度为2,实际得到142970
>  - 无法解析'rec'。预期序列长度为4,实际得到142970
>  - 无法解析'rec'。预期序列长度为4,实际得到142970

错误原因&修复方案

  1. 坐标遍历错误:np.where(result <= threshold)返回的是包含行、列索引的元组(格式为(array([y1,y2...]), array([x1,x2...]))),直接遍历这个元组会拿到整组索引数组,而非单个坐标,导致cv.rectangle收到的参数长度不符合要求。
  2. 阈值设置错误:TM_SQDIFF_NORMED的匹配结果范围是0到1,值越小匹配度越高,你设的25完全超出范围,永远不会找到匹配。
  3. 函数参数错误:代码里错误地写了(line_color == 0, 255, 0)这类无效参数,应该直接使用定义好的变量。

修正后的代码

import cv2 as cv
import numpy as np

haystack_img = cv.imread('pokemon_tempv2.png', cv.IMREAD_UNCHANGED)
needle_img = cv.imread('pokestopv4.png', cv.IMREAD_UNCHANGED)

result = cv.matchTemplate(haystack_img, needle_img, cv.TM_SQDIFF_NORMED)
print(result)

# 修正阈值:TM_SQDIFF_NORMED结果范围0-1,这里设0.05表示匹配度极高的才保留
threshold = 0.05
locations = np.where(result <= threshold)
print(locations)

# 判断是否有匹配结果:检查locations里的数组是否非空
if len(locations[0]) > 0:
    print('Found needle.')

    needle_w = needle_img.shape[1]
    needle_h = needle_img.shape[0]
    line_color = (0, 255, 0)
    line_type = cv.LINE_4

    # 用zip(*locations)将行、列索引一一配对,得到每个匹配点的(y, x)坐标
    for y, x in zip(*locations):
        # 左上角坐标是(x, y),因为OpenCV图像的坐标是(x列, y行)
        top_left = (x, y)
        bottom_right = (x + needle_w, y + needle_h)
        # 绘制矩形
        cv.rectangle(haystack_img, top_left, bottom_right, line_color, line_type)

    cv.imshow('Matches', haystack_img)
    cv.waitKey()
    cv.destroyAllWindows()  # 加上这句关闭窗口后释放资源
    #cv.imwrite('result.jpg', haystack_img)

else:
    print('Needle not found.')

关键修改说明

  • 用zip(*locations)把行、列索引打包成单个坐标对,每个循环拿到的y是行索引,x是列索引,对应OpenCV图像的(x, y)坐标(先列后行)
  • 把阈值改成符合TM_SQDIFF_NORMED范围的小数,比如0.05,你可以根据实际匹配效果调整这个值
  • 修复cv.rectangle的参数,直接使用定义好的line_color和line_type
  • 修正匹配结果的判断逻辑:原代码里if locations:永远为真(因为np.where返回的元组永远非空),改成检查len(locations[0]) > 0才是正确判断是否有匹配点的方式

内容的提问来源于stack exchange,提问作者That's Not Toasty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:50:28