I am working on some images to extract two curves and find their intersection points.
Doing a sobel and then applying canny edge filter pops them out.
How do I fit curves to them and find the two intersection points (which they will have for sure)?
import cv2
import numpy as np
img = cv2.imread('image6.jpg')
grad_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, 3)
grad_y = cv2.Sobel(img, cv2.CV_64F, 0, 1, 3)
grad = np.sqrt(grad_x**2 + grad_y**2)
grad_norm = (grad * 255 / grad.max()).astype(np.uint8)
grad_norm = cv2.blur(grad_norm,(3,3))
cv2.imshow('Blur', grad_norm)
cv2.waitKey(0)
# Canny Edge Detection
edges = cv2.Canny(image=grad_norm, threshold1=100, threshold2=200) # Canny Edge Detection
# Display Canny Edge Detection Image
cv2.imshow('Canny Edge Detection', edges)
cv2.waitKey(0)
Then you can fit an ellipse as done in this answer.
you can divide the set of points into two halves (above the longest axis, under the longest axis), then you fit each of the two sets into a parabola, the algebraic solution of the two equations will be the intersection points.
here is an example with one of your images using basic thresholding and cropping, and ellipse fitting, the challenge in your case lies in better filtering noise to keep only the ellipse/curves.
#!/usr/bin/python3
import os
import numpy as np
import cv2
from skimage.measure import EllipseModel
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
im_id = 1
im_path = f"eliipse_fitting/{im_id}.jpg"
original = cv2.imread(im_path, cv2.IMREAD_GRAYSCALE)
img = original.copy()
width, height = img.shape
## Cropping to remove large objects
img = img[width//3:2*width//3, height//3: 2*height//3]
## Thresholding
th = 50
img[img>=th] = 255
img[img<th] = 0
## TODO: Add Noise Filtering, and Large Objects Removal
nonzero_indices = np.transpose(np.nonzero(img))
points = [(index[1], index[0]) for index in nonzero_indices]
a_points = np.array(points)
x = a_points[:, 0]
y = a_points[:, 1]
ell = EllipseModel()
ell.estimate(a_points)
xc, yc, a, b, theta = ell.params
print("center = ", (xc, yc))
print("angle of rotation = ", theta)
print("axes = ", (a,b))
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.imshow(original, cmap='gray')
x0 = xc+height//3
y0 = yc+width//3
plt.scatter(x0, y0, color='green', s=10)
ell_patch = Ellipse((x0, y0), 2*a, 2*b, theta*180/np.pi, edgecolor='green', facecolor='none')
ax.add_patch(ell_patch)
plt.show()