Creating approximation line between objects.

Hello, I have image with a few objects I measured centroids of each one, now I want to create approximation line using centroids. Do you have any ideas how could I do that? Thank you in advance.

 Accepted Answer

Compute the centroids with regionprops(). Then pass those into polyfit(). Then use polyval() to get coordinates along the line.

4 Comments

Thank you for yor answer. I wrote a code but results are not so good. Could you look at this and give me some advice?
Here's my code:
clear all
close all
obraz_org = imread('image1.png');
obraz_bw = im2bw(obraz_org);
obraz_label = bwlabel(obraz_bw, 8);
bb = regionprops(obraz_label,'Centroid');
centroids = cat(1, bb.Centroid);
imshow(obraz_bw);
axis on;
hold on
[Y,I]=sort(centroids(:,2));
B=centroids(I,:);
x = B(:,1)
y = B(:,2)
plot(x, y, 'r+')
[p,~,mu] = polyfit(x, y, 1);
f = polyval(p,x,[],mu);
plot(x,f)
hold off
Final image:
Orginal image:
Note that polyfit is NOT the right tool for this fit. You need a code that can fit a line with errors in BOTH variables. If you choose to use the wrong tool (i.e., polyfit) then you WILL get a biased line. The slope will be wrong. Always.
My comment above should be a hint as to why polyfit gave the wrong slope. Again, polyfit is the WRONG tool here.
Look on the file exchange. There are lots of such tools. I would start with the keyword "orthogonal regression".
Be careful though, because not all orthogonal regressions were done at all well. (I just looked, and I found a fair amount of crap.) You need to use a tool that has SVD at its core. This one should suffice:
Marcin: you got confused when you did the fit as to which coordinate was the independent variable and which was the dependent variable. Fixed code is below:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
%===============================================================================
% Read in a gray scale demo image.
folder = pwd;
baseFileName = 'image1.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
% subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
axis image;
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
binaryImage = im2bw(grayImage);
labeledImage = bwlabel(binaryImage, 8);
props = regionprops(labeledImage, 'Centroid');
centroids = [props.Centroid];
xCenters = centroids(1:2:end);
yCenters = centroids(2:2:end);
hold on;
plot(xCenters, yCenters, 'r+', 'LineWidth', 2, 'MarkerSize', 20);
% Fit to a polynomial
coefficients = polyfit(yCenters, xCenters, 1);
% Get fit over all y (row) values.
rowFit = 1 : rows;
% Get an x value (columns value) for each row.
colFit = polyval(coefficients, rowFit);
% Plot it over the image.
plot(colFit, rowFit, 'm-', 'LineWidth', 2);
hold off
Thank you very much for your help

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!