[英]Separate lines and circles in an image using OpenCV in python
I'm trying to separate the lines and circles, instead of lines some circles are connected with curves.我试图将线条和圆圈分开,而不是一些圆圈与曲线连接的线条。
I tried to use contours to find circles but it is however including the lines inside the contour, so I also tried skeletoning the image so that to see if the connection between the circles and lines might break, but it is unsuccessful.我尝试使用轮廓来查找圆圈,但它包括轮廓内的线条,因此我还尝试对图像进行骨架化,以查看圆圈和线条之间的连接是否可能会中断,但未成功。
Hough_circles is not detecting circles in all cases, so the only option I've to find the circles using contours once the lines around it are eliminated. Hough_circles 并非在所有情况下都检测到圆圈,因此一旦消除了周围的线条,我就必须使用轮廓找到圆圈。
Example 2示例 2
Input
Output : Not desired output
In the output image, I got circles weren't got separated and lines got merged with circles and the contour gave a different shape.在输出图像中,我得到的圆圈没有被分开,线条与圆圈合并,轮廓给出了不同的形状。
Please find some way to split the circles and lines.请找到一些方法来分割圆和线。 Please try to answer it in Python instead of C++.
请尝试用 Python 而不是 C++ 来回答。 C++ answers are allowed too.
也允许使用 C++ 答案。
Thanks in advance!提前致谢!
Here's a simple approach using morphological operations.这是使用形态学操作的简单方法。 The idea is to fill the contours, create an elliptical shaped structuring element, then morph open to remove the lines.
这个想法是填充轮廓,创建一个椭圆形的结构元素,然后变形打开以去除线条。 From here we simply find the external contours and draw the circles.
从这里我们只需找到外部轮廓并绘制圆圈。 Here's the process visualized:
这是可视化的过程:
Filled thresholded image填充阈值图像
Morph open变形打开
Result结果
Code代码
import cv2
# Load iamge, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Fill contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(thresh, [c], -1, (255,255,255), -1)
# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)
# Draw circles
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.drawContours(image, [c], -1, (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()
For the other image using contour hierarchy对于使用轮廓层次结构的其他图像
import cv2
import numpy as np
# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Filter using contour hierarchy
cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
hierarchy = hierarchy[0]
for component in zip(cnts, hierarchy):
currentContour = component[0]
currentHierarchy = component[1]
x,y,w,h = cv2.boundingRect(currentContour)
# Only select inner contours
if currentHierarchy[3] > 0:
cv2.drawContours(mask, [currentContour], -1, (255,255,255), -1)
# Filter contours on mask using contour approximation
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.05 * peri, True)
if len(approx) > 5:
cv2.drawContours(mask, [c], -1, (0,0,0), -1)
else:
cv2.drawContours(image, [c], -1, (36,255,12), 2)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.imshow('mask', mask)
cv2.waitKey()
Note: For a through explanation on contour hierarchy, take a look at this post注意:有关轮廓层次结构的详细解释,请查看此帖子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.