如何在低通滤波图像上找到轮廓?

how to find contours on a low pass filtered image?

我是计算机视觉的新手。所以我不知道以下代码的内部实现,因此我无法调试错误。谁能指出以下代码中的错误?

该代码使用盒式滤波器和边缘检测内核矩阵的组合将停车图像转换为二进制图像。然后我试图找到轮廓。 现在我知道轮廓是在二值图像上找到的,可以使用cv2.threshold()函数导出,从Filter和Kernel矩阵得到的图像不也是二值图像吗?

import cv2
import numpy as np
import matplotlib.pyplot as plt

img=cv2.imread('parking spot1.jpg',1)
k3 = np.array(([-1,-1,-1],[-1,8,-1],[-1,-1,-1]))
low_filter = cv2.boxFilter(img, -1, (4,4))
output_low = cv2.filter2D(low_filter, -1, k3)
plt.subplot(2, 2, 1)
plt.imshow(img)
plt.title('Original Image')

plt.subplot(2, 2, 2)
plt.imshow(output_low)
plt.title('matrix1')

plt.show()

img, ret, heirarchy = cv2.findContours(output_low, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

你认为我做错了什么? 我真的很感激这个问题的解释或指导。

非常感谢。

我面临的错误是:


Traceback (most recent call last) in () ----> 1 img, ret, heirarchy = cv2.findContours(output_low, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

error: OpenCV(3.4.3) /io/opencv/modules/imgproc/src/contours.cpp:199: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function 'cvStartFindContours_Impl

请正确阅读documentation of filtering。明确指出输出与源具有相同的大小和类型。因此,您的 output_low 是三维的,cv2.findContours 无法应用于它。您可以像您所说的那样采用阈值,也可以简单地将 output_low 转换为灰度,然后找到轮廓。

编辑

我想我的回答在陈述通道和图像深度之间的差异时不清楚。从滤波器和核矩阵得到的图像不一定是一维或灰度的。它与输入矩阵大小相同,这意味着通道数也相等。因此,如果您的输入图像是灰度图像,那么输出将是一维的。

您可以参考此处阅读有关 difference between channels and depth 的更多信息。

因此,如果您想要 cv2.boxFiltercv2.filter2D 的灰度结果,只需在对其应用过滤之前将原始图像转换为灰度。

img = cv2.imread('opencv1.png', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
k3 = np.array(([-1,-1,-1],[-1,8,-1],[-1,-1,-1]))
low_filter = cv2.boxFilter(gray, -1, (4,4))
output_low = cv2.filter2D(low_filter, -1, k3)

您的错误清楚地表明 FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 imagesCV_8UC1CV_32SC1中的C1表示通道数只能是一个。