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

如何在NumPy数组中为值为0的像素区域绘制轮廓

如何给图像中0值像素区域绘制轮廓

你的代码问题在于,你只是找到了所有0值像素的最小/最大行、列范围,然后把这个矩形区域内的所有像素改成了1,这自然只会得到一个包围整个0值区域的矩形,而不是每个0值区域的边缘轮廓。咱们来用两种方法解决这个问题:

方法一:用OpenCV(最简便的专业方法)

OpenCV有专门的轮廓检测API,能精准提取每个连通的0值区域的轮廓,代码示例如下:

import numpy as np
import cv2
from PIL import Image
import matplotlib.pyplot as plt

# 读取图像并转为灰度图
input_image = Image.open(path_to_image).convert("L")
input_image_array = np.asarray(input_image).astype(np.uint8)

# 找轮廓:cv2.RETR_EXTERNAL只找最外层轮廓,cv2.CHAIN_APPROX_SIMPLE压缩轮廓点
contours, _ = cv2.findContours(input_image_array, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 创建一个和原图一样的空白画布,用来绘制轮廓
contour_image = np.zeros_like(input_image_array)
# 绘制轮廓:颜色设为255(白色),线条宽度2
cv2.drawContours(contour_image, contours, -1, 255, 2)

# 展示结果
plt.imshow(contour_image, cmap='gray')
plt.show()

方法二:纯Numpy/Matplotlib实现(不用OpenCV)

如果不想依赖OpenCV,可以用形态学膨胀操作来提取轮廓:膨胀0值区域后,减去原0值区域,得到的就是边缘部分:

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from scipy.ndimage import binary_dilation

# 读取图像并转为灰度数组
input_image = Image.open(path_to_image).convert("L")
input_image_array = np.asarray(input_image).astype(np.uint8)

# 创建0值区域的掩码
zero_mask = input_image_array == 0

# 定义膨胀的结构元素(3x3的正方形,用来扩展边缘)
structuring_element = np.ones((3,3), dtype=bool)
# 膨胀掩码
dilated_mask = binary_dilation(zero_mask, structure=structuring_element)

# 轮廓 = 膨胀后的掩码 - 原掩码(得到边缘部分)
contour_mask = dilated_mask ^ zero_mask

# 将轮廓区域设为255(白色),其余保持0
result_image = np.where(contour_mask, 255, 0).astype(np.uint8)

# 展示结果
plt.imshow(result_image, cmap='gray')
plt.show()

这两种方法都能准确提取每个0值连通区域的轮廓,而不是一个大矩形。你可以根据自己的环境选择合适的方案~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:25:46