You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中将旋转正方形映射至Numpy数组并修改区域内数值

解决旋转正方形区域的Numpy数组修改问题

嗨,这个问题其实挺常见的——处理任意旋转的多边形区域掩码生成嘛,我给你推荐一个简单又高效的方案,用matplotlib.path.Path做点-in-多边形判断,完美适配你的需求,不用写复杂的线性代数代码就能搞定。

下面是具体的实现步骤和代码:

核心思路

我们需要先生成一个掩码,标记出旋转正方形内的所有像素位置,再用这个掩码把原数组的对应位置设为1。matplotlib.path.Path可以轻松处理任意凸多边形(包括旋转的正方形)的点归属判断,是这个场景的绝佳工具。

完整代码示例

import numpy as np
from matplotlib.path import Path

# 初始化你的行星表面数组(15000行 × 7500列)
planet_surface = np.zeros((15000, 7500), dtype=np.int8)

# 替换成你实际的四个角点坐标,格式为[[y0, x0], [y1, x1], [y2, x2], [y3, x3]]
# 注意:角点顺序必须是顺时针或逆时针,不能乱序
corners = np.array([[1000, 2000], [1500, 3000], [2000, 2500], [1500, 1500]])

# 创建多边形路径对象
square_path = Path(corners)

# --- 方法1:遍历整个数组(适合小数组或对性能要求不高的场景)---
# 生成整个数组的坐标网格,indexing='ij'确保y对应行、x对应列,和数组索引一致
y_coords, x_coords = np.meshgrid(np.arange(planet_surface.shape[0]),
                                 np.arange(planet_surface.shape[1]),
                                 indexing='ij')
# 把网格转换成[N, 2]的点数组,每个元素是(y, x)坐标
all_points = np.stack((y_coords.flatten(), x_coords.flatten()), axis=1)

# 判断每个点是否在旋转正方形内
is_inside = square_path.contains_points(all_points)

# 将判断结果恢复成原数组形状,然后赋值
planet_surface[is_inside.reshape(planet_surface.shape)] = 1

# --- 方法2:裁剪子区域提升性能(强烈推荐给你的大数组)---
# 先找到正方形的包围盒,只处理这个范围内的点,大幅减少计算量
y_min, y_max = corners[:, 0].min(), corners[:, 0].max()
x_min, x_max = corners[:, 1].min(), corners[:, 1].max()

# 确保切片不超出数组边界
y_slice = slice(max(0, y_min), min(planet_surface.shape[0], y_max + 1))
x_slice = slice(max(0, x_min), min(planet_surface.shape[1], x_max + 1))

# 生成子区域的坐标网格
y_sub, x_sub = np.meshgrid(np.arange(y_slice.start, y_slice.stop),
                           np.arange(x_slice.start, x_slice.stop),
                           indexing='ij')
sub_points = np.stack((y_sub.flatten(), x_sub.flatten()), axis=1)

# 判断子区域内的点是否在正方形内
sub_inside = square_path.contains_points(sub_points)

# 给子区域内的对应位置赋值
planet_surface[y_slice, x_slice][sub_inside.reshape(y_sub.shape)] = 1

关键注意事项

  • 角点顺序:四个角点必须按顺时针或逆时针的顺序排列,不能是随机顺序,否则Path会识别出错误的多边形形状。
  • 性能优化:你的数组是15000×7500,有1.125亿个像素,方法2通过裁剪包围盒能大幅减少需要判断的点数量,速度会快很多。
  • 依赖说明:matplotlib是Python数据科学栈的标准库,大多数环境都已经预装,如果没有的话用pip install matplotlib安装即可。

如果不想依赖matplotlib,也可以用纯Numpy实现点-in-旋转正方形的判断,但需要推导四条边的线性不等式,代码会繁琐不少,上面的方法已经是最简洁高效的方案了。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:18:12