MATLAB:以二进制形式查找底部对角线层

时间:2016-06-05 23:37:36

标签: matlab image-processing binary selection layer

我有一个二层图像,有几个层 - 通常是对角线和不同宽度,我试图找到底层。换句话说,我不能依赖于图层,质心等的最小Y值。

我认为解决方案应该与查看多个层交叉的特定Y值,并选择该值的底层有关。不知道如何编码 - (特别是不确定如何找到它y值)...也许这是一个更聪明的方法吗?

所以在附图中:这将以二进制开始,蓝色和绿色线都是白色。我在二进制文件上运行bwconncomps()。绿线是我想要识别的。红线是我想象我可以检查底层的地方 - 但我如何找到这个位置?

enter image description here

1 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是在图片的每一列中找到最后一个1。然后,在您运行bwconncomp之后,您可以查看给定组件在每列中包含最后1的次数。

我们可以将其分解为以下步骤。

  1. 标识包含每列中最后一个1的行。有许多不同的方法可以做到这一点,但一种方法是采用累积总和({{ 1}})沿第一个维度找到每列中最大值的行(使用cumsum)。这将告诉我们每行包含最后max的行。

    举个例子:

    1
  2. 识别所有已连接的组件。这个很简单,因为我们可以使用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 来获取连接的组件。

  3. 确定每个连接组件的成员数是其各自列中的最后一个bwconncomp我们可以将我们在步骤1中找到的1转换为他们的线性索引使用rows。然后,我们可以遍历所有连接的组件,并使用sub2indismember来确定在给定的连接组件中发生了多少这些值(使用sum确定)。

  4. 使用行中最后一个PixelIdxList像素最多的组件作为“最远距离”组件。我们可以再次在步骤3的输出上使用1来确定这一点。

  5. 全部放在一起

    因此,如果我们为您的数据写出全部内容,它将类似于以下内容(忽略前两行,因为只需要从您在帖子中提供的图像创建二进制图像)。

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

    enter image description here