我正在尝试将Sobel运算符应用于简单的二进制图像,但最终的梯度却被翻转了(与scipy的signal.convolve2d
函数的输出进行比较时。
from scipy import signal
import numpy as np
import matplotlib.pyplot as plt
def sobelx_homemade(arr, kx):
offset = 1
sx = np.zeros(arr.shape)
for y in range(offset, arr.shape[0] - offset):
for x in range(offset, arr.shape[1] - offset):
rstart, rend = y-offset, y+offset+1
cstart, cend = x-offset, x+offset+1
w = arr[rstart:rend, cstart:cend]
Ix = kx * w
sx[y, x] = Ix.sum()
return sx
A = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
kx = np.array([
[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]
], dtype=np.float)
ky = np.array([
[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]
], dtype = np.float)
Gx = signal.convolve2d(A, kx, boundary='symm', mode='same')
Gy = signal.convolve2d(A, ky, boundary='symm', mode='same')
# calculate homemade sobel x gradient
myGx = sobelx_homemade(A, kx)
plt.subplot(131)
plt.title("Original")
plt.imshow(A, cmap="gray")
plt.subplot(132)
plt.title("Gx")
plt.imshow(Gx, cmap="gray")
plt.subplot(133)
plt.title("My Gx")
plt.imshow(myGx, cmap="gray")
我希望标有“ Gx”和“ My Gx”的图像完全相同。
答案 0 :(得分:0)
因此,事实证明, true 卷积会翻转内核/过滤器矩阵,从而解释了翻转的结果。
这是安德鲁·伍(Andrew Ng)的视频,解释了教科书卷积和互相关在机器学习风格图像处理中常用的区别: https://youtu.be/tQYZaDn_kSg?t=308