首页 > 解决方案 > 如何使用 OpenCV 从图像中删除内部和边界轮廓?

问题描述

我使用 OpenCv 中的 findContours() 函数绘制轮廓线。我想从中消除边界和内部轮廓

在此处输入图像描述

这是我用来绘制轮廓的代码

import numpy as np
import cv2 as cv

im = cv.imread('0.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
#ret, thresh = cv.threshold(imgray, 127, 255, 0)
blur = cv.GaussianBlur(imgray,(5,5),0)
ret3,thresh = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, 
cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(im, contours, -1 ,(0,0,255), 1)
cv.imwrite('image.jpg',im)

标签: pythonopencvimage-processingopencv-contour

解决方案


函数 findContours 检测非零像素周围的轮廓。在您的示例中,背景是白色的,而您尝试检测的对象是黑色的,因此在背景周围检测到轮廓,而不是您期望的对象。假设背景颜色为 255,您可以简单地使用 cv2.bitwise_not 函数对图像进行取反以使背景变黑。

现在,当您正确定义了对象和背景后,您可以使用标志 CV_RETR_EXTERNAL 用于 findContours 函数来仅检测外部轮廓。请注意,如果背景为白色,则此标志将不起作用,因为所有这些字母都是图像边框上这一大轮廓的内部轮廓。

这是固定代码:

import numpy as np
import cv2 as cv

im = cv.imread('0.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
blur = cv.GaussianBlur(imgray, (5, 5), 0)
ret3, thresh = cv.threshold(blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
thresh_inverse = cv.bitwise_not(imgray)
contours, hierarchy = cv.findContours(thresh_inverse, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(im, contours, -1, (0, 0, 255), 1)
cv.imwrite('image.jpg', im)

更新

作为使用 cv2.bitwise_not 的替代方法,您可以更改阈值函数,它将 255 值分配给深色字母而不是背景:

ret3, thresh = cv.threshold(blur, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)

推荐阅读