How to Split Contour
This is general idea how you can split contour using pyhton and OpenCV.
First, you need black and white object to be able trace the contour. Using the binary threshold, you can get a binary image from your image. For example, I use circle as my shape.
import cv2
import numpy as np
import copy
#Generate a 640 by 640 black image
image = np.zeros((640, 640), dtype=np.uint8)
# Draw a circle
cv2.circle(image, (320, 320), 200, 255, -1) # Draw the main moon circle
# Apply a binary threshold to get a binary image
_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
Then, make contour for your detected shape
# Find contours in the binary image
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw contours on the original image
contour_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # Convert to BGR for color drawing
cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2) # Draw all contours in green
Make a definition to split the contour. To make that happen, I created a black line where it split the contour. You have to determined where the 2 point that will be used to create the line.
def split_contour(image):
# Deepcopy the image to avoid modifying the original
image_copy = copy.deepcopy(image)
#Determine the start and the end point of your line
point1 = (0, 320)
point2 = (640, 320)
# Draw a line from the center to the calculated endpoint
cv2.line(image_copy, point1, point2, (0, 0, 0), 3)
# Find contours again on the modified image copy
split_contours, _ = cv2.findContours(image_copy, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return split_contours
And then, make your binary image do the processing and display it. Because I just wanted 2 splitted area, so I make sure only to 2 area of contour.
split_contours = []
contours = split_contour(image)
if len(contours) == 2: # Ensure there are exactly 2 contours found
area1 = cv2.contourArea(contours[0])
area2 = cv2.contourArea(contours[1])
area_diff = abs(area1 - area2) # Calculate the difference of area between the 2 contours
split_contours = contours
areas = [cv2.contourArea(contour) for contour in split_contours]
print(f"Areas of contours: {areas}")
# Draw the split contours on the original image
contour_image_split = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # Convert to BGR for color drawing
for i, contour in enumerate(split_contours):
color = (np.random.randint(0, 256), np.random.randint(0, 256), np.random.randint(0, 256)) # Random color
cv2.drawContours(contour_image_split, split_contours, i, color, 5) # Draw each split contour in a different color
# Display the original image and the split contours
cv2.imshow('Original image', image)
cv2.imshow('Contour image', contour_image)
cv2.imshow('Splitted image', contour_image_split)
# waits for user to press any key
# (this is necessary to avoid Python kernel form crashing)
cv2.waitKey(0)
# closing all open windows
cv2.destroyAllWindows()