簡體   English   中英

從 Python 中的二進制圖像獲取像素邊界坐標(不是邊緣)

[英]Get pixel boundary coordinates from binary image in Python (not edges)

我有一個包含單個連續斑點的二進制圖像,沒有孔。 我想根據邊緣像素的外邊緣創建一個多邊形 object。 我知道如何自己獲取邊緣像素,但我想要像素邊界的實際坐標,順時針或逆時針排序。 所有像素都有 integer 坐標。

例如,假設我在 (2,2) 處有一個像素。 多邊形的頂點為: (2.5, 2.5) (2.5, 1.5) (1.5, 1.5) (1.5, 2.5) (2.5, 2.5)

有沒有一種精確的、非近似的方法來做到這一點? 最好在 Python 中?

參見示例:

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

根據評論,這是我實施的方法:

  1. 將所有像素坐標乘以 10,這樣我們就只處理整數。

  2. 對於每個像素,通過添加 +/- 5 生成 4 個角。例如,對於 (20,20),角為 (25, 25) (25, 15) (15, 15) (15, 25) (25 , 25)。 並將所有角存儲在一個列表中。

  3. 計算每個角的出現次數。 如果計數是奇數,則它是 blob 的角。 使坐標整數使這一步變得容易。 計算浮點數有問題。

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

  5. 使用標准算法順時針對角進行排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM