imagematlablinemaxima

How to connect the disconnected-points in image with Matlab?


This is a more specific problem with complex settings. I have calculated the distance of all 1-pixels to its nearest 0-pixels of raw image and transformed to an image with local maxima shown as below:

enter image description here

I used the following code to extract the local maxima from this transformed matrix:

loc_max = imregionalmax(loc,4);
figure;imshow(loc_max)

The loc_max gives out disconnected dots of those local maxima points. Tried a bunch of ways to connect them, but not working as it was supposed to do yet.

Here is one of my ideas:

[yy xx]=find(loc_max ==1);
d = [];
dmin = [];
idx = [];
for i = 1: size(yy,1)
    for j = 1:size(xx,1)
        if i ~= j
            d(j) = sqrt(sum(bsxfun(@minus,[yy(j) xx(j)],[yy(i) xx(i)]).^2,2));
            %calculate the distance between current 1-pixel in loc_max and all other local maxima pixels in loc_max.
        end        
    end    
    [dmin(i),idx(i)] = min(d(:));%find the minimum distance between current 1-pixel to others
end

I tried to find the nearest 1-pixels in loc_max to the current 1-pixel in loc_max, and then connect them. But this isn't the solution yet. Because it won't connect to its next 1-pixel if the previous pixel is the nearest pixel of the current one.

In addition, I want to preserve the pixel information of those 0-pixels along the connected line between two disconnected 1-pixels. I want to be able to reconstruct the whole image out of this simplified skeleton later.

Any help would be greatly appreciated!


Solution

  • I have tried erode and dilate (like Ander Biguri advised).
    I tried setting the angles of the kernels to be correct.

    Check the following:

    %Fix the input (remove JPEG artifacts and remove while margins)
    %(This is not part of the solution - just a little cleanup).
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    I = imread('https://i.sstatic.net/4L3fP.jpg'); %Read image from imgur.
    I = im2bw(I);
    [y0, x0] = find(I == 0);
    [y1, x1] = find(I == 0, 1, 'last');
    I = I(y0:y1, x0:x1);
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    se0 = strel('disk', 3);
    J = imdilate(I, se0); %Dilate - make line fat
    
    se1 = strel('line', 30, 150); %150 degrees.
    se2 = imdilate(se1.getnhood , se0); %Create 150 degrees fat line
    J = imclose(J, se2); %Close - (dilate and erode)
    
    se1 = strel('line', 30, 140); %140 degrees.
    se2 = imdilate(se1.getnhood , se0);
    J = imclose(J, se2);
    
    se1 = strel('line', 80, 60); %60 degrees.
    se2 = imdilate(se1.getnhood , se0); %Create 60 degrees fat line
    J = imclose(J, se2);
    
    se4 = strel('disk', 2);
    J = imerode(J, se4); %Erode - make lines little thinner.
    
    figure;imshow(J);
    

    Result:

    enter image description here

    Do you think it's good enough?


    Ander Biguri gets the credit for the following solution:

    J = bwmorph(J,'skel',Inf);
    

    enter image description here