使用matlab

时间:2017-08-30 11:47:22

标签: image matlab image-processing computer-vision

我有一个分段图像,如enter image description here

所示

我想在分割图像的顶部像素上拟合一条曲线(显示为红色曲线),我想找到沿曲线显示的顶点蓝色。enter image description here我已经研究过基本的想法比如穿过顶部到底部并沿每列收集顶点。我想知道是否有任何简单的解决方案,例如直接取出边界像素并找到最高点。我正在使用MATLAB来解决这个问题

2 个答案:

答案 0 :(得分:4)

%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

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

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或convexhull并找到边界向下的位置

答案 1 :(得分:1)

至于#34;最简单的matlab解决方案"我认为你的意思是内置matlab函数:imclose() - > edge() - > bwboundaries() - > findpeaks()'在每个边界上' - >'过滤器基于峰值宽度和幅度的结果' *你需要调整这些函数中的所有参数,我只是列出了如果适当应用会让你到那里的东西。

就处理速度而言,我认为我会完全按照您的方式完成,基本上从上到下的列搜索中收集上边缘,然后寻找最高拐点。一旦你开始处理任何类型的处理,你就开始对每个像素进行多次操作,这将比你的初始搜索更快地成本(只需要你的图像和目标足够简单)

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

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

2:如果您知道您的兴趣点不在图片(边界)的左侧或右侧,您可以采用右边缘和左边缘点并计算要应用的偏斜以平整整个图像。

3:如果你的图像总是在这里看到的峰下方有一个很大的暗线性区域,你可以找到那些用houghlines寻找垂直的边,然后只搜索它们之间的列。

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