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
错误原因&修复方案
- 坐标遍历错误:
np.where(result <= threshold)返回的是包含行、列索引的元组(格式为(array([y1,y2...]), array([x1,x2...]))),直接遍历这个元组会拿到整组索引数组,而非单个坐标,导致cv.rectangle收到的参数长度不符合要求。 - 阈值设置错误:
TM_SQDIFF_NORMED的匹配结果范围是0到1,值越小匹配度越高,你设的25完全超出范围,永远不会找到匹配。 - 函数参数错误:代码里错误地写了
(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
相关产品推荐
相关产品推荐

