Other answers correctly point out that calling the [Function 1] version requires using int coordinates in some of the arguments (center and axes, specifically). However, they don't mention that you can use the shift argument to maintain "fractional bit" accuracy in the coordinates for sub-integer resolution.
Here's an example wrapper function for cv2.ellipse that can accept float coordinates and cast them to ints after rewriting them for use with the shift argument:
def draw_ellipse(
img, center, axes, angle,
startAngle, endAngle, color,
thickness=3, lineType=cv2.LINE_AA, shift=10):
center = (
int(round(center[0] * 2**shift)),
int(round(center[1] * 2**shift))
)
axes = (
int(round(axes[0] * 2**shift)),
int(round(axes[1] * 2**shift))
)
cv2.ellipse(
img, center, axes, angle,
startAngle, endAngle, color,
thickness, lineType, shift)
The shift parameter indicates the number of "fractional bits" in the center and axes coordinate values, so that's why the coordinates multiplied by powers of 2 (multiplying by 2 is the same as shifting the bits in their integer binary representations to the left by one.) This shift trick is handy with many other opencv functions, as well, but its usage isn't documented very well (especially in python).