如何解决在 OpenCV 中实现加权平均绝对/平方差
我正在尝试在 Python-OpenCV 中实现模板图像和视频流帧之间的某种相关性跟踪
我正在尝试使用加权平均绝对偏差(加权 MAD)作为模板和视频帧之间的相似性度量(对象应位于最小 MAD 的位置。
我需要做的等式是:
其中 F 是图像,T 是模板,w 是权重窗口(与模板大小相同)
我知道 open-cv 提供了进行模板匹配的函数(即:cv2.matchTemplate)。最接近 MAD 的是 TM_SQDIFF_norMED,即均方偏差(MSD),我相信 open-cv 实现了这个方程
如果有一种方法可以像这样在其中实现权重函数,这将给出我想要的相似性度量
我的问题是如何在 Open-CV 中实现任何加权 MAD 或加权 MSD 而不使用 cv2.matchTemplate 函数(或类似方法)自己实现循环(以免降低速度)
解决方法
你可以用小的矩阵技巧来做到这一点。我会试着用一个例子来解释。
如果您有一个具有 k_ij 值和 3x3 权重内核 w_ij 的 3x3 内核,您可以通过在每个方向上每次移动一次,从原始图像创建 9 个图像。您最终会得到 9 张图片。
现在,您可以展平内核 t 并从堆叠的 9 个图像中减去它。结果将相当于移动内核。
取绝对值后,你可以对 w 做同样的(展平和相乘)。
最后,您可以对新轴上的张量求和并最终得到解决方案。
实现示例:
def stack_image(image,n):
channels = []
row,col = image.shape
for i in range(n):
for j in range(n):
channels.append(image[i:row-(n - i)+1,j:col-(n - j)+1])
return np.stack(channels,axis=-1)
def weighted_mad(f,t,w):
image_stack = stack_image(image=f,n=t.shape[0])
image_stack = np.abs(image_stack - t.flatten()) * w.flatten()
image_stack = image_stack.sum(axis=-1)
norm = len(image_stack.flatten())
return 1 / norm * image_stack
注意事项:
- 我的实现不处理边界(“有效”),可以通过其他方式实现。
- 我的实现假设使用方形内核 (kxk),但也可以使用矩形内核来实现。
- 只有当内核大小不太大时,解决方案才会有效。
我将回答受此答案启发的问题Compute mean squared,absolute deviation and custom similarity measure - Python/NumPy
我决定使用加权 MSD(均方偏差),因为我可以扩展方括号并在三个项上分配权重。步骤如下
1- 展开方括号
[
2- 在扩展括号上分配窗口内核
3-在每一项上分布两个求和运算符 我们将结束三个学期
3.a- Image square (F^2) 和 Window(W) 之间的卷积
3.b- -2 * Image (F) 和 window*template (T * W,element-wise) 之间的卷积
3.c- 模板平方 T^2 * window (w) (element-wise) 的总和
最后乘以 (1/(m*n))
这里是如何在 python open-cv 中做到这一点
def wmsd( img,tmp,W):
# input: img= image
# input: tmp= template
# input: W= weighting window
# return: msd_map= weighted mean square deviation map
h,w = img.shape
th,tw = tmp.shape
img_sq=np.square(np.uint64(img))
tmp_sq=np.square(np.uint64(tmp))
p1=cv2.filter2D(img_sq,-1,cv2.flip(W,-1),0)
WT=W*tmp
p2=-2*cv2.filter2D(img,cv2.flip(WT,0)
p3=np.sum(tmp_sq*W)
msd_map=(p1+p2+p3)/(th*tw)
return msd_map
这样看,可以很容易地利用 open-cv 功能以良好的 fps 快速完成此操作
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。