有没有办法在我的图像中正确找到外部轮廓
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提出,感谢您)
我在我的程序中得到了一个分割图像作为入口,目标是将区域分成两幅图像,一幅包含外部轮廓(区域),另一幅包含内部轮廓(区域)。
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提出,感谢您)