Str*_*nge 4 python opencv image image-processing computer-vision
我试图将线条和圆圈分开,而不是一些圆圈与曲线连接的线条。
我尝试使用轮廓来查找圆圈,但它包括轮廓内的线条,因此我还尝试对图像进行骨架化,以查看圆圈和线条之间的连接是否可能会中断,但未成功。
Hough_circles 并非在所有情况下都检测到圆圈,因此一旦消除了周围的线条,我必须使用轮廓找到圆圈的唯一选择。
示例 2
Input
Run Code Online (Sandbox Code Playgroud)
Output :  Not desired output
Run Code Online (Sandbox Code Playgroud)
在输出图像中,我得到的圆圈没有被分开,线条与圆圈合并,轮廓给出了不同的形状。
请找到一些方法来分割圆和线。请尝试用 Python 而不是 C++ 来回答。也允许使用 C++ 答案。
提前致谢!
这是使用形态学操作的简单方法。这个想法是填充轮廓,创建一个椭圆形的结构元素,然后变形打开以去除线条。从这里我们只需找到外部轮廓并绘制圆圈。这是可视化的过程:
填充阈值图像
变形打开
结果
代码
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()
Run Code Online (Sandbox Code Playgroud)
对于使用轮廓层次结构的其他图像
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()
Run Code Online (Sandbox Code Playgroud)
注意:有关轮廓层次结构的详细解释,请查看此帖子