在OpenCV中,cv2.filter2D()期望的数据类型是什么?

时间:2012-09-08 00:41:14

标签: python opencv gradient edge-detection convolution

我正在自学边缘探测器,我正在尝试使用OpenCV的filter2D来实现我自己的渐变计算器,类似于cv2.Sobel()。在OpenCV的Python界面中,cv2.filter2D()允许用户使用自定义过滤器卷积图像。在OpenCV命名法中,此过滤器称为“内核”。

使用per00001.png中的图片(MIT pedestrian dataset),我发现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)

↑GOOD


↓BROKEN

当我尝试实现自己的Sobel()代码(如下)时,我得到all-black image。我猜测问题是我传入horizontalSobelMtx的内核参数(cv2.filter2D())的数据类型。但是,我无法找到有关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)cv2.filter2D(..., kernel, ...)参数kernel期望的数据类型是什么?

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

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

我有同样的问题,但我相信我有一个部分答案。基本上,你需要加权你的内核。过滤器算法的工作方式是使用过滤器,将其相乘,然后将所有值相加并将它们用作新值。关键是ADDING部分。添加8个不同的值(一些是负的,一些是正的)通常会导致大量的,并且显示为黑色(或者在我的情况下,全部为白色)。 所以你必须补偿增加。将内核中的所有值除以内核的大小/区域。请参阅示例here并注意

  kernel = Mat::ones( kernel_size, kernel_size, CV_32F )/ (float)(kernel_size*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我的照片'弹出'进入视野。