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

如何提取二值图像白像素并在Matplotlib中正确展示分支及计算间距

问题描述
  • 需实现两个需求:
    1. 正确提取二值图像中的白像素,在Matplotlib绘图板上正确展示带交叉点与分支的图像结构
    2. 分别计算各分支的边缘像素间距
  • 现有问题:提供的Python脚本仅能处理无分支二值图像,处理带分支图像时会出现展示错误,且无法独立计算各分支间距
解决方案

针对分支图像的特性,我们需要先对图像中的分支进行连通域分割,再对每个独立分支单独处理边缘提取与间距计算。以下是修改后的完整代码:

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy.spatial.distance import euclidean
from skimage.measure import label, regionprops
import matplotlib
from matplotlib.colors import BoundaryNorm
from matplotlib.colorbar import ColorbarBase

# 配置字体
matplotlib.rc("font", family='Microsoft YaHei')

# 加载图像
image_path = r'E:\data\ground_truth\1089_13.jpg'
image = Image.open(image_path).convert('L')  # 确保为灰度图
image_array = np.array(image)

# 提取白像素点
white_points = np.column_stack(np.where(image_array == 255))

# 连通域分割,区分不同分支
label_image = label(image_array == 255)
regions = regionprops(label_image)

# 初始化绘图
fig, ax = plt.subplots(figsize=(10, 8))
ax.set_xlim(0, image_array.shape[1])
ax.set_ylim(0, image_array.shape[0])
ax.invert_yaxis()
ax.set_title('带分支的二值图像分支间距分析')

# 预设不同分支的颜色
branch_colors = ['#FF0000', '#00FF00', '#0000FF', '#FFA500', '#800080', '#00FFFF']
cmap = plt.get_cmap('viridis')

# 处理每个分支
for idx, region in enumerate(regions):
    # 获取当前分支的所有像素点
    branch_points = region.coords
    if len(branch_points) < 2:
        continue  # 跳过过小的连通域

    # 绘制分支原始像素
    ax.plot(branch_points[:, 1], branch_points[:, 0], '.', color=branch_colors[idx % len(branch_colors)], markersize=1)

    # 提取分支的左右边缘点(按行处理,兼容分支场景)
    left_points = []
    right_points = []
    unique_ys = np.unique(branch_points[:, 0])
    for y in unique_ys:
        row_points = branch_points[branch_points[:, 0] == y]
        if len(row_points) >= 2:
            left = row_points[np.argmin(row_points[:, 1])]
            right = row_points[np.argmax(row_points[:, 1])]
            left_points.append(left)
            right_points.append(right)
    left_points = np.array(left_points)
    right_points = np.array(right_points)

    if len(left_points) == 0 or len(right_points) == 0:
        continue

    # 绘制分支边缘
    ax.plot(left_points[:, 1], left_points[:, 0], '-', color=branch_colors[idx % len(branch_colors)], lw=1, label=f'分支{idx+1}边缘')
    ax.plot(right_points[:, 1], right_points[:, 0], '-', color=branch_colors[idx % len(branch_colors)], lw=1)

    # 计算当前分支的间距
    distances = [euclidean(l, r) for l, r in zip(left_points, right_points)]
    max_dist = max(distances)
    min_dist = min(distances)
    max_pair = (left_points[distances.index(max_dist)], right_points[distances.index(max_dist)])
    min_pair = (left_points[distances.index(min_dist)], right_points[distances.index(min_dist)])

    # 打印当前分支的间距信息
    print(f"=== 分支{idx+1} ===")
    print(f"最大间距: {max_dist:.2f} 像素,对应坐标: {max_pair[0]}, {max_pair[1]}")
    print(f"最小间距: {min_dist:.2f} 像素,对应坐标: {min_pair[0]}, {min_pair[1]}")
    print(f"换算为实际宽度(假设1像素=0.1cm): 最大{max_dist/10:.2f}cm,最小{min_dist/10:.2f}cm\n")

    # 绘制间距可视化线段
    bounds = np.linspace(min_dist, max_dist, num=8)
    norm = BoundaryNorm(bounds, cmap.N)
    for l, r, d in zip(left_points, right_points, distances):
        color = cmap(norm(d))
        ax.plot([l[1], r[1]], [l[0], r[0]], '-', color=color, lw=0.8)

    # 标注当前分支的最大/最小间距线段
    ax.plot([max_pair[0][1], max_pair[1][1]], [max_pair[0][0], max_pair[1][0]], '#1E90FF', lw=2, label=f'分支{idx+1}最大宽度')
    ax.plot([min_pair[0][1], min_pair[1][1]], [min_pair[0][0], min_pair[1][0]], 'black', lw=2, label=f'分支{idx+1}最小宽度')

# 添加图例和颜色条
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
cb_ax = fig.add_axes([0.92, 0.1, 0.02, 0.8])
cb = ColorbarBase(cb_ax, cmap=cmap, norm=norm, boundaries=bounds, ticks=bounds, orientation='vertical')
cb.set_label('间距(像素)')

# 显示图像
plt.tight_layout()
plt.show()
关键改进点
  • 连通域分割:使用skimage.measure.label将图像中的不同分支分割为独立的连通域,确保每个分支被单独处理
  • 分支独立处理:对每个连通域单独提取边缘点、计算间距,避免分支间的干扰
  • 可视化优化:用不同颜色区分不同分支,同时保留间距的颜色映射,直观展示各分支的间距分布
  • 信息输出:单独打印每个分支的最大/最小间距及对应坐标,满足分支独立计算的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:05:00