我有一个类似于下面的灰度图像,这是我在一些后处理步骤后获得的(图像 0001)。我想要一个对应于下部亮条底部​​的向量(如图像 0001b 所示)。我可以使用具有各种阈值的 im2bw 来实现图像 0002 中的矢量(阈值越高,矢量线向上的趋势越高,阈值越低,线向下的趋势越高)..和然后我正在考虑遍历每个向量并在某个增量(可能是 100 像素左右)上测量弧长并选择具有最低弧长的向量……并将 100 像素拉伸(stretch)添加到最终向量中,创建一个类似弗兰肯斯坦的向量使用每个阈值向量中最直的段。我还应该提到,当有多个直/平行向量时,最上面的一个是最合适的。

首先,我应该在这里采用一些更好的策略来找到图像 0001 上的那条线吗? (这需要很快,所以一些长拟合代码将不起作用)。如果我目前的弗兰肯斯坦怪物解决方案有效,关于如何最好地解决这个问题有什么建议吗?

提前致谢

image=im2bw(image,0.95); %or 0.85, 0.75, 0.65, 0.55
vec=[];
for v=1:x
    for x=1:z
        if image(c,v)==1
            vec(v)=c;
        end
    end
end
vec=fastsmooth(vec,60,20,1);

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

最佳答案

这是我最初所做的修改版本。它适用于您的图像。如果你想要亚像素分辨率,你可以使用一些拟合函数来实现一个事件轮廓模型。

files = dir('*.png');
filenames = {files.name};
for ifile=1:length(filenames)
    %%
    % read image
    im0 = double(imread(filenames{ifile}));
    %%
    % remove background by substracting a convolution with a mask
    lobj=100;
    convmask = ones(lobj,1)/lobj;
    im=im0-conv2(im0,convmask,'same');
    im(im<0)=0;
    imagesc(im);colormap gray;axis image;

    %%
    % use canny edge filter, alowing extremely weak edge to exist
    bw=edge(im,'canny',[0.01,0.3]);
    % use close operation on image to close gaps between lines
    % the kernel is a flat rectangular so that it helps to connect horizontal
    % gaps
    se=strel('rectangle',[10,30]);
    bw=imdilate(bw,se);
    % thin the lines to be single pixel line
    bw=bwmorph(bw,'thin',inf);
    % connect H bridge
    bw=bwmorph(bw,'bridge');
    imagesc(bw);colormap gray;axis image;
    %% smooth the image, find the decreasing region, and apply the mask
    imtmp = imgaussfilt(im0,3);
    imtmp = diff(imtmp);
    imtmp = [imtmp(1,:);imtmp];
    intensity_decrease_mask = imtmp < 0;
    bw = bw & intensity_decrease_mask;
    imagesc(bw);colormap gray;axis image;

    %%
    % find properties of the lines, and find the longest lines
    cc=regionprops(bw,'Area','PixelList','Centroid','MajorAxisLength','PixelIdxList');
    % now select any lines that is larger than eighth of the image width
    cc=cc([cc.MajorAxisLength]>size(bw,2)/8);
    %%
    % select lines that has average intensity larger than gray level
    for i=1:length(cc)
        cc(i).meanIntensity = mean(im0(sub2ind(size(im0),cc(i).PixelList(:,2), ...
        cc(i).PixelList(:,1) )));
    end
    cc=cc([cc.meanIntensity]>150);
    cnts=reshape([cc.Centroid],2,length(cc))';
    %%
    % calculate the minimum distance to the bottom right of each edge
    for i=1:length(cc)
        cc(i).distance2bottomright = sqrt(min((cc(i).PixelList(:,2)-size(im,1)).^2 ...
            + (cc(i).PixelList(:,1)-size(im,2)).^2));
    end
    % select the bottom edge
    [~,minindex]=min([cc.distance2bottomright]);
    bottomedge = cc(minindex);
    %% clean up the lines a little bit
    bwtmp = false(size(bw));
    bwtmp(bottomedge.PixelIdxList)=1;
    % find the end points to the most left and right
    endpoints = bwmorph(bwtmp, 'endpoints');
    [endy,endx] = find(endpoints);
    [~,minind]=min(endx);
    [~,maxind]=max(endx);
    pos_most_left = [endx(minind),endy(minind)];
    pos_most_right = [endx(maxind),endy(maxind)];
    % select the shortest path between left and right
    dists = bwdistgeodesic(bwtmp,pos_most_left(1),pos_most_left(2)) + ...
         bwdistgeodesic(bwtmp,pos_most_right(1),pos_most_right(2));
    dists(isnan(dists))=inf;
    bwtmp = imregionalmin(dists);
   bottomedge=regionprops(bwtmp,'PixelList');
    %% plot the lines
    imagesc(im0);colormap gray;axis image;hold on;axis off;
    for i=1:length(cc)
        plot(cc(i).PixelList(:,1),cc(i).PixelList(:,2),'b','linewidth',2);hold on;
    end
    plot(bottomedge.PixelList(:,1),bottomedge.PixelList(:,2),'r','linewidth',2);hold on;
    print(gcf,num2str(ifile),'-djpeg');
%     pause
end

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择-LMLPHP

关于image - MATLAB:通过曲折度/弧长进行层检测、矢量组合和选择,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36360749/

10-11 21:13