从多边形点Python创建一个填充的numpy数组

2024-10-01 04:53:57 发布

您现在位置:Python中文网/ 问答频道 /正文

如果有人能帮助我更快地解决我的问题,我将不胜感激。在

这是场景:-I有一个浮点数多边形,我想映射到一个网格。网格单元可以是不同的宽度和高度,而不是像我的图像所显示的一样统一。即矩形。在

我试过使用图像绘制,但它只使用整数。将浮点数转换成整数意味着我必须放大浮点数并去掉小数点以保持一定的精度,但是图像绘制无法处理较大的多边形点。在

有没有更雄辩和快速的方法来实现一个数字数组1(蓝色)的填充区域的多边形和0(红色)的其余部分。我已经读了一点关于网格网格,但看不出它如何可以用于这个场景。在

非常感谢

代码的结果是

cols = 4
rows = 4
points = [[1535116L, 1725047L], [1535116L, 2125046L], [-464884L, 2125046L], [-464884L, 125046L]]    

bbCut = getPythonBoundBox(points)
cutWidth =  bbCut[1][0]-bbCut[0][0]
scale = float(cutWidth) / float(rows)
###Center data to origin
for p in range(len(points)):
    points[p][0] -= (bbCut[1][0] - bbCut[0][0])/2
    points[p][1] -= (bbCut[1][1] - bbCut[0][1])/2
    points[p][0] /= scale
    points[p][1] /= scale


##move points to Zero
bbCut = getPythonBoundBox(points)

for p in range(len(points)):
    points[p][0] -=bbCut[0][0]
    points[p][1] -=bbCut[0][1]

pointToTuple= []
for p in range(len(points)):
  pointToTuple.append((points[p][0], points[p][1]))

imgWidth = float(rows)
imgHeight = float(cols)

img = Image.new('L', (int(imgWidth), int(imgHeight)), 0) 
draw = ImageDraw.Draw(img)

draw.polygon(pointToTuple, fill=1)

array =  np.reshape(list(img.getdata()), (cols, rows))

############This is the result from the array############
##If you compare this array to the coloured scaled image ive have drawn
##its missing a 1 on the second value in the first row
##and another 1 on the second row 3rd value
##I'm assuming there is some parsing happening here with float to int?                       
array([1, 0, 0, 0])
array([1, 1, 0, 0])
array([1, 1, 1, 1])
array([1, 1, 1, 1])
#########################################################

def getPythonBoundBox(points):
    bigNumber = 10e10
    xmin = bigNumber
    xmax = -bigNumber
    ymin = bigNumber
    ymax = -bigNumber
    g = []
    a = len(points)
    for i in xrange(a):
        if points[i][0] < xmin: xmin = points[i][0]
        if points[i][0] > xmax: xmax = points[i][0]
        if points[i][1] < ymin: ymin = points[i][1]
        if points[i][1] > ymax: ymax = points[i][1]
    p1 = [xmin,ymin]
    g.append(p1)
    p2 = [xmax,ymax]
    g.append(p2)
    return (g)

polygon shape over grid


Tags: thetoin网格forlenfloatarray
1条回答
网友
1楼 · 发布于 2024-10-01 04:53:57

matplotlib.path.Path有一个方法contains_points。因此,只需用多边形点实例化一条路径,然后检查网格坐标是否在该路径内。你的网格可以有你想要的任何分辨率。这由下面代码中的nx和{}(或者dx和{})控制。在

代码:

import numpy as np
import matplotlib.pyplot as plt

from matplotlib.patches import PathPatch
from matplotlib.path import Path

# create a matplotlib path
points = [[1535116L, 1725047L],
          [1535116L, 2125046L],
          [-464884L, 2125046L],
          [-464884L, 125046L],
          [1535116L, 1725047L]]
codes = [Path.MOVETO,
         Path.LINETO,
         Path.LINETO,
         Path.LINETO,
         Path.CLOSEPOLY,
         ]
path = Path(points, codes)

# check the path
fig, (ax1, ax2, ax3) = plt.subplots(1,3)
patch = PathPatch(path, facecolor='k')
ax1.add_patch(patch)
xmin, ymin = np.min(points, axis=0)
xmax, ymax = np.max(points, axis=0)
ax1.set_ylim(ymin,ymax)
ax1.set_xlim(xmin,xmax)
ax1.set_aspect('equal')

# create a grid
nx, ny = 1000, 1000
x = np.linspace(xmin, xmax, nx)
y = np.linspace(ymin, ymax, ny)
xgrid, ygrid = np.meshgrid(x, y)
pixel_coordinates = np.c_[xgrid.ravel(), ygrid.ravel()]

# find points within path
img = path.contains_points(pixel_coordinates).reshape(nx,ny)

# plot
ax2.imshow(img, cmap='gray_r', interpolation='none', origin='lower')

# repeat, but this time specify pixel widths explicitly
dx, dy = 2000, 2000
x = np.arange(xmin, xmax, dx)
y = np.arange(ymin, ymax, dy)
xgrid, ygrid = np.meshgrid(x, y)
pixel_coordinates = np.c_[xgrid.ravel(), ygrid.ravel()]
img = path.contains_points(pixel_coordinates).reshape(len(x), len(y))
ax3.imshow(img, cmap='gray_r', interpolation='none', origin='lower')

enter image description here

更新:

好的,现在测试每个平铺的角是否在路径内。出于某种原因,我还是得到了另一个答案。你有多确定你提供的观点是准确的?在

代码+图像:

^{pr2}$

enter image description here

相关问题 更多 >