改进算法以定位由 0 和 1 的二维矩阵表示的对象的极值

问题描述

注意:这里不是在寻找代码,只是一个算法,因为我不是在为这个问题实施解决方案,而是在找出解决方案是什么。

我有一个大的二维数组,它是从一个由零和一组成的图像创建的;那些代表黑色像素,反之亦然。背景为白色,图片包含许多形状不规则的黑色物体。我已经写了代码来检测这些对象的边缘,所以假设这个二维数组只包含这些对象的边缘,因为处理步骤已经完成

我正在尝试创建一种算法,能够为这些对象中的每一个找到四个极值:最高的 y、最低的 y、最大的 x 和最低的 x。

我现在最好的伪代码是这样的:

Initialize array = aforementioned array
Initialize temporary_coord_store=[]
Initialize coordinates=where value in array equals one
Initialize extrema=[]

Define coordinate_recurs(coordinates):
     Initialize x = first value in coordinates
     append x to temporary_coord_store
     loop while the following if statement evaluates true:
          if the value in array at an index equal to any neighbors of any coordinate in coordinates equals 1:
               append all neighbors to temporary_coord_store
     append to extrema the extreme x and y values in temporary coordinate store
     set all values in array at indexes equal to any values in temporary coordinate store=zero
     set coordinates=where value in array equals one
     if any value in coordinates equals one:
          call method coordinate_recurs(coordinates)

call method coordinate_recurs(coordinates)

但是我觉得必须有一个可以设计的更有效和算法,因为这基本上查看所有非白色数组值。有没有人看到我可以用这个伪代码节省一些时间的地方?如果这是在错误的堆栈交换频道中发布的,请道歉;如果是,请告诉我,以便我可以将其重新发布到正确的位置。

解决方法

您可以调整标准的 Connected-Component Labeling 算法,并在访问邻居时考虑在适当的方向上扩展当前的极值。例如,如果您在东边找到当前单元格的邻居,那么您只需考虑增加最大 x 值。

为了简化事情,我假设您的边界是 4-connected。我也忽略了确定邻居是否有效的问题,即在图像内。

image[][]   // array containing 0|1
visited[][] // boolean
queue[]     // struct to hold coordinates to be processed
extrema[]   // array of object extrema
id = 0      // current object id

for y = 0 to image.height-1
  for x = 0 to image.width-1
    if image[x][y] == 1 and visited[x][y] == false
      // new object/component
      id = id + 1
      extrema[id] = (x,y)
      queue.add(x,y)
      visited[x][y] = true
      while queue not empty
        p = queue.remove()
        // Check East
        if image[x+1][y] == 1 and visited[x+1][y] == false
          queue.add(p.x+1,p.y)
          visited[p.x+1][p.y] = true
          if x+1 > extrema[id].maxX 
            extrema[id].maxX = x+1
        // Consider North,South,West...