I am using cv2 to compute the line withing the object present in the mask image attached. The orientation/shape of the object might vary (horizontal, vertical, horizontal curved or vertical curved objects) from mask images in my dataset.
I had been suggest by @Tino D, a PCA based approach to compute the points. It worked initially for the image in question but failed to bend the line (to be drawn end to end withing an object) as orientation of an object in mask image is not always straight. it would be helpful if anyone can suggest an much flexible approach so that line is always following the orientation.
[Example raw mask image where object is not straight](https://i.sstatic.net/LhIr7R8d.png)
[here’s how line was computed](https://i.sstatic.net/JpSaIxO2.png)
[here is what I want](https://i.sstatic.net/nSVD28xP.png)
%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import cv2
im = cv2.imread("mask.png", 0) # read as gray
y, x = np.where(im) # get non-zero elements
centroid = np.mean(x), np.mean(y) # get the centroid of the particle
x_diff = x - centroid[0] # center x
y_diff = y - centroid[1] # center y
cov_matrix = np.cov(x_diff, y_diff) # get the convariance
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # apply EVD
indicesForSorting = np.argsort(eigenvalues)[::-1] # sort to get the primary first
eigenvalues = eigenvalues[indicesForSorting]
eigenvectors = eigenvectors[:, indicesForSorting]
plt.figure()
plt.imshow(im, cmap = "gray") # plot image
vecPrimary = eigenvectors[:, 0] * np.sqrt(eigenvalues[0])
plt.plot([centroid[0] - vecPrimary[0], centroid[0] + vecPrimary[0]],
[centroid[1] - vecPrimary[1], centroid[1] + vecPrimary[1]])
vecSecondary = eigenvectors[:, 1] * np.sqrt(eigenvalues[1])
plt.plot([centroid[0] - vecSecondary[0], centroid[0] + vecSecondary[0]],
[centroid[1] - vecSecondary[1], centroid[1] + vecSecondary[1]])