为什么OpenCV中的drawcontours不能填充图像边缘的轮廓?

use*_*402 13 python opencv

编辑:我通过向图像添加2位帧,然后使用我的代码,最后裁剪图像以删除额外的帧来绕过问题.这是一个丑陋的解决方案,但它的工作原理!


我遇到了一个问题,我不确定这是一个错误还是我缺乏经验.我会尽可能清楚地总结一下:

  1. 我得到一个二进制图像,其中包含我想要分析的彩色图像的轮廓(白色像素是我的算法检测到的轮廓的周长,其余为黑色).图像非常复杂,因为我想要检测的对象完全填充图像(没有"背景").

  2. 我对该图像使用findcontours:

    contours, hierarchy = cv2.findContours(image,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后"for"循环检测面积小于"X"像素的轮廓和hierarchy[0][x][3] >= 0(让我们调用新数组"contours_2")

  4. 我在新图像中绘制"contours_2":

    cv2.drawContours(image=image2, contours=contours_2, contourIdx=-1, color=(255,255,255), thickness=-1)
    
    Run Code Online (Sandbox Code Playgroud)

问题是drawcontours绘制所有轮廓都很好,但它不会"填充"图像边界中的轮廓(也就是说,图像边缘有一个边界的轮廓).我尝试将图像的边框像素(如框架)设置为True,但它不起作用,因为findcontours会自动将这些像素设置为零(在函数说明中).

使用cv2.contourArea在前面的回路检测的轮廓以及返回正常值,所以没有办法知道当一个轮廓将drawcontours被忽略,什么时候会填写正确.cv2.isContourConvex根本不起作用,因为每个轮廓返回为假.

我可以在绘制它们之前使用cv2.convexHull绘制那些"边缘"轮廓,但我只需要在边缘上使用它(因为它会使轮廓变形并且我想尽可能地避免这种情况).问题是......我无法检测哪些轮廓位于图像的边缘,哪些轮廓不是,并且使用drawcontours可以正常工作.

所以我想问为什么drawContour表现得那样,如果有一些方法可以让它填充边缘的轮廓.或者,另一种解决方案是找到如何检测图像边界中的轮廓(因此我可以在需要时应用凸包).

Dan*_*rez 6

如果您只有 1 个轮廓并且您使用contourIdx=-1它,则会认为轮廓中的每个点都是一个单独的轮廓。您需要将单个轮廓包装为一个列表(即,contours=[contours_2]如果 中只有一个轮廓contours_2


tfv*_*tfv 2

除了边缘出现一条小白线之外,填充边缘的轮廓没有任何问题。

在此输入图像描述

import cv2
import numpy as np

rows=512
cols=512

# Create image with new colour for replacement
img= np.zeros((rows,cols,3), np.uint8)
img[:,:]= (0,0,0)

#img=cv2.copyMakeBorder(img,1,1,1,1, cv2.BORDER_CONSTANT, value=[0,0,0])

# Draw rectangle
img = cv2.rectangle(img,(400,0),(512,100),(255,255,255),-1)

imggray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


# Find Contour
_, contours, hierarchy = cv2.findContours( imggray.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img, contours, 0, (0,0,255), -1)

cv2.imshow('image',img)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)