H = np.floor(np.array(B.shape)/2).astype(np.int)
outdims = (np.array(A.shape) - np.array(B.shape)) + 1
C = C[H[0]:H[0]+outdims[0], H[1]:H[1]+outdims[1]]
运行以下代码片段说明了这两种方法在输出大小上的差异:
import cv2
import numpy as np
from scipy.signal import convolve2d
A = np.reshape(np.arange(49), (7,7)).astype(np.float32)
B = np.random.rand(2, 2) # convolve with an even kernel
C = cv2.filter2D(A, -1, B)
C2 = convolve2d(A, B, mode='valid')
H = np.floor(np.array(B.shape)/2).astype(np.int)
C = C[H[0]:-H[0],H[1]:-H[1]]
shapes_match = C.shape == C2.shape
print shapes_match # prints False
import cv2
import numpy as np
A = cv2.imread('...') # Load in image here
B = (1.0/25.0)*np.ones((5,5)) # Specify kernel here
C = cv2.filter2D(A, -1, B) # Convolve
H = np.floor(np.array(B.shape)/2).astype(np.int) # Find half dims of kernel
C = C[H[0]:-H[0],H[1]:-H[1]] # Cut away unwanted information
我将在仔细阅读scipy资料来源的基础上修改公认的答案:
(见https://github.com/scipy/scipy/blob/2526df72e5d4ca8bad6e2f4b3cbdfbc33e805865/scipy/signal/firfilter.c#L137)
它将有效的输出大小计算为
其中Ns对应于A的尺寸,Nwin对应于B的尺寸
所以替换:
^{pr2}$与
运行以下代码片段说明了这两种方法在输出大小上的差异:
OpenCV只支持对返回的输出与输入图像大小相同的图像进行卷积。因此,您仍然可以使用OpenCV的过滤函数,但只需忽略那些边缘上的像素,这些像素是内核没有完全封装在图像中的。假设您的图像内核是奇数,您可以简单地将每个维度除以一半,取地板(或向下取整)并使用这些来删除无效的信息并返回剩余的内容。正如Divakar所提到的,这与使用}'s 2D convolution method 相同。在
'valid'
选项的^{因此,假设您的图像存储在
A
中,而内核存储在B
中,您只需执行以下操作即可获得过滤后的图像,其中内核完全封装在图像中。注意,我们假设内核是奇数的,输出存储在C
中。在请注意,
^{pr2}$cv2.filter2D
执行相关,而不是卷积。然而,如果核是对称的(也就是说,如果你取转置,它等于它自己),相关和卷积是等价的。如果不是这样,那么在使用cv2.filter2D
之前,需要对内核执行180度旋转。您只需执行以下操作即可:为了进行比较,我们可以证明上面的代码等价于使用
scipy
的convolve2D
函数。下面是一个可复制的IPython会话,它向我们展示了:这个例子很容易理解。我声明一个7×7的伪矩阵,其中值从0增加到48行。我还为每个元素声明一个}来提取卷积结果的有效部分。就精度而言,}的输出。不仅要特别注意实际内容,还要注意两个输出数组的形状。在
(1/25)
的5x5内核,因此这实际上将实现一个5x5平均值过滤器。因此,我们使用cv2.filter2D
和{C
是cv2.filter2D
的输出,C2
是{但是,如果您希望保持原始图像的大小并用过滤后的结果替换受影响的像素,只需制作原始图像的副本,并使用用于删除无效信息的索引逻辑,即用卷积结果替换副本中的这些像素:
相关问题 更多 >
编程相关推荐