How to represent the skeleton of a mask as an equation of a line?

3 views (last 30 days)
Dominik Mattioli on 4 Feb 2020
Edited: Dominik Mattioli on 4 Feb 2020
My masks are assumed to always take the following shape, and I need to represent them with minimum information (x_start, x_end, and an equation for all points in between). The only variance in the shape of these masks are that they can be 2-4 times thicker, and the curvature at the top can be more pronounced (top). For "short" masks - where the length of the object is shorter - I can simply use 'fitlm'. For "longer" masks, fitting a fourier series to the mask's skeleton works reasonably well. For masks like this, though, I can't get an accurate representation (bottom). I'm thinking that polar coordinates would be an easy fix?  How can I get a more thorough representation of this object? Here is the code for fitting a fourier series.
[y, x] = find( bwmorph( BW, 'thin', Inf ) )
B = horzcat( x, y );
fittedFunc = fit( B( :, 1 ), B( :, 2 ), 'fourier1' ); % Only gets worse with higher degrees.
% Create a function handle from the fit.
fx = strcat( '@(x)', formula( fittedFunc ) );
names = coeffnames( fittedFunc );
values = coeffvalues( fittedFunc );
for idx = 1:length( names )
fx = strrep( fx, names( idx ), num2str( values( idx ) ) );
end
fs = '';
for idx = 1:length( fx{ 1 } )
if ~isstrprop( fx{ 1 }( idx ), 'wspace' )
fs = strcat( fs, fx{ 1 }( idx ) );
end
end
end
eq = str2func( fs );
% Testing
[~, xBW] = find( BW );
xplot = linspace( min( xBW ), max( xBW ), 1000 );
yplot = eq( xplot );
figure; imshow( BW ); hold on; plot( xplot, yplot, 'r.-' );
Dominik Mattioli on 4 Feb 2020
Primarily because there are context-dependent properties of the object that I use for a more complex analysis involving other objects, and ultimately those properties and analysis are derived from the minimum information of those objects as they relate to one other. I can go into great detail, if you'd like, but I figured it was not relevant to the question.