Search code examples
pythonopencvspline

Fit a spline on image


I'm trying to find a way to fit a spline on an image. I know that in the images to be processed there is a line that is:

  • somewhat horizontal
  • from left to right edge
  • not continuous

I cannot find a way to fit a spline there. This can be achieved with NI LabView, so it's hard to believe there wouldn't be a way also with OpenCV.

This is how far I have gotten:

import cv2
frame = cv2.imread("./download.png")
edged = cv2.Canny(frame, 50, 200)
cv2.imshow('frame', frame)
cv2.imshow('edge', edged)
cv2.waitKey()

Schematic image below describes what I have accomplished and what is the expected output (red manually drawn spline).

Example image from COCO


Solution

  • Turns out that fitting a spline is not possible with OpenCV, but I found a workaround with help from @triiiiista. For future reference (with the upper part of the original image for simplicity):

    import numpy as np
    import cv2
    from scipy.interpolate import interp1d
    import matplotlib.pyplot as plt
    
    frame = cv2.imread("./download.png")
    blur = cv2.blur(frame,(5,5))
    edged = cv2.Canny(blur, 50, 200)
    
    # remove vertical parts
    kernel_remove_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(3, 1))# remove vertical parts
    edged_hor = cv2.erode(edged, kernel_remove_vertical)
    cv2.imshow('edge', edged)
    cv2.imshow('edge_hor', edged_hor)
    cv2.waitKey(1)
    
    # Find coordinates for white pixels
    # Hope that there aren't too many outliers :)
    pixels = np.argwhere(edged_hor == 255)
    x = (pixels[:, 1])
    y = (pixels[:, 0])
    
    # Interpolate with scipy
    f = interp1d(x, y, kind='cubic')
    xnew = np.linspace(10, 630)
    
    plt.figure()
    plt.imshow(cv2.cvtColor(edged_hor, cv2.COLOR_BGR2RGB))
    plt.plot(xnew, f(xnew))
    

    This results in: enter image description here