首页 > 解决方案 > 如何在OpenCV中分割轮廓以打开弧线

问题描述

我有下面的图像,我需要分割轮廓以创建各种 30 度弧,然后我需要通过它来拟合一个圆圈。我唯一不知道如何分割轮廓。我在python中这样做。任何帮助都是值得的在此处输入图像描述

标签: pythonopencvimage-processing

解决方案


这个答案解释了如何将轮廓分成 12 个切片。这个答案分为三个步骤:

1. Find contours
2. Find the region that constitutes a slice
3. Test whether the contour point lies in that slice.

这是我用来查找轮廓的代码:

import cv2
import numpy as np
import math
import random
img = cv2.imread('/home/stephen/Desktop/cluv0.jpg')
h, w, _ = img.shape
low = np.array([99,130,144])
high = np.array([132,255,255])
mask = cv2.inRange(cv2.cvtColor(img, cv2.COLOR_BGR2HSV), low, high)
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour = contours[0]
center, radius = cv2.minEnclosingCircle(contour)
center = tuple(np.array(center, int))

这是我用来查找分区的代码:

distance = 2*max(img.shape)
for i in range(divisions):
    # Get some start and end points that slice the image into pieces (like a pizza)
    x = math.sin(2*i*math.pi/divisions) * distance + center[0]
    y = math.cos(2*i*math.pi/divisions) * distance + center[1]    
    x2 = math.sin(2*(i+1)*math.pi/divisions) * distance + center[0]
    y2 = math.cos(2*(i+1)*math.pi/divisions) * distance + center[1]    
    xMid = math.sin(2*(i+.5)*math.pi/divisions) * 123 + center[0]
    yMid = math.cos(2*(i+.5)*math.pi/divisions) * 123 + center[1]

    top = tuple(np.array((x,y), int))
    bottom = tuple(np.array((x2,y2), int))
    midpoint = tuple(np.array((xMid,yMid), int))

切片

为了测试轮廓点是否位于切片中,我制作了一个临时蒙版并将切片绘制为白色。然后,我检查了该点是否在蒙版图像中的白色区域中:

# Create a mask and draw the slice in white
mask = np.zeros((h,w), np.uint8)    
cv2.line(mask, center, top, 255, 1)
cv2.line(temp_image, center, top, (255,0,0), 3)
cv2.line(mask, center, bottom, 255, 1)
cv2.floodFill(mask, None, midpoint, 255)
cv2.imshow('mask', mask)
cv2.waitKey()


# Iterate through the points in the contour
for contour_point in contour:
    x,y = tuple(contour_point[0])
    # Check if the point is in the white section
    if mask[y,x] == 255:
        cv2.circle(img, (x,y), 3, color, 3)
for i in range(25):
    vid_writer.write(cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR))

这个 gif 显示了切片:

比萨

这是输出图像:

输出


推荐阅读