将一组(x,y)坐标设置为数组,以便绘制多边形。

3

我有一些代码,可以打印出一个坐标列表(保存在points中)

f=open('139cm_2000_frame27.json') 
data=json.load(f) 
shapes=data["shapes"] 
for i in shapes: 
    print(i['label'])   # prints the label first
    for c in i['points']:
        d=np.array(c)
        print(d)       # an array containing coordinates in the form (x,y) 

d是n个十边形的点的坐标。所以0-9号坐标是第一个多边形的坐标,10-19号坐标是第二个多边形......

在json文件中可能有任意数量的多边形,但它们每个都始终具有10个坐标。

我需要找到一种使用这些坐标在128x128数组中“绘制”/“重建”这些多边形的方法。

我已经尝试过了。

from skimage.draw import polygon
   img = np.zeros((128, 128), dtype=np.uint8)
   r = np.array([#the x coordinates of d])
   c = np.array([#the y coordinates of d])
   rr, cc = polygon(r, c)
   img[rr, cc] = 1 #unsure about the 1
   img

但我不知道如何 1) 获得一组由10个坐标组成的集合,以及 2) 将xs读入r,ys读入c。

非常感谢!

输入json的示例:

{
  "version": "4.6.0",
  "flags": {},
  "shapes": [
    {
      "label": "blob",
      "points": [
        [
          61.42857142857143,
          20.285714285714285
        ],
        [
          59.10047478151446,
          18.879430437885873
        ],
        [
          58.04359793578868,
          16.37330203102605
        ],
        [
          58.661631924538575,
          13.724584936383643
        ],
        [
          60.71850877026435,
          11.94499905752918
        ],
        [
          63.42857142857143,
          11.714285714285715
        ],
        [
          65.75666807562841,
          13.120569562114127
        ],
        [
          66.81354492135418,
          15.62669796897395
        ],
        [
          66.19551093260428,
          18.275415063616357
        ],
        [
          64.13863408687851,
          20.05500094247082
        ]
      ],
      "group_id": null,
      "shape_type": "polygon",
      "flags": {}
    },
    {
      "label": "blob",
      "points": [
        [
          88.71428571428572,
          82.42857142857143
        ],
        [
          85.63470409582908,
          81.33512050565437
......

请分享一个输入文件(json)的简单示例。 - wohlstad
1个回答

2

从软件工程的角度来看,建议将代码分解成简单的独立部分(即模块化)。

首先,您需要一个读取输入JSON并解析它的函数。在下面的代码中,我将其称为read_input。解析数据的格式取决于应用程序。
我选择返回ndarray对的list。列表中的每个元素代表一个多边形。每个多边形包含2个ndarray:1个用于x坐标,1个用于y坐标。我选择这种表示方法是因为它便于绘制多边形(见下文)。

其次,您需要一个绘制多边形的函数(draw_polygons)。它将包含对多边形列表的迭代,并调用一个低级别的函数来绘制一个多边形(draw_one_polygon),同样出于模块化的原因。

请参见下面的代码:

import json
import numpy as np
from skimage.draw import polygon

def read_input(filename: str):
    polygons = []
    with open(filename) as f:
        data = json.load(f)
        shapes = data["shapes"]
        for i in shapes:
            cur_poly_points = i["points"]
            tmp = list(zip(*cur_poly_points))
            # NOTE: The following line assumes that the point coordinates are given as (x,y). 
            #       Change the order of the indices if needed.
            polygons.append((np.array(tmp[1]), np.array(tmp[0])))
    return polygons

def draw_one_polygon(img, one_poly):
    r = one_poly[0];
    c = one_poly[1];
    rr, cc = polygon(r, c)
    img[rr,cc] = 1

def draw_polygons(img, polygons):
    for poly in polygons:
        draw_one_polygon(img, poly)

filename = '139cm_2000_frame27.json'
polygons = read_input(filename)
img = np.zeros((128, 128), dtype=np.uint8)
draw_polygons(img, polygons)
print(img)

注意:在您的实际代码中,您应该验证坐标是否超出图像尺寸。

文档和示例: skimage.draw.polygon

如果您不熟悉此记法:*cur_poly_points,请参见此处:如何将元组列表解压缩为单个列表?


如果我要循环遍历文件,那么依次遍历 139cm_2000_frame27.json、139cm_2000_frame28.json、139cm_2000_frame29.json。 - Joseph Darton
然后添加一个名为 handle_files 的新函数。它将在循环中逐个读取文件,并为每个文件调用 handle_one_file,该函数将执行与上面主脚本中相似的代码(调用 read_input 等)。 - wohlstad
我的意思是handle_files将逐个处理文件(在循环中),但不会直接读取它们。实际读取文件的调用应该只在handle_one_file中。handle_one_file是当前主脚本中代码的“替代品”,但带有文件名作为参数。 - wohlstad
你可以增加网格大小或者裁剪多边形。要裁剪多边形,你需要在绘制每个多边形之前迭代所有点,并更新所有坐标(x或y)为最大值127。 - wohlstad
@CharlieG 好的建议。我已经更新了代码。 - wohlstad
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接