You can try this code.
import cv2
import numpy as np
def split_contour(gradient):
# returns the top and bottom of the contour
r1, r2 = 8, 128
c = cv2.findNonZero(gradient)
triangle = cv2.minEnclosingTriangle(c)[1]
triangle = np.intp(triangle)
score = np.zeros(3)
for i in range(0, 3):
grad_temp = gradient.copy()
cv2.line(grad_temp, triangle[i][0], triangle[(i+1) % 3][0], 0, 6)
score[i] = cv2.countNonZero(grad_temp)
idx = np.argmin(score)
cv2.line(gradient, triangle[idx][0], triangle[(idx+1) % 3][0], 0, r1)
g1 = gradient.copy()
cv2.line(gradient, triangle[idx][0], triangle[(idx+1) % 3][0], 0, r2)
g2 = gradient.copy()
g2 = cv2.bitwise_xor(g1, g2)
return (g1, g2)
img = cv2.imread('ellipse.png')
im = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
gradient = cv2.morphologyEx(im, cv2.MORPH_GRADIENT, kernel)
g1, g2 = split_contour(gradient)
pixels = cv2.findNonZero(g1)
ellipse1 = cv2.fitEllipse(pixels)
cv2.ellipse(img, ellipse1, (255, 0, 0), 1)
pixels = cv2.findNonZero(g2)
ellipse2 = cv2.fitEllipse(pixels)
cv2.ellipse(img, ellipse2, (0, 0, 255), 1)
cv2.imwrite('out.png', img)