MATLAB:找到二进制的底部对角线层

MATLAB: finding the bottom diagonal layer in binary

我有一个包含多个层的二值图像 - 通常是对角线的并且具有不同的宽度,我正在尝试找到底层。换句话说,我不能依赖图层、质心等的最小 Y 值。

我认为解决方案应该与查看多个层交叉的特定 Y 值有关,然后选择该值的底层.. 不确定如何对此进行编码-(特别是不确定如何找到那个 y 值)...也许还有更聪明的方法来做到这一点?

因此在所附图片中:这将以二进制形式开始,蓝线和绿线均为白色。我 运行 bwconncomps() 在二进制文件上。绿线是我想识别的那条。红线是我想我可以检查底层的地方——但我如何找到这个位置?

一种方法是在图像的每一列中找到最后一个 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
    
  2. 识别所有连通分量。这个很简单,因为我们可以只使用 bwconncomp 来获取连通分量。

  3. 判断每个连通分量有多少个成员在各自列的最后1我们可以转换rows我们在步骤 1 中使用 sub2ind 找到了它们的线性索引。然后我们可以遍历所有连接的组件并使用 ismembersum 来确定这些值中有多少出现在给定的连接组件中(使用 PixelIdxList 确定)。

  4. 使用其行中最后 1 像素最多的组件作为 "most distance" 组件。我们可以再次对步骤 3 的输出使用 max 来确定这一点。

综合起来

因此,如果我们为您的数据写出所有内容,它看起来将类似于以下内容(忽略前两行,因为只需要它们来根据您在 [=71= 中提供的图像创建二进制图像]).

% 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);

并显示该组件作为概念证明

% Just to show this, we will create a binary image of JUST that component
I = img;
I(CC.PixelIdxList{bottomComponent}) = 2;

figure, imagesc(I)