如何使用Numpy实现RGB图像色标数字化及目标区域数值分析
DICOM伪彩图标定与数值映射实现方案
核心实现步骤
1. 色标区域提取与映射关系构建
首先需要确定色标在整图中的像素坐标范围,你的示例图中色标为最右侧垂直分布,从上到下对应测量值-10到30:
- 裁剪出色标区域的numpy数组:假设原图数组形状为
(H, W, 3),色标x范围可设为[W-30, W-10],y范围设为[50, H-50](可根据实际图像微调坐标),沿y轴对色标每个位置取x方向的平均RGB,得到色标的RGB序列colorbar_rgb,长度等于色标高度 - 生成色标对应的测量值序列:默认线性分布的情况下直接用
np.linspace(-10, 30, len(colorbar_rgb))得到每个RGB对应的基准测量值 - 为提升匹配精度,建议将RGB转换为LAB色彩空间,避免RGB空间色差计算与人眼感知不一致的问题,转换可借助OpenCV的
cv2.cvtColor实现
代码示例:
import numpy as np import cv2 from scipy.spatial import cKDTree # 变量说明:dicom_arr为你提取的三维numpy数组,形状为(H, W, 3) H, W = dicom_arr.shape[:2] # 色标坐标配置,可根据你的图像实际尺寸调整 colorbar_x_start, colorbar_x_end = W - 30, W - 10 colorbar_y_start, colorbar_y_end = 50, H - 50 # 提取色标区域 colorbar_area = dicom_arr[colorbar_y_start:colorbar_y_end, colorbar_x_start:colorbar_x_end, :] # 沿x轴取平均得到每个y位置的基准RGB colorbar_rgb = np.mean(colorbar_area, axis=1) # 转换为LAB色彩空间 colorbar_lab = cv2.cvtColor(colorbar_rgb.reshape(-1, 1, 3).astype(np.uint8), cv2.COLOR_RGB2LAB).reshape(-1, 3) # 生成色标对应的测量值序列 colorbar_values = np.linspace(-10, 30, len(colorbar_lab)) # 构建KD树用于后续快速色差匹配 kdt = cKDTree(colorbar_lab)
2. 计算目标区域平均RGB
先确定目标方格的坐标范围,裁剪后取区域平均值即可:
# 目标方格坐标,根据你的实际需求修改 y1, y2, x1, x2 = 100, 150, 200, 250 roi_area = dicom_arr[y1:y2, x1:x2, :] roi_avg_rgb = np.mean(roi_area, axis=(0,1)).reshape(1, 1, 3).astype(np.uint8) # 同样转换为LAB空间保证匹配精度 roi_avg_lab = cv2.cvtColor(roi_avg_rgb, cv2.COLOR_RGB2LAB).reshape(1, 3)
3. 匹配得到对应测量值
用KD树查找最接近的色标LAB值对应的测量值,若需要更高的平滑度可选择前N个近邻做加权平均:
# 匹配最近的1个色标点,返回距离和对应索引 dist, idx = kdt.query(roi_avg_lab, k=1) result_value = colorbar_values[idx[0]] # 可选优化方案:取前3个近邻做距离加权平均,减少匹配误差 # dist, idx = kdt.query(roi_avg_lab, k=3) # weights = 1 / (dist + 1e-6) # 加极小值避免除零 # result_value = np.sum(weights * colorbar_values[idx]) / np.sum(weights)
注意事项
- 色标坐标需要根据你的实际DICOM图像尺寸手动校准,确保裁剪的是纯色标区域,不要包含周围的刻度文字
- 如果色标不是线性分布,可以提前标注色标上的刻度点位置和对应数值,用插值方式生成完整的色标数值序列
- 如果DICOM图像存在伽马校正或色彩偏移,可先对整图做色彩校正后再做映射
内容的提问来源于stack exchange,提问作者ocns
相关产品推荐
相关产品推荐

