image - MATLAB:层检测,矢量组合和曲折/弧长选择

标签 image matlab vector

我有一张类似于下图的灰度图像,是我在经过一些后处理步骤后获得的(图像 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);

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

最佳答案

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

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

picture 1

picture 2

picture 3

picture 4

picture 5

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

相关文章:

html - 图像溢出边界

javascript - IE9上加载图片后的事件

matlab - 仅搜索矩阵的第一个(一对)特征值和特征向量 - MATLAB

matlab - @文件夹和+文件夹

R - 简洁地将向量添加到每个向量元素

c++ - 如何为 std::vector/std::string 保留空间?

android - 图像太大会导致应用程序返回到以前的 Activity 吗?

java - 如何在java中围绕特定点而不是图像中心旋转图像?

file - 从脚本中读取 TDM (Diadem) 文件

c++ - 将字符串添加到 vector<string> 循环时内存损坏