如何解包cv2.findcontours()返回的可变数量不规则二维numpy元组?
处理cv2.findContours结果与Awkward Array的访问方法
cv2.findContours返回长度可变的元组,每个元素是形状为(N,1,2)的NumPy数组(N为轮廓点数量)。要将其转为Awkward Array并单独访问每个轮廓,可按以下步骤操作:
1. 将轮廓转为Awkward Array
先把每个轮廓的数组压缩掉冗余的中间维度(从(N,1,2)转为(N,2)),再用ak.from_iterable生成Awkward Array:
import cv2 import awkward as ak # 读取二值图像并获取轮廓 img = cv2.imread("binary_image.png", cv2.IMREAD_GRAYSCALE) contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 转换为Awkward Array ak_contours = ak.from_iterable([cnt.squeeze(axis=1) for cnt in contours])
2. 单独访问单个轮廓
直接通过索引获取指定轮廓,如需转为NumPy数组进一步操作,使用ak.to_numpy:
# 获取第0个轮廓(Awkward Array格式) first_contour = ak_contours[0] # 转为NumPy数组 first_contour_np = ak.to_numpy(first_contour) # 如需恢复cv2需要的(N,1,2)形状,可reshape first_contour_cv2 = first_contour_np.reshape(-1, 1, 2)
3. 遍历所有轮廓
用for循环直接遍历Awkward Array,逐个处理每个轮廓:
for idx, contour in enumerate(ak_contours): # 获取轮廓点数量 point_count = ak.num(contour) print(f"轮廓{idx}包含{point_count}个点") # 转为NumPy数组并计算面积 contour_np = ak.to_numpy(contour).reshape(-1,1,2) area = cv2.contourArea(contour_np) print(f"轮廓{idx}面积:{area:.2f}")
关键说明
- cv2返回的轮廓数组自带
(N,1,2)的冗余维度,用squeeze(axis=1)压缩后,Awkward Array才能正确识别为可变长度的二维点集合。 - Awkward Array支持向量化操作,比如批量计算所有轮廓的点数量:
ak.num(ak_contours)会返回每个轮廓的点数量数组。
内容的提问来源于stack exchange,提问作者Bob Bobinson
相关产品推荐
相关产品推荐

