实现黑白灰三值图像阈值分割,寻求阈值设置及贴纸分离方案
实现黑、白、灰三值阈值分割并合理设置阈值
一、改造代码实现三值阈值分割
要实现黑、白、灰三值分割,需要设置两个阈值(低阈值t_low和高阈值t_high),将灰度图像划分为三个区域:
- 黑色区域:灰度值 <
t_low - 灰色区域:
t_low≤ 灰度值 <t_high - 白色区域:灰度值 ≥
t_high
基于你提供的代码,修改后的完整实现如下:
import numpy as np import matplotlib.pyplot as plt import skimage.io import skimage.color import skimage.filters # 加载图像 image = skimage.io.imread("/home/student_joy/desktop/optimization_11_10/original_duplicate.png")[:,:,:3] # 转为灰度图并去噪 gray_image = skimage.color.rgb2gray(image) blurred_image = skimage.filters.gaussian(gray_image, sigma=1.0) # 绘制直方图(用于辅助选阈值) histogram, bin_edges = np.histogram(blurred_image, bins=256, range=(0.0, 1.0)) fig, ax = plt.subplots() plt.plot(bin_edges[0:-1], histogram) plt.title("灰度直方图") plt.xlabel("灰度值") plt.ylabel("像素数量") plt.xlim(0, 1.0) # 设置三值分割的两个阈值(示例值,可根据实际调整) t_low = 0.3 t_high = 0.7 # 创建三值掩码 black_mask = blurred_image < t_low gray_mask = (blurred_image >= t_low) & (blurred_image < t_high) white_mask = blurred_image >= t_high # 可视化三个区域 fig, axes = plt.subplots(1, 3, figsize=(15, 5)) axes[0].imshow(black_mask, cmap="gray") axes[0].set_title("黑色区域掩码") axes[1].imshow(gray_mask, cmap="gray") axes[1].set_title("灰色区域掩码") axes[2].imshow(white_mask, cmap="gray") axes[2].set_title("白色区域掩码") # 生成三值图像(0=黑,1=灰,2=白),方便后续分离贴纸 three_value_image = np.zeros_like(blurred_image) three_value_image[gray_mask] = 1 three_value_image[white_mask] = 2 fig, ax = plt.subplots() plt.imshow(three_value_image, cmap="gray") plt.title("三值分割结果") plt.show()
二、合理设置阈值的方法
手动设置t=0.72缺乏依据,推荐三种可靠的阈值选择方式:
1. 基于直方图手动选阈值
观察灰度直方图的波谷位置:直方图的波谷对应不同区域的分界点。如果你的图像直方图有两个明显波谷,这两个波谷的灰度值就可以作为t_low和t_high——波谷左侧对应黑色区域,中间是灰色,右侧是白色。
2. 自动阈值算法(适配三值分割)
如果需要自动计算阈值,可以结合Otsu算法分两步处理:
- 先用Otsu算法得到全局二值阈值,再针对其中一个区域(比如灰色+白色区域)再次计算Otsu阈值,得到第二个分界值。
示例代码如下:
# 第一步:用Otsu得到全局二值阈值 global_thresh = skimage.filters.threshold_otsu(blurred_image) # 第二步:针对灰度+白色区域再次计算Otsu阈值 upper_region = blurred_image[blurred_image >= global_thresh] t_high = skimage.filters.threshold_otsu(upper_region) if len(upper_region) > 0 else global_thresh t_low = global_thresh # 用自动生成的阈值创建掩码 black_mask = blurred_image < t_low gray_mask = (blurred_image >= t_low) & (blurred_image < t_high) white_mask = blurred_image >= t_high
这种方法适合直方图有三个明显峰值的图像,能自动定位分界阈值。
3. 交互式调整阈值
如果处理的图像数量不多,可以用交互式工具实时调整阈值,直观看到效果:
from ipywidgets import interact def update_thresholds(t_low=0.3, t_high=0.7): black_mask = blurred_image < t_low gray_mask = (blurred_image >= t_low) & (blurred_image < t_high) white_mask = blurred_image >= t_high fig, axes = plt.subplots(1, 3, figsize=(15,5)) axes[0].imshow(black_mask, cmap="gray") axes[1].imshow(gray_mask, cmap="gray") axes[2].imshow(white_mask, cmap="gray") plt.show() interact(update_thresholds, t_low=(0,1,0.01), t_high=(0,1,0.01))
运行后拖动滑块,就能实时看到不同阈值组合下的掩码效果,快速找到最适合分离贴纸的参数。
内容的提问来源于stack exchange,提问作者user20384021
相关产品推荐
相关产品推荐

