在OpenCV中,cv2.filter2D()需要什么数据类型?

2024-05-18 23:26:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我在自学边缘检测器,并尝试使用OpenCV的filter2D来实现我自己的梯度计算器,类似于cv2.Sobel()。在OpenCV的Python接口中,cv2.filter2D()允许用户使用自定义过滤器卷积图像。在OpenCV术语中,这个过滤器被称为“内核”

使用来自MIT pedestrian dataset的图像(per00001.png),我发现cv2.Sobel()生成了一个外观合理的输出。(代码如下,output image is here。)

#OpenCV's Sobel code (outputs nice-looking gradient)
import cv2, numpy
img = cv2.imread("./per00001.png")

gradientX = cv2.Sobel(img, -1, 1, 0)

compression_params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, 9]
cv2.imwrite("gradientX.png", gradientX, compression_params)

810好


???坏

当我尝试实现我自己的类似于Sobel()的代码(如下所示)时,我得到一个all-black image。我推测问题出在我传递给cv2.filter2D()的内核参数(horizontalSobelMtx)的数据类型上。但是,我还没有找到任何关于cv2.filter2D()的内核数据类型的文档。

#Custom Sobel code (outputs all-black image)
import cv2, numpy
img = cv2.imread("./per00001.png")

horizontalSobelMtx = [[-1,0,1],[-2,0,2],[-1,0,1]]
horizontalSobelMtx = numpy.asanyarray(horizontalSobelMtx) #guessing about appropriate datatype.
gradientX_customSobel = cv2.filter2D(img, -1, horizontalSobelMtx)

compression_params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, 9]
cv2.imwrite("gradientX_customSobel.png", gradientX_customSobel, compression_params)

所以,以下是我的问题:

1)对于kernel参数,cv2.filter2D(..., kernel, ...)需要什么数据类型?

2)如果kernel的数据类型不是问题所在,那么是什么导致我的自定义Sobel代码输出一个空白图像?


Tags: 代码图像imgpngparamscv2内核opencv
2条回答

我也有同样的问题,但我相信我有部分的答案。基本上,你需要加重你的内核。过滤算法的工作方式是将你的过滤器相乘,然后将所有值相加,并将它们用作新值。关键是增加部分。添加8个不同的值(一些是负数,一些是正数)通常会导致一个很大的数字,并且显示为黑色(或者在我的例子中,全部为白色)。 所以你必须补偿额外的费用。将内核中的所有值除以内核的大小/面积。请参见示例here,并注意行

  kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*kernel_size);

它们用核大小的平方来划分所有的东西。

我自己,我做了这件事,它帮助了我(展示了一些东西),但它被冲走了,所以我把它添加到我的代码中,找到了我完美的体重:

 int d2weight = 1;
 //... start loop, make your Mat kernel
 kernel = kernel / d2weight;  //put right before your filter2d() call
 createTrackbar("kernel", "kernel", &d2weight, 255, NULL);

摆弄着吧台,在d2weight=140左右,我的照片“突然”出现在眼前。

卷积核的系数应该总是浮动的- 点数。这意味着您应该在分配矩阵时使用CV fc1。 在这个特定的示例中,请尝试:

horizontalSobelMtx = [[-1,0,1],[-2,0,2],[-1,0,1]]
horizontalSobelMtx = numpy.asanyarray(horizontalSobelMtx, np.float32)

相关问题 更多 >

    热门问题