如何用Numpy高效将图像轮廓坐标在零矩阵中设为1?
解决方案
一、Numpy高效实现
直接用zero[test] = 1无效的原因是轮廓数组的(N,1,2)维度不符合Numpy的索引规则,需要先简化坐标维度,分离行(y)和列(x)索引:
分步实现
import numpy as np zero = np.zeros((5, 5)) test = np.array([[[2,1]], [[3, 1]], [[1, 0]]]) # 将轮廓数组从(N,1,2)压缩为(N,2) coords = test.reshape(-1, 2) # 分离y(行索引)和x(列索引) y_indices = coords[:, 1] x_indices = coords[:, 0] # 批量赋值 zero[y_indices, x_indices] = 1 print(zero)
输出结果:
[[0. 1. 0. 0. 0.] [0. 0. 1. 1. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.] [0. 0. 0. 0. 0.]]
简洁写法
可以一行完成坐标转换与赋值:
zero[tuple(test.reshape(-1, 2).T)] = 1
test.reshape(-1,2).T将坐标转为(2, N)的数组,再转成元组(y_array, x_array),完美匹配Numpy的二维数组索引规则。
二、其他高效方法
1. OpenCV drawContours(推荐)
OpenCV的drawContours是底层C++实现,速度远超Python循环,且完全适配你得到的轮廓格式:
import cv2 import numpy as np zero = np.zeros((5, 5), dtype=np.uint8) test = np.array([[[2,1]], [[3, 1]], [[1, 0]]]) # 绘制轮廓,thickness=-1表示填充(此处仅标记坐标点,设为1也可) cv2.drawContours(zero, [test], 0, 1, thickness=-1) print(zero)
注意:drawContours的第二个参数需要是轮廓列表,直接把你的轮廓数组用[]包裹即可。
2. Scipy稀疏矩阵(超大图像场景)
如果图像尺寸极大,普通零矩阵占用内存过高,可使用稀疏矩阵存储:
from scipy.sparse import csr_matrix coords = test.reshape(-1, 2) rows = coords[:, 1] cols = coords[:, 0] # 创建稀疏矩阵 sparse_mat = csr_matrix((np.ones(len(rows)), (rows, cols)), shape=(5,5)) # 按需转为稠密矩阵 dense_mat = sparse_mat.todense()
这种方法在处理百万级坐标时,内存效率远高于普通Numpy数组。
内容的提问来源于stack exchange,提问作者gugi200
相关产品推荐
相关产品推荐

