我有一个二层图像,有几个层 - 通常是对角线和不同宽度,我试图找到底层。换句话说,我不能依赖于图层,质心等的最小Y值。
我认为解决方案应该与查看多个层交叉的特定Y值,并选择该值的底层有关。不知道如何编码 - (特别是不确定如何找到它y值)...也许这是一个更聪明的方法吗?
所以在附图中:这将以二进制开始,蓝色和绿色线都是白色。我在二进制文件上运行bwconncomps()。绿线是我想要识别的。红线是我想象我可以检查底层的地方 - 但我如何找到这个位置?
答案 0 :(得分:2)
执行此操作的一种方法是在图片的每一列中找到最后一个1
。然后,在您运行bwconncomp
之后,您可以查看给定组件在每列中包含最后1
的次数。
我们可以将其分解为以下步骤。
标识包含每列中最后一个1
的行。有许多不同的方法可以做到这一点,但一种方法是采用累积总和({{ 1}})沿第一个维度找到每列中最大值的行(使用cumsum
)。这将告诉我们每行包含最后max
的行。
举个例子:
1
识别所有已连接的组件。这个很简单,因为我们可以使用data = [1 0 0;
0 0 1;
1 1 0];
C = cumsum(data, 1);
% 1 0 0
% 1 0 1
% 2 1 1
[~, rows] = max(C, [], 1);
% 3 3 2
来获取连接的组件。
确定每个连接组件的成员数是其各自列中的最后一个bwconncomp
。我们可以将我们在步骤1中找到的1
转换为他们的线性索引使用rows
。然后,我们可以遍历所有连接的组件,并使用sub2ind
和ismember
来确定在给定的连接组件中发生了多少这些值(使用sum
确定)。
使用行中最后一个PixelIdxList
像素最多的组件作为“最远距离”组件。我们可以再次在步骤3的输出上使用1
来确定这一点。
因此,如果我们为您的数据写出全部内容,它将类似于以下内容(忽略前两行,因为只需要从您在帖子中提供的图像创建二进制图像)。
max
并将该组件显示为概念证明
% Load the image and convert to binary image
img = imread('http://i.stack.imgur.com/flpoC.jpg');
img = img(:,:,2) > 50 | img(:,:,3) > 50;
% Determine the row which contains the last 1 in each column
C = cumsum(img, 1);
[~, rows] = max(C, [], 1);
% Now convert these rows indices to linear indices
% (the ones that will appear in PixelIdxList)
inds = sub2ind(size(img), rows, 1:size(C, 1));
% Get connected components of the image
CC = bwconncomp(img);
% Determine the number of pixels in each component that were at the bottom
numAtBottom = cellfun(@(x)sum(ismember(inds, x)), CC.PixelIdxList);
% The one that has the most was the largest bottom-most component
[~, bottomComponent] = max(numAtBottom);