【问题标题】:MATLAB: layer detection, vector combination and selection by tortuosity/arclengthMATLAB:层检测、向量组合和通过曲折度/弧长选择
【发布时间】:2016-04-14 05:39:07
【问题描述】:

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

首先,我应该在这里采用一些更好的策略来找到图像 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 vector


【解决方案1】:

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

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

【讨论】:

  • 这很好用,但我最终遇到了同样的问题,很多向量并且没有选择/组合的好方法。在您附加的图像中,绿线非常适合,但我尝试了其他图像并再次出现不连续性 - 需要连接多个连接组件/ROI以跨越整个距离。我尝试查看可能有助于组合的 regionprops(希望有类似的方向等)但没有运气
  • @user3470496 你能再发几张图片,包括最坏的情况吗?我将添加更多行来选择底部边缘。
  • 添加了更多图片
【解决方案2】:

我不确定这是否能直接回答您的问题,但我有很多经验将数组(或在我的情况下为矩阵)拟合到 3D 光栅图像。我们使用的是功率相对较低的机器(标准 i7 处理器 32 GB 内存),并且必须非常快速地执行拟合(

无论如何,我们使用的过程是 Matlab 内部的 fminsearch 函数。文档可以在这里找到:http://www.mathworks.com/help/optim/functionlist.html

我们将从一个普通的点云开始,并在每个像素的基础上执行连续的操作,以将点云调整为栅格。基本上遍历光栅中的每个像素以产生点云和光栅之间的最低偏移。

今天下午我将尝试搜索一些代码并更新我的答案,但我可能会针对您的情况探索此选项。我想您可以通过设置优化函数快速准确地将曲线拟合到某些像素(例如白色像素)。

如果我能更好地理解您的目标,我也可以提供更多帮助。您是否只是想在高反照率/白色区域设置一条线?

以示例的方式:我可以通过从标准点云、3D 栅格和最小化函数开始将 3D 点云拟合到下图(在这种情况下,只是 z 中每个单独点的 RMS 误差)轴)。在那里抛出一个 fmin 函数,在几秒钟内你会得到一个比标准更好的修改点云。

【讨论】:

  • 谢谢,我会研究 fminsearch 功能。我正在尝试将一条线拟合到底部高强度水平区域的底部。如果我能有一些合适的结构,从底部向上工作,并且具有确定的灵活性水平,这样就不会允许更大的波动/气泡......但我不知道如何去做,我'我还试图将总处理时间控制在 1 秒以下,我觉得这会超过那个时间。
  • 我不知道如何使用 fminsearch 来解决这个问题......它有点超出我的专业知识(尝试通读但仍然难以理解)。我是否应该在附加的第二张图片中为每个向量拟合一条曲线……然后以某种方式在这些向量上运行 fminsearch?
猜你喜欢
  • 2016-05-14
  • 1970-01-01
  • 2020-01-20
  • 2015-02-02
  • 1970-01-01
  • 2016-03-05
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多