利用MKL实现OpenCV的模板匹配(matchTemplate)
基于FFT实现OpenCV的模板匹配(matchTemplate)
以 TM_CCORR_NORMED 为例,因为这个实现简单,并且效率高。
先看公式
显然,分子是I图和T图的卷积。
分母是T图平方的求和乘以I图平方和T图大小的全为1的矩阵,开方的结果。
根据卷积定理,实现方法就很显然了。
import numpy as np
from scipy import signal
from matplotlib import pyplot as plt
import cv2
I = cv2.imread('3.png', cv2.IMREAD_GRAYSCALE)
T = cv2.imread('4.png', cv2.IMREAD_GRAYSCALE)
I = I.astype(np.float32) / 255
T = T.astype(np.float32) / 255
import mkl_fft
def mkl_fft_conv2d(A,K):
tmp_cols = A.shape[0] + K.shape[0] - 1
tmp_rows = A.shape[1] + K.shape[1] - 1
input = np.zeros((tmp_cols, tmp_rows)).astype(np.float32)
input[:A.shape[0], :A.shape[1]] = A
kernel = np.zeros((tmp_cols, tmp_rows)).astype(np.float32)
kernel[:K.shape[0], :K.shape[1]] = K
fi = mkl_fft.fft2(input)
fk = mkl_fft.fft2(kernel)
# output as valid
output = mkl_fft.ifft2(fi * fk)
output = np.real(output)
output = output[K.shape[0]-1:-K.shape[0]+1, K.shape[1]-1:-K.shape[1]+1]
return output
import time
t0 = time.time()
r0 = mkl_fft_conv2d(I, np.flip(T,axis=(0,1)))
ST = np.sum(T ** 2)
S = mkl_fft_conv2d(I ** 2, np.ones_like(T))
r0 = r0 / np.sqrt(ST * S)
t1 = time.time()
print('fftconvolve:', t1-t0)
t0 = time.time()
r1 = cv2.matchTemplate(I, T, cv2.TM_CCORR_NORMED)
t1 = time.time()
print('matchTemplate:', t1-t0)
plt.figure()
plt.imshow(r0)
plt.colorbar()
plt.title('fftconvolve')
plt.figure()
plt.imshow(r1)
plt.colorbar()
plt.title('matchTemplate')
plt.show()
max_x0, max_y0 = np.unravel_index(np.argmax(r0), r0.shape)
max_x1, max_y1 = np.unravel_index(np.argmax(r1), r1.shape)
print(max_x0, max_y0)
print(max_x1, max_y1)
print(r0[max_x1, max_y1])
和OpenCV效果对比
可以看出结果是一样的
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战