Search code examples
matlabimage-processinglinecentroid

Draw line to connect centroids


I have an image

enter image description here.

After I process to find centroid, it has four centroids. My goal is I want to connect them using line and measure the angle between this area. To be clear about the centroid and my goal, you can open enter image description here.

Here it is my code to achieve the centroid

I = imread('22c.jpg');
Ibw = im2bw(I);
Ibw = imfill(Ibw,'holes');

Ilabel = bwlabel(Ibw);
stat = regionprops(Ilabel,'centroid');
imshow(I); hold on;
for x = 1: numel(stat)
    plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro');
end

The problem is I am still confused to do the next (to connect each centroids and measure the angle). I need your help, thanks


Solution

  • Here is a file exchange link to bresenham.m

    Changed your code to get all the 4 centroids

    %// read your input image
    im = imread('https://i.sstatic.net/xeqe8.jpg');
    
    BW = im>220;
    
    CC = bwconncomp(BW);
    stat = regionprops(CC,'Centroid');
    
    figure; imshow(BW); hold on
    for x = 1: numel(stat)
        plot(stat(x).Centroid(1),stat(x).Centroid(2),'ro');
    end
    

    Here is the output:

    enter image description here

    Further implementation:

    %// putting all the Centroid coordinates into corresponding x,y variable
    x = [stat(1).Centroid(1),stat(2).Centroid(1),stat(3).Centroid(1),stat(4).Centroid(1)];
    y = [stat(1).Centroid(2),stat(2).Centroid(2),stat(3).Centroid(2),stat(4).Centroid(2)];
    
    %// obtain row and col dim
    [r,c] = size(BW);
    
    %// get all x,y values connecting the centroid points
    [xAll{1},yAll{1}] = bresenham(x(1),y(1),x(4),y(4));
    [xAll{2},yAll{2}] = bresenham(x(2),y(2),x(3),y(3));
    [xAll{3},yAll{3}] = bresenham(x(3),y(3),x(4),y(4));
    
    %// change row and col subs to linear index
    for ii = 1:3
        idx{ii} = sub2ind(size(BW),yAll{ii},xAll{ii});
    end
    
    %// change grayscale image to 3D (as you want red line)
    out = repmat(im,[1,1,3]);
    
    %// obtaining corresponding index of all 3 slices
    for ii = 1:3
        idxall{ii} = bsxfun(@plus, idx{ii},[0:2].*(r*c));
    end
    
    %// keep only the index of 1st slice to 255 and changing rest to 0 to obtain a red line.
    %// Similar process for blue line except keep the index in the 3rd slice to 255
    out(cat(1,idxall{:})) = 0;
    out(idx{1}) = 255;
    out(idx{2}) = 255;
    out(idx{3}+2*(r*c)) = 255;
    
    %// see what you have obtained
    figure; imshow(out);hold on
    for x = 1: numel(stat)
        plot(stat(x).Centroid(1),stat(x).Centroid(2),'bo');
    end
    

    Result:

    Note: The line may look dotted due to the picture's large size, but its continuous

    enter image description here

    Last figure zoomed to see continuous line:

    enter image description here

    Going further:

    You may have to take the advice of @Spektre to find the angle of inclination using atan2. Also refer his answer for more explanation.