细化过程中不需要的分支

时间:2015-05-11 11:10:58

标签: matlab image-processing

我正在尝试编码以稀疏图像,并且在一定程度上我得到了输出。但最终输出仍然会产生一些来自不同领域的不必要的小线。我的下一步是寻找交叉点。由于这些小线,我得到的点实际上不是交点。如何改进我的代码以避免这些行。

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');

输入:

enter image description here

输出:

enter image description here

必需的img:

enter image description here

2 个答案:

答案 0 :(得分:2)

我的方法有三个关键步骤

  1. 识别线之间的交叉点。 bwmorph有一个branchpoint选项,但它不够激进。我使用conv2来计算邻近像素
  2. 使用bwconncomp
  3. 将像素分组为线段
  4. 使用阈值删除小线段,同时检查图像是否保持连接状态。
  5. 我使用了10像素的简单阈值。如果需要自适应阈值,可以使用相对于中值或平均线段长度的度量。选择阈值在很大程度上取决于数据集中的变化量。如果变化太多,您可能需要为每个图像进行人工交互。

    %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);
    

    输出图像与您想要的输出非常相似

    Output image

答案 1 :(得分:0)

当我使用手指静脉识别时,我的骨骼图像有类似的问题

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

会产生这样的结果

Orignal Skelton Image

After Applying this function