简体   繁体   English

convolve2d 和 filter2D 之间的区别。 为什么 output 形状有差异?

[英]Difference between convolve2d and filter2D. Why is there a difference in output shapes?

I need to perform a 2D convolution.我需要执行 2D 卷积。 I have a similarity matrix of shape 100, 100 and a filter of shape 5,5 .我有一个形状为100, 100的相似矩阵和一个形状为5,5的过滤器。

If I do using scipy:如果我使用 scipy:

scipy.signal.convolve2d(similarity_matrix, np.diag(filter))

I get 104,104 matrix in response.我得到104,104矩阵作为响应。

But if I do using OpenCV's filter2D method:但如果我确实使用 OpenCV 的 filter2D 方法:

cv2.filter2D(similarity_matrix, -1, np.diag(filter))

I get a 100,100 matrix in response.我得到一个100,100的矩阵作为响应。

  • What is happening here?这里发生了什么? Why is there a difference in shape?为什么形状有差异?
  • With convolve2d why do I get 4 extra rows and 4 extra columns?使用 convolve2d 为什么我会得到 4 个额外的行和 4 个额外的列?

The default output mode of scipy.signal.convolve2d is a full convolution. scipy.signal.convolve2d的默认output模式是全卷积。 If you want your output size to be the same as your input size, set mode parameter as "same".如果您希望您的 output 大小与您的输入大小相同,请将模式参数设置为“相同”。

scipy.signal.convolve2d(similarity_matrix, np.diag(filter), mode="same")

Update: When you convolve an image with a kernel, you can't directly calculate convolution results at the edges of the image because there are some neighbours missing.更新:当您使用 kernel 对图像进行卷积时,您无法直接计算图像边缘的卷积结果,因为缺少一些邻居。 There are different ways to solve this issue有不同的方法可以解决这个问题

1- Ignore values of the edges, eg. 1-忽略边缘的值,例如。 if your kernel is 3x3, ignore elements at the edges, if your kernel is 5x5, ignore last 2 elements at the edges and so on..如果你的 kernel 是 3x3,忽略边缘的元素,如果你的 kernel 是 5x5,忽略边缘的最后 2 个元素,依此类推。
2- Apply some kind of padding to image, meaning that enlarge your image in a specific way temporarily so that you can apply apply convolution kernel to values at the edge. 2-对图像应用某种填充,这意味着以特定方式暂时放大图像,以便您可以将卷积 kernel 应用于边缘的值。 Again, there are different ways of doing this (and this time more than 2), but most basic way is to zero-padding.同样,有不同的方法可以做到这一点(这次不止 2 种),但最基本的方法是零填充。 For example if your image size is 100x100, and your kernel is 5x5, at each side of the image (right, up, left, down) we can not calculate convolution of two outer values due to lack of neighbours.例如,如果您的图像尺寸为 100x100,而您的 kernel 为 5x5,则在图像的每一侧(右、上、左、下),由于缺少邻居,我们无法计算两个外部值的卷积。 With zero padding method you first enlarge your image to 104x104.使用零填充方法,您首先将图像放大到 104x104。 This enlarged image is consist of your original 100x100 image at the center, and some zero values added to edges, now the main thing is now you can apply your filter to the 100x100 region because you created artificial neighbours for the edge values.这个放大的图像由中心的原始 100x100 图像和添加到边缘的一些零值组成,现在主要的是现在您可以将过滤器应用于 100x100 区域,因为您为边缘值创建了人工邻居。

About the mode names:关于模式名称:
1- If you choose "padding way" and keep your output size same as your input size, its called same convolution. 1-如果您选择“填充方式”并保持 output 大小与输入大小相同,则称为相同卷积。 With padding method above this is done by dropping outer values at your enlarged image.使用上面的填充方法,这是通过在放大的图像上删除外部值来完成的。
2- If you choose "ignore edge values way" of doing convolution, your output will be smaller. 2-如果您选择“忽略边缘值方式”进行卷积,您的 output 会更小。 This is called valid convolution.这称为有效卷积。 As the name implies, you only performed convolution operation on "valid" region.顾名思义,您只对“有效”区域执行了卷积操作。
3- If you choose "padding way" and keep added values also, its called full convolution. 3-如果您选择“填充方式”并保留附加值,则称为卷积。 Notice that by cropping output of full convolution, you can obtain same and valid convolution too.请注意,通过裁剪全卷积的 output,您也可以获得相同且有效的卷积。

Amanda, a full convolution includes the zero-padding . Amanda,一个完整的卷积包括零填充 In other words, you must remove the out-of-bounds pixels:换句话说,您必须删除越界像素:

res=scipy.signal.convolve2d(similarity_matrix, np.diag(filter))
w,h=res.shape()
res=res[w-2][w-2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM