Suppose I have a binary image as shown below. The white colour indicates the shape of interest.
Task: I want to fit two connected line segment that best describes the shape. Example output is shown below.
Constraints: We can assume that the start, mid and end points are all part of the white shape and are integers.
What I have tried so far: I tried scipy.optimize.minimize but it seems to be stuck in a local minimum and I cannot constrain the search space to be an integer and be one of the white coordinates. I also tried basinhopping which seems to give good results but it takes forever to run and I don't know how to constrain the solution as per above.
import scipy.optimize as spo
def fit_skeleton(start_point, mid_point, end_point, data_points):
"""
:param start_point: np.array,
an array of shape (1,2) representing the x,y coordinates of the start point.
:param mid_point: np.array,
an array of shape (1,2) representing the x,y coordinates of the start point.
:param end_point: np.array,
an array of shape (1,2) representing the x,y coordinates of the start point.
:param data_points: np.array,
an array of shape (n,2) representing the list of x,y coordinates of the pixels of the shape in the image.
:return:
"""
start_point_x, start_point_y = start_point
mid_point_x, mid_point_y = mid_point
end_point_x, end_point_y = end_point
result = spo.basinhopping(objective_function,
x0=[start_point_x, start_point_y, mid_point_x, mid_point_y, end_point_x, end_point_y],
minimizer_kwargs={"args": (data_points,)},
stepsize=1,
accept_test=mybounds
)
start_point_x, start_point_y, mid_point_x, mid_point_y, end_point_x, end_point_y = result.x
The objective function simply measures the distance the shape's pixels from the closest line segment and sums these. The objective function is fine. I just want to know if there is a simple and quick approach that can find the two line segments that best fit the shape given the constraints.