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

求助:如何用skimage实现类圆形目标的等距环径向强度分布测量

复刻CellProfiler径向强度分布分析的实现方案

核心思路:

  • 基于分割对象的质心(或加权质心)计算每个像素的径向距离
  • 按最大径向距离划分等间距区间,每个区间对应一个贴合对象形状的环
  • 提取每个环内像素的强度统计值(平均、总强度)

1. 依赖库导入

import numpy as np
from skimage import measure, img_as_float

2. 单对象径向强度计算函数

高效版本(推荐)

def compute_radial_intensity(image, obj_mask, num_rings=5):
    # 获取对象属性(质心、加权质心可选)
    props = measure.regionprops(obj_mask)[0]
    # 可选:用加权质心(基于图像强度)更准确,适合内部强度不均的样本
    # cy, cx = props.weighted_centroid
    cy, cx = props.centroid
    
    # 获取对象内所有像素坐标
    y_coords, x_coords = np.where(obj_mask > 0)
    # 计算每个像素到质心的欧氏距离
    distances = np.sqrt((x_coords - cx)**2 + (y_coords - cy)**2)
    max_dist = distances.max()
    
    # 生成等间距距离分界,划分环区间
    bin_edges = np.linspace(0, max_dist, num_rings + 1)
    # 给每个像素分配所属环编号
    ring_ids = np.digitize(distances, bin_edges)
    # 修正边界编号,确保所有像素落在1~num_rings范围内
    ring_ids[ring_ids == 0] = 1
    ring_ids[ring_ids > num_rings] = num_rings
    
    # 提取对应像素的强度值
    ring_intensities = image[y_coords, x_coords]
    
    # 按环统计强度
    radial_stats = []
    for ring_idx in range(1, num_rings + 1):
        ring_mask = (ring_ids == ring_idx)
        # 处理空环情况(比如对象太小,某环无像素)
        if np.any(ring_mask):
            mean_int = np.mean(ring_intensities[ring_mask])
            total_int = np.sum(ring_intensities[ring_mask])
        else:
            mean_int = 0.0
            total_int = 0.0
        # 记录当前环的距离范围
        dist_lower = bin_edges[ring_idx - 1]
        dist_upper = bin_edges[ring_idx]
        radial_stats.append({
            "ring": ring_idx,
            "distance_range": (round(dist_lower, 3), round(dist_upper, 3)),
            "mean_intensity": round(mean_int, 4),
            "total_intensity": round(total_int, 4)
        })
    return radial_stats

3. 批量处理所有分割对象

# 假设binary_mask是skimage分割得到的二值掩码
label_image = measure.label(binary_mask)
# 原始强度图像(转成float类型避免整数溢出)
intensity_image = img_as_float(original_microscopy_image)

# 遍历所有非背景对象
for label in np.unique(label_image)[1:]:
    object_mask = (label_image == label)
    stats = compute_radial_intensity(intensity_image, object_mask, num_rings=6)
    print(f"对象 {label} 径向强度统计:")
    for stat in stats:
        print(f"环{stat['ring']} | 距离范围{stat['distance_range']} | 平均强度{stat['mean_intensity']} | 总强度{stat['total_intensity']}")

关键细节说明

  • 质心选择:优先使用props.weighted_centroid(基于图像强度加权),对于内部强度不均的类圆形细胞,比几何质心更贴合实际中心。
  • 环的划分逻辑:完全匹配CellProfiler的逻辑——以对象最大径向距离为总长度,等分成N段,每个环是距离中心在对应区间内的所有对象像素,自然贴合对象的非完美圆形边界。
  • 性能优化:用np.digitize替代循环筛选像素,处理大对象或批量对象时速度提升明显。
  • 边界处理:通过修正ring_ids避免像素落在环区间外,同时处理空环情况(比如极小对象的边缘环无像素)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 06:35:49