opencv cv2.findContours()无法完全找到轮廓

zd287kbt  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(271)

所以我试图用轮廓线重新填充图像中的黑洞,这是原始图像:

然后,我试图使用此代码来填充图像上半部分的这个唯一的小黑洞,我的意图是通过逐位与只包含最大面积轮廓的图像来删除图像下半部分的所有这些不必要的噪声,无论如何,这是我尝试的代码:

blankImage = maskImage # cv2.bitwise_not(maskImage)
contours, hierarchy = cv2.findContours(blankImage, cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
maxAreaContour = max(contours, key = cv2.contourArea)
blankImage = np.zeros(maskImage.shape, dtype='uint8')
for cnt in contours:
    cv2.drawContours(blankImage,[cnt],0,125,-1)

其中空白图像是上面的图像(原始图像),然后我试图显示绘制的轮廓,结果如下:

为什么呢

zf9nrax1

zf9nrax11#

问题是图像的上部黑色部分包含非零像素(值接近零但不是零)。
当应用cv2.findContours时,非零像素被认为是轮廓的一部分(范围[1,255]中的所有像素被认为是“白色像素”)。
非零黑色像素的示例:

我们可以在cv2.drawContours之前使用cv2.threshold来应用阈值处理:

blankImage = cv2.threshold(maskImage, 0, 255, cv2.THRESH_OTSU)[1]  # Apply binary thresholding with automatic threshold

接近零的值将被阈值化为零,白色像素将为255。
代码示例:

import cv2
import numpy as np

maskImage = cv2.imread('original_image.jpg', cv2.IMREAD_GRAYSCALE)  # Read image as grayscale.

#blankImage = maskImage # cv2.bitwise_not(maskImage)
blankImage = cv2.threshold(maskImage, 0, 255, cv2.THRESH_OTSU)[1]  # Apply binary thresholding with automatic threshold
contours, hierarchy = cv2.findContours(blankImage, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
maxAreaContour = max(contours, key=cv2.contourArea)
blankImage = np.zeros(maskImage.shape, dtype='uint8')
for cnt in contours:
    cv2.drawContours(blankImage, [cnt], 0, 125, -1)

# Show result for testing
cv2.imshow('blankImage', blankImage)
cv2.waitKey()
cv2.destroyAllWindows()

blankImage

相关问题