如何将纯黑白图像转换为多边形集合?

时间:2012-10-31 09:31:14

标签: javascript image image-processing

我有一堆纯黑白图像,上面有各种文字和形状。我的目标是将每个图像转换为围绕黑色区域的一组多边形(定义为一组顶点)(就像魔术棒工具可以在照片编辑软件中选择区域一样)。

我更愿意在JavaScript中实现这一点,但我最感兴趣的是在概念上如何做到这一点。谢谢!

3 个答案:

答案 0 :(得分:1)

魔术棒在简单位图编辑器中的工作方式是:

让颜色C成为所选原始点的颜色。 让最后的颜色LC为任何颜色。

  1. 获取选定的点(x,y)
  2. 如果(x,y)的颜色= C且未访问像素
    1. 将坐标存储在数组
    2. 重复算法(x + 1,y),(x-1,y),(x,y + 1),(x,y-1)
  3. 将像素存储在受访像素数组中
  4. 如果(x,y)!的颜色= LC
    1. 将像素标记为数组中的边框像素
    2. 设置LC =(x,y)的颜色

答案 1 :(得分:1)

当只扫描周边时,可以制作“墙上的右手”算法。

步骤1:沿图像右侧移动,找到第一个相反颜色的像素 步骤2:按顺时针顺序搜索当前像素的所有相邻像素 第3步:移动到第一个可用像素。存储像素索引
步骤4:重复步骤2-3,直到当前像素是步骤​​1中的起始像素

步骤5:从存储的像素中检测图案,例如
运行LLLLLLLLLLL,[左]上,右或下,

表格模式

RRRRRRR U RRRRRRR U RRRRRRRR U RRRRRRR U ...
<-N--->   <--N-->   <--N+1->   <--N-->

可以用直线建模,虽然“反向bresenham”检测线段的最佳起点和终点并不容易。

无论如何,蛮力方法可用于从当前像素到N个先前像素绘制一条线,并测试bresenhams算法是否产生完全相同的像素。

答案 2 :(得分:0)

首先,让我解释一下“边缘”是什么。

边是两个连续像素之间的虚线。

+---+---+
| A | B |  // The middle line is the edge between pixel A and pixel B
+---+---+

边缘有起点和终点,因此朝上,向下,“向左”或“向右”。

为了处理跨越图像边界的多边形,我们将在图像周围添加1像素的白色边框。

以下是算法:

For each row of our image {  
  For each pixel of the row except the last one {  
    If current pixel is white and next pixel is black {
      Create a new upward edge between the two pixels and add it to
      the global edge list.
    }
    Else if current pixel is black and next pixel is white {
      Create a new downward edge between the two pixels and add it to
      the global edge list.
    }
  }  
}
For each column of our image {  
  For each pixel of the column except the last one {  
    If current pixel is white and next pixel is black {
      Create a new "left going" edge between the two pixels and add it to
      the global edge list.
    }
    Else if current pixel is black and next pixel is white {
      Create a new "right going" edge between the two pixels and add it to
      the global edge list.
    }
  }  
}  

For each edge of the global edge list {
  Find the edge starting from the point where your current edge ends
  (for now on, we gonna call it next_edge).
  Connect the two edges to form a linked list
  (edge->next = next_edge; next_edge->previous = edge;)
}

While there is edges in the global edge list {
  Create a new polygon and add it to the polygon list
  Take the first edge of the list (for now on, we gonna call it first_edge)
  For each edge in the linked list starting at first_edge {
     Remove edge from global edge list
     Add edge to polygon's edge list
  }
}

完成后,您有一个多边形列表。

修改

当然,在使用它之前你必须对它进行一些优化,但这很容易:具有相同方向的连续边可以用一个更长的边来代替。