有没有办法在我的图像中正确找到外部轮廓

Is there a solution to find the external contour correctly in my images

我在我的程序中得到了一个分割图像作为入口,目标是将区域分成两幅图像,一幅包含外部轮廓(区域),另一幅包含内部轮廓(区域)。

python3.7 和 opencv 中的程序 我尝试使用一些形态学操作(关闭)和平滑滤波器(中值)然后我应用二进制和 otsu 阈值和精明的边缘检测以获得更好版本的轮廓与 function find contour 首先我用 CV2.RETR_EXTERNAL 提取外部轮廓,但这是我得到的:

def function(image):
    #pretraitement
    im = cv2.imread(image,0)
     _Kernel = 3  
    iteration__ = 5
    im = Pretraitement.pretraitement.lissage_median(im, _Kernel, iteration__)
    kernel = (3,3)
    im = cv2.morphologyEx(im, cv2.MORPH_CLOSE,cv2.getStructuringElement(cv2.MORPH_CROSS,kernel))

    high_thresh, im = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    lowThresh = 0.5 * high_thresh

    cv2.rectangle(im, (0, 0), (im.shape[1], im.shape[0]), 0, 3)
    contour = cv2.findcontours(
                        cv2.Canny(im.copy(), lowThresh, high_thresh),
                        Img_Colored_Readed.shape, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    MaskExtern = np.zeros((im.shape[0],im.shape[1],3),dtype=np.uint8)
    MaskRegion = np.zeros((im.shape[0],im.shape[1],3),dtype=np.uint8)
    MaskContour = = np.zeros(im.shape,dtype=np.uint8)
    for i in range(len(contour)):
                        for j in range(len(contour)):
                            #to check if the contour j is inside contour i 
                            if  BoundaryBasedDescriptors.Contours.pointInContour3(contour[i],contour[j]):
                                pass
                            else:

                                cv2.drawContours(MaskExtern,contour, j, (0,255,255), 1)
                        cv2.drawContours(MaskContour,contour,i,255,1)
                        cv2.drawContours(MaskRegion,contour,i,(255,i*10,255-i*10),-1)

                    cv2.imwrite('_external.jpg', MaskExtern)
                    cv2.imwrite('_contour.bmp', MaskContour)
                    cv2.imwrite('_colore.jpg', MaskRegion)

图像的link表示分割后的图像enter image description here

这就是我绘制厚度为 -1enter image description here

的所有轮廓时得到的结果

我希望得到正确的外部轮廓(区域)我得到一些内部区域enter image description here

这是您的代码中的错误:
cv2.rectangle(im, (0, 0), (im.shape[1], im.shape[0]), 0, 3)
结果没有赋值,所以它什么也不做。如果您在前面添加 im =,您将得到您期望的行为。

如果你的目的是将内部和外部的白色区域分开,你也可以试试这个方法。首先反转图像。然后找到黑色区域的外部轮廓(原始的,白色的倒置),然后您可以将其用作分隔该区域的遮罩。如有必要,您可以使用蒙版内部图像来找到较小的轮廓。

结果:

代码:

import cv2
import numpy as np
# load image as grayscale
img = cv2.imread('cSxN8.png',0)
# treshold to create binary image
tr, img = cv2.threshold(img,50,255,cv2.THRESH_BINARY)
# invert image
img_inv = cv2.bitwise_not(img)
# find external contours
contours, hier = cv2.findContours(img_inv, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# draw contours in gray
for cnt in contours:
    cv2.drawContours(img,[cnt],0,(127),5)
# display image
cv2.imshow('Result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```python```
import cv2 
import numpy as np
# load image as grayscale
img = cv2.imread('cSxN8.png',0)
# treshold to create binary image
tr, thresh = cv2.threshold(img,50,255,cv2.THRESH_BINARY)
img = thresh.copy()
# invert image
img_inv_ = cv2.bitwise_not(img)

#find_external_contours
_,cnt = cv2.findcontours(img_inv.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for i in cnt:
    cv2.drawContours(img, [cnt], 0, (127), 1)

#to extract the edges of the external contour
img = cv2.bitwise_xor(img,img_inv)
#binarisation of the external contour
_, img = cv2.threshold(img,126,255,cv2.THRESH_BINARY)

#now we fill the external region
cnt = cv2.findcontours(img_prete_2,cv2.RETR_CCOPM,cv2.CHAIN_APPROX_SIMPLE) 
mask_externe=np.zeros(img.shape,dtype=np.uint8)
for i in range(cnt.longeurCnt):
   cv2.drawContours(mask_externe,[cnt.contour [i]],-1,255,-1)

#get the internal region 
mask_internal = cv2.bitwise_xor(img_inv,mask_extern)


```

这是完整的解决方案(该方法由J.D提出,感谢您)