How to split a contour with python and OpenCV

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