简体   繁体   English

如何使用 OpenCV 从图像中删除内部和边界轮廓?

[英]How to remove internal and border contours from an image using OpenCV?

I used the findContours() function from OpenCv to draw contour lines.我使用了 OpenCv 中的 findContours() 函数来绘制轮廓线。 I want to eliminate border and internal contours from it我想从中消除边界和内部轮廓

在此处输入图片说明

This is the code I've used to draw contours这是我用来绘制轮廓的代码

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)

The function findContours detects contours around non-zero pixels.函数 findContours 检测非零像素周围的轮廓。 In your example the background is white, while the objects you are trying to detect are black, therefore the contours are detected around the background, not the objects as you expect.在您的示例中,背景是白色的,而您尝试检测的对象是黑色的,因此在背景周围检测到轮廓,而不是您期望的对象。 You can simply negate the image with cv2.bitwise_not function to make the background black, assuming that the background color is 255.假设背景颜色为 255,您可以简单地使用 cv2.bitwise_not 函数否定图像以使背景变黑。

Now when you have correctly defined objects and background, you can use the flag CV_RETR_EXTERNAL for findContours function to detect only external contours.现在,当您正确定义了对象和背景时,您可以使用标志 CV_RETR_EXTERNAL for findContours 函数来仅检测外部轮廓。 Note that this flag won't work if the background is white, because all those letters are internal contours for this one big contour on the image border.请注意,如果背景为白色,则此标志将不起作用,因为所有这些字母都是图像边框上这一大轮廓的内部轮廓。

Here is the fixed code:这是固定代码:

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)

Update更新

As an alternative for using the cv2.bitwise_not you can change the thresholding function that it assigns 255 value to dark letters instead of background:作为使用 cv2.bitwise_not 的替代方法,您可以更改阈值函数,它将 255 值分配给深色字母而不是背景:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM