SSD模板匹配报错及匹配区域矩形绘制求助
SSD模板匹配错误修复与匹配区域绘制
错误原因分析
原代码存在两个关键问题引发ValueError: mismatch in the length of stride and shape:
- 重复调用
as_strided并覆盖了正确的滑动窗口数组y,第二次调用的shape为2维,但strides是原图像步长的2倍(4个元素),维度不匹配 - 后续
einsum运算依赖高维滑动窗口数组,被覆盖后的2维数组无法满足运算要求
修复后的SSD计算函数
import numpy as np from numpy.lib.stride_tricks import as_strided import cv2 def sumsqdiff3(input_image, template): window_size = template.shape # 计算输出特征图的尺寸 out_h = input_image.shape[0] - window_size[0] + 1 out_w = input_image.shape[1] - window_size[1] + 1 # 生成滑动窗口数组:shape=(out_h, out_w, h_tpl, w_tpl) y = as_strided( input_image, shape=(out_h, out_w) + window_size, strides=input_image.strides * 2 ) # SSD公式展开:sum((I-T)^2) = sum(I²) - 2*sum(I*T) + sum(T²) ssd = -2 * np.einsum('ijkl,kl->ij', y, template) ssd += np.einsum('ijkl,ijkl->ij', y, y) ssd += np.sum(template ** 2) return ssd
完整匹配与绘制流程
加载并预处理图像
将原图和模板转为灰度图,确保维度一致:# 替换为实际本地图像路径 img = cv2.imread('原图路径', cv2.IMREAD_GRAYSCALE) template = cv2.imread('模板路径', cv2.IMREAD_GRAYSCALE)计算SSD匹配结果
ssd_map = sumsqdiff3(img, template)定位最佳匹配区域
SSD值越小匹配度越高,找到最小值对应的坐标:min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ssd_map) top_left = min_loc h, w = template.shape bottom_right = (top_left[0] + w, top_left[1] + h)绘制匹配矩形框
转彩色图后绘制矩形,可选择显示或保存结果:img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2.rectangle(img_color, top_left, bottom_right, (0, 255, 0), 2) # 显示结果 cv2.imshow('匹配结果', img_color) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果 cv2.imwrite('匹配结果图.jpg', img_color)
注意事项
- 模板图尺寸必须小于原图,否则无法生成有效滑动窗口
- 若处理彩色图像,需转为灰度图或对每个通道分别计算SSD后合并结果
as_strided创建数组视图不复制数据,效率较高,但需确保尺寸和步长计算正确,避免内存越界访问
内容的提问来源于stack exchange,提问作者programmer_smart
相关产品推荐
相关产品推荐

