Kshitij Patil
Kshitij Patil

Reputation: 91

How to split a contour in to open arcs in OpenCV

I have the image below and I need to split the contour to create various 30 degrees arc which I then need to fit a circle through. The only thing I don't know how to split a contour. I am doing this in python. Any help is apperciatedenter image description here

Upvotes: 3

Views: 1590

Answers (1)

Stephen Meschke
Stephen Meschke

Reputation: 2940

This answer explains how to split the contour into 12 slices. There are three steps in this answer:

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

This is the code that I used to find the contour:

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))

This is the code that I used to find the divisions:

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))

slices

To test whether the contour point lies in the slice, I made a temporary mask and drew the slice in white. Then, I checked if the point was in a white region in the masked image:

# 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))

This gif shows the slices:

pizza

This is the output image:

output

Upvotes: 4

Related Questions