【问题标题】:Draw a curve in the segmented image using matlab使用matlab在分割图像中绘制曲线
【发布时间】:2018-02-08 02:52:12
【问题描述】:

我有一个分段图像,如下所示

我想沿着分割图像的顶部像素拟合一条曲线(显示为红色曲线),我想找到沿曲线显示为蓝色的顶点。我已经研究过像遍历这样的基本想法从上到下并沿每列收集顶点。我想知道这个问题有没有简单的解决方案,比如直接取出边界像素并找到顶点。我正在使用 MATLAB 来解决这个问题

【问题讨论】:

    标签: image matlab image-processing computer-vision


    【解决方案1】:
    %download the image
    img = logical(imread('http://i.stack.imgur.com/or2iX.png'));
    %for some reason it appeared RGB with big solid borders.
    %to monochrome
    img = img(:,:,1);
    %remove borders
    img = img(~all(img,2), ~all(img,1));
    %split into columns
    cimg = num2cell(img,1);
    %find first nonzero element per column
    ridx = cellfun(@(x) find(x,1,'first'), cimg);
    figure, imshow(img)
    hold on
    %image dim1 is Y, dim2 is X
    plot(1:size(img,2),ridx-1,'r','linewidth',2)
    %find top point
    [yval, xval] = min(ridx);
    

    如果你想要更平滑的曲线,试试 polyfit/polyval

    @编辑 如果我们希望线在连接组件之间的间隙处中断,我们应该将代码更改为类似

    bord_idx = sub2ind(size(img), ridx, 1:size(img,2));
    regs=regionprops(bwlabel(img),'pixelidxlist');
    regs_idx = struct2cell(regs);
    split_step = cellfun(@(x) sum(ismember(bord_idx,x)), regs_idx);
    split_step = split_step(split_step>0);
    split_yvals = mat2cell(ridx',split_val);
    split_xvals = mat2cell([1:size(img,2)]',split_val);
    figure, imshow(img)
    hold on
    for k = 1:length(split_step),
     plot(split_xvals{k}, split_yvals{k}, 'r', 'linewidth', 2),
    end
    

    但是,如果一个区域位于另一个区域之上,则结果并不理想。如果需要“阴影”点,您应该尝试 bwtraceboundary 或凸包并找到边界向下的位置

    【讨论】:

    • 感谢您的回复..虽然还有一件事我忘记提及了。如果两者之间没有点,我不想在两点之间进行插值怎么办。更新了图片
    • 是否将 plotstile 更改为 plot(1:size(img,2),ridx-1,'rs','markerfacecolor','r') 是否足够?如果没有,则需要完全不同的方法,我会休息一下并发布新的回复。
    • 再推荐一个,但仍然不是完美的解决方法
    【解决方案2】:

    至于“最简单的 matlab 解决方案”,我认为您的意思是内置 matlab 函数:imclose()->edge()->bwboundaries()->findpeaks()'在每个边界上'->'过滤结果基于峰的宽度和幅度”。 *您将需要调整这些函数中的所有参数,我只是列出了如果应用得当,您将获得什么。

    就处理速度而言,我想我会完全按照您的做法进行,基本上是从自上而下的列搜索中收集顶部边缘,然后寻找最高拐点。一旦您开始进行任何类型的处理,您就会开始对每个像素进行多个操作,这将很快变得比您的初始搜索更昂贵(只需要您的图像和目标足够简单)

    话虽如此,这里有一些想法可能会有所帮助:

    1:如果您运行足够重的关闭(扩张->侵蚀),那应该会填满底部的所有垃圾。

    2:如果您知道您的兴趣点不在图片的左侧或右侧(边界),您可以获取右侧和左侧边缘点并计算斜率作为偏移量,以使整个图像变平。

    3:如果您的图像始终在峰值下方有较大的深色线性区域,如此处所示,您可以通过寻找垂直线的轮廓线定位这些边缘,然后仅搜索它们之间的列。

    4:如果速度是一个问题,你可以做一个比从左到右更复杂的搜索模式,因为你的峰值在它周围有一个很好的分布,这有助于更快地定位最大值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-15
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多