如何用Python将图像像素值处理为仅0或255?(附卫星掩码图像)
卫星掩码图像二值化(仅保留0和255像素值)解决方案
针对掩码数据集存在非0/255像素值的问题,以下提供几种实用的Python处理方案,解决阈值处理效果不佳的问题:
方法1:基于像素值范围的手动二值化(适用于已知有效区间)
如果能明确前景像素的大致范围,直接通过区间判断转换比单一阈值更可靠:
import cv2 import numpy as np # 读取灰度掩码图像(彩色图先转灰度) mask = cv2.imread('satellite_mask.jpg', cv2.IMREAD_GRAYSCALE) # 查看原图像所有像素值,辅助确定区间(可选) print("原掩码像素值:", np.unique(mask)) # 定义前景像素的范围(根据实际数据调整) lower_bound = 80 upper_bound = 255 # 生成二值掩码:区间内设为255,其余为0 binary_mask = np.where((mask >= lower_bound) & (mask <= upper_bound), 255, 0) # 保存处理后的掩码 cv2.imwrite('binary_mask.jpg', binary_mask.astype(np.uint8))
方法2:K-means聚类自动区分前景背景(适用于未知像素区间)
如果不清楚前景像素范围,用聚类自动将像素分为背景、前景两类,再映射为0和255:
import cv2 import numpy as np # 读取灰度掩码图像 mask = cv2.imread('satellite_mask.jpg', cv2.IMREAD_GRAYSCALE) # 转换为K-means所需的二维格式 pixel_data = mask.reshape((-1, 1)).astype(np.float32) # K-means聚类参数:分2类,迭代100次 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2) _, labels, centers = cv2.kmeans(pixel_data, 2, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS) # 映射聚类结果为0/255 centers = np.uint8(centers) clustered_mask = centers[labels.flatten()].reshape(mask.shape) # 按亮度区分背景(暗)和前景(亮) binary_mask = np.where(clustered_mask == centers.min(), 0, 255) # 保存结果 cv2.imwrite('binary_mask.jpg', binary_mask.astype(np.uint8))
方法3:基于PIL库的轻量处理
习惯用PIL的话,可参考以下代码:
from PIL import Image import numpy as np # 读取并转为灰度图 mask = Image.open('satellite_mask.jpg').convert('L') mask_np = np.array(mask) # 区间判断生成二值掩码 binary_mask_np = np.where(mask_np >= 80, 255, 0) binary_mask = Image.fromarray(binary_mask_np.astype(np.uint8)) # 保存 binary_mask.save('binary_mask.jpg')
注意事项
- 先通过
np.unique(mask)查看原掩码的所有像素值,能更精准设置阈值区间; - 若原掩码是彩色图,需先转为灰度图,或针对每个通道单独处理后合并。
内容的提问来源于stack exchange,提问作者Bishal Rijal
相关产品推荐
相关产品推荐

