【问题标题】:Get pixel boundary coordinates from binary image in Python (not edges)从 Python 中的二进制图像获取像素边界坐标(不是边缘)
【发布时间】:2020-07-23 17:45:58
【问题描述】:

我有一个包含单个连续斑点的二进制图像,没有孔。我想根据边缘像素的外部边缘创建一个多边形对象。我知道如何自己获取边缘像素,但我想要像素边界的实际坐标,顺时针或逆时针排序。所有像素都有整数坐标。

例如,假设我在 (2,2) 处有一个像素。多边形的顶点将是: (2.5, 2.5) (2.5, 1.5) (1.5, 1.5) (1.5, 2.5) (2.5, 2.5)

有没有一种精确的、非近似的方法来做到这一点?最好在 Python 中?

【问题讨论】:

  • 每个坐标加/减 0.5,“装箱”2x2 组合。你在哪里纠结这个?
  • 您是说,将所有像素上所有角的出现次数相加,并保留奇数的那些?这很优雅。那么我如何订购剩余的顶点?我不确定这些组合是什么意思。
  • 不,我在您的描述中漏掉了一句话。在线多处解决时钟顺序排序点;在你的研究中寻找“形状”算法。这些还将为您提供查找边界框(琐碎)、凸容器的点或边缘或两者之一的例程和步骤。
  • 我今天遇到了同样的问题。我没有答案,但假设您已经知道如何按顺序获取周边像素(我使用 opencv 的 findContours),让 closer 靠近边界的一种方法是在更高的分辨率。不幸的是,这可能很昂贵,而且它不会让你到达原始像素的边缘,所以这不是一个好主意。但这是我能立即想到的唯一一个。
  • 另一个帮助确定应该在最终多边形中的像素角集的提示:连接像素中心(再次假设您知道如何获取周长),然后删除所有像素角坐标在像素中心多边形内。

标签: python image image-processing polygon scikit-image


【解决方案1】:

查看示例:

from PIL import Image, ImageFilter, ImageChops
import math

a = [['.','.','.','.','.','.','.'],
      ['.','.','.','.','.','.','.'],
      ['.','.','.','.','.','.','.'],
      ['.','#','#','#','.','.','.'],
      ['.','#','#','#','.','.','.'],
      ['.','.','.','.','.','.','.']]      

sz=(len(a[0]), len(a))
flat_list = [j=='.' for i in a for j in i]
image=Image.new('1', sz)
image.putdata(flat_list)
contour=ImageChops.difference(image, image.filter(ImageFilter.MinFilter(3)))
contour_list=list(contour.getdata())
points=[divmod(i,sz[0]) for i in range(len(contour_list)) if contour_list[i]]
points_x,points_y=zip(*points)
avg=lambda x: sum(x)/len(x)
mean_x=avg(points_x)
mean_y=avg(points_y)
phase=[(math.atan2(points_y[i]-mean_y, points_x[i]-mean_x),i) \
       for i in range(len(points))] 
phase.sort()
for i in range(len(points)):
    print(*points[phase[i][1]])

【讨论】:

  • 感谢您的示例,但此代码会找到与“#”相邻的像素。我想要将“#”与边框分开的轮廓坐标,其中的值应为 0.5。
【解决方案2】:

基于 cmets,这是我实施的方法:

  1. 将所有像素坐标乘以 10,这样我们将只处理整数。

  2. 对于每个像素,通过添加 +/- 5 生成 4 个角。例如,对于 (20,20),角为 (25, 25) (25, 15) (15, 15) (15, 25 ) (25, 25)。并将所有角点存储在一个列表中。

  3. 计算每个角的出现次数。如果计数是奇数,则它是 blob 的角。使坐标整数使这一步变得容易。计算浮点数有问题。

  4. 将 blob 角坐标除以 10,得到原始分辨率。

  5. 使用标准算法顺时针对角进行排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2019-11-12
    • 2021-02-19
    • 2021-08-29
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    相关资源
    最近更新 更多