Incomplete ellipse fitting by python

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)