使用JSON创建掩码遇OpenCV drawContours报错npoints>0的咨询
问题解决:OpenCV drawContours断言错误及掩码创建失败
错误原因
OpenCV的drawContours函数对输入的轮廓点格式有严格要求:
- 轮廓必须是**(N, 1, 2)**形状的numpy数组,其中N是点的数量
- 数组数据类型必须为
np.int32
你的代码中ab = np.stack((x_val, y_val))生成的是(2, N)形状的数组,不符合函数要求,导致触发npoints > 0的断言错误。
代码修改方案
步骤1:修正轮廓点格式
将原来的ab生成代码替换为符合OpenCV要求的格式:
# 替换原ab=np.stack((x_val, y_val))这一行 ab = np.array(list(zip(x_val, y_val)), dtype=np.int32).reshape((-1, 1, 2))
步骤2:简化点的遍历逻辑(可选,但更清晰)
你的JSON结构是三层嵌套[[[x,y], [x,y], ...]],可以简化循环代码,避免多层索引的混乱:
x_val = [] y_val = [] # 直接遍历最内层的点列表 for point in data[0]: x_val.append(point[0]) y_val.append(point[1])
完整修改后代码
import cv2 import numpy as np import matplotlib.pyplot as plt # 假设data是读取后的JSON数据,img是输入图像 x_val = [] y_val = [] # 简化点遍历 for point in data[0]: x_val.append(point[0]) y_val.append(point[1]) fig = plt.figure() plt.imshow(img.astype(np.uint8)) plt.scatter(x_val, y_val, zorder=2, color='red', marker='.', s=55, alpha=0.25) # 生成符合要求的轮廓数组 ab = np.array(list(zip(x_val, y_val)), dtype=np.int32).reshape((-1, 1, 2)) # 绘制轮廓到原图(使用副本避免修改原图像) img2 = cv2.drawContours(img.copy(), [ab], -1, (255, 255, 255), 1) # 创建掩码,指定uint8类型避免异常 mask = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) img3 = cv2.drawContours(mask, [ab], -1, 255, -1)
额外注意事项
- 创建掩码时,要确保
mask的 dtype 为np.uint8,否则可能出现显示异常 - 调用
drawContours时建议传入图像的副本,避免误修改原图像
内容的提问来源于stack exchange,提问作者fromHere
相关产品推荐
相关产品推荐

