OpenCV模板匹配报错(-215):实时相机场景下问题求助
解决OpenCV matchTemplate错误:(-215) _img.size().height <= _templ.size().height && ...
嘿,这个错误我之前帮好几个开发者排查过,本质原因特别直白:你用来匹配的模板图片尺寸,比待检测的原图还大!OpenCV的matchTemplate函数要求,待匹配的原图(也就是你代码里的img_gray)的宽度和高度,必须分别大于等于模板(template)的宽高——毕竟要在原图上滑动模板做匹配计算,模板比原图大的话根本没法滑嘛。
结合你的代码来看,问题大概率出在这两个地方:
- 要么是你选的
book.jpg(模板)本身就比mybook.png(原图)尺寸大; - 要么是其中某张图片加载失败了(比如路径写错了,导致读进来的是
None,空图的尺寸为0,也会触发这个判断)。
下面给你一步步的解决方案:
1. 先确保图片正确加载
在读取图片后立刻加个判断,避免因为路径错误导致的隐性问题:
img_rgb = cv.imread('mybook.png') if img_rgb is None: print("Error: 无法加载原图mybook.png,请检查文件路径是否正确!") exit() template = cv.imread('book.jpg', 0) if template is None: print("Error: 无法加载模板book.jpg,请检查文件路径是否正确!") exit()
2. 检查并修正尺寸问题
加载成功后,先打印两张图的尺寸,确认到底是不是模板太大:
print(f"原图尺寸: {img_gray.shape}") print(f"模板尺寸: {template.shape}")
如果确实是模板更大,有两种处理方式:
- 方式一(推荐):更换一张尺寸比原图小的模板,或者用图像编辑工具把模板裁剪到合适大小;
- 方式二:把原图放大到至少和模板一样大,用
cv.resize实现:# 获取模板的宽高 templ_h, templ_w = template.shape[:2] # 计算需要放大的比例,确保原图放大后能容纳模板 scale = max(templ_h / img_gray.shape[0], templ_w / img_gray.shape[1]) # 按比例放大原图(包括灰度图和彩色图,方便后续画框) img_gray_resized = cv.resize(img_gray, None, fx=scale, fy=scale, interpolation=cv.INTER_LINEAR) img_rgb_resized = cv.resize(img_rgb, None, fx=scale, fy=scale, interpolation=cv.INTER_LINEAR)
3. 完整修正后的示例代码
把上面的检查和处理整合到你的代码里,最终版本大概是这样:
import cv2 as cv import numpy as np # 加载原图并检查 img_rgb = cv.imread('mybook.png') if img_rgb is None: print("Error: 无法加载原图mybook.png,请检查路径是否正确!") exit() img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY) # 加载模板并检查 template = cv.imread('book.jpg', 0) if template is None: print("Error: 无法加载模板book.jpg,请检查路径是否正确!") exit() # 检查尺寸是否符合要求 img_h, img_w = img_gray.shape[:2] templ_h, templ_w = template.shape[:2] if img_h < templ_h or img_w < templ_w: print(f"警告:模板尺寸({templ_w}x{templ_h})大于原图尺寸({img_w}x{img_h}),将自动放大原图") # 计算放大比例 scale = max(templ_h / img_h, templ_w / img_w) img_gray = cv.resize(img_gray, None, fx=scale, fy=scale, interpolation=cv.INTER_LINEAR) img_rgb = cv.resize(img_rgb, None, fx=scale, fy=scale, interpolation=cv.INTER_LINEAR) # 执行模板匹配 res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED) threshold = 0.8 # 可根据实际情况调整匹配阈值 loc = np.where(res >= threshold) # 在原图上标记匹配区域 for pt in zip(*loc[::-1]): cv.rectangle(img_rgb, pt, (pt[0] + templ_w, pt[1] + templ_h), (0, 0, 255), 2) # 显示结果 cv.imshow('匹配结果', img_rgb) cv.waitKey(0) cv.destroyAllWindows()
内容的提问来源于stack exchange,提问作者JeffChen
相关产品推荐
相关产品推荐

