Reputation: 225
I was trying to code for thinning an image and to an extent I got an output. But still the final output does have some small unwanted lines emerging from different areas. My next step was to find intersection points. Because of these small lines, I get points which are actually not intersection points. How can I improve my code in order to avoid those lines.
I = imread('img.jpg');
I = rgb2gray(I);
I = uint8(255*mat2gray(I));
I=imresize(I,[128 128]);
I1=edge(I,'canny',0.6);
I2=edge(I,'canny',0.1);
I = imsubtract(I2,I1);
si = imdilate(I,strel('line',3,0));
se = imerode(I,strel('line',3,0));
I = imsubtract(si,se);
si = imdilate(I,strel('disk',1));
se = imerode(I,strel('disk',3));
I = imsubtract(si,se);
I = imfill(I,'holes');
[L num]=bwlabel(I); %%number of connected objects found in binary%%%
A=[];
for i=1:num
a=find(L==i);
A(i)=size(a,1);
end
[b indxA]=max(A);
L2(128,128)=0;
for i=1:num
if A(i)>=0.9*b
L2(find(L==i))=1;
end
end
I = imerode(L2,strel('disk',1));
I = bwmorph(I,'skel',Inf);
[i,j] = ind2sub(size(I),find(bwmorph(bwmorph(I,'thin',Inf),'branchpoint') == 1));
figure,imshow(I); hold on; plot(j,i,'rx');
Input:
Output:
Required img:
Upvotes: 1
Views: 1909
Reputation: 141
I had a similar problem with skeleton image when i was working with finger vein recognition
function [ unbrachImg ] = removingSmallBraches( image ,brnchsize)
%Removing Small Branches from skelton image and also removes small loops
% Detailed explanation goes here
% image=bwmorph(bwmorph(image,'dilate',1),'erode',1);
%
% image=bwmorph(bwmorph(image,'dilate',1),'skel','Inf');
Dmask=zeros(size(image));
B = bwmorph(image,'branchpoints');
D = bwdistgeodesic(image,find(B),'quasi');
Dmask(D < 2) =true;
skelD=image-Dmask;
img1=bwmorph(image,'spur',brnchsize);
Dmask=zeros(size(img1));
B = bwmorph(img1,'branchpoints');
D = bwdistgeodesic(img1,find(B),'quasi');
Dmask(D < 2) =true;
Dmask1=img1-Dmask;
brach=xor(img1,Dmask1);
unbrachImg=bwareaopen( skelD|brach|Dmask1,10);
unbrachImg=bwareaopen(unbrachImg,10);
end
It will result like that
Upvotes: 0
Reputation: 4721
My approach has three key steps
bwmorph
has a branchpoint
option, but it wasn't aggressive enough. I used conv2
to count neighboring pixels insteadbwconncomp
I've used a simple threshold of 10 pixels. If you want an adaptive threshold, you could use a metric relative to the length of the median or mean line segment. Choosing the threshold depends greatly on how much variation you have in your dataset. If there is too much variation, you might need human interaction for each image.
%Start off with your code above then do the following
%I got a better starting image with the 'thin' option than the 'skel' option
I = bwmorph(I,'thin',Inf);
%Alternative splitting method to 'branchpoint'
%Use convolution to identify points with more than 2 neighboring pixels
filter = [1 1 1;
1 0 1;
1 1 1];
I_disconnect = I & ~(I & conv2(double(I), filter, 'same')>2);
cc = bwconncomp(I_disconnect);
numPixels = cellfun(@numel,cc.PixelIdxList);
[sorted_px, ind] = sort(numPixels);
%Remove components shorter than threshold
threshold = 10;
for ii=ind(sorted_px<threshold)
cur_comp = cc.PixelIdxList{ii};
I(cur_comp) = 0;
%Before removing component, check whether image is still connected
full_cc = bwconncomp(I);
if full_cc.NumObjects>1
I(cur_comp) = 1;
end
end
%Clean up left over spurs
I = bwmoph(I, 'spur');
figure; imshow(I);
The output image is very similar to your desired output
Upvotes: 2