第3章 常见细胞特征类型:形态、纹理、强度

做细胞分类,说白了就是跟特征打交道。

我记得刚入行那会儿,拿到一批宫颈细胞涂片,兴奋得不行,直接把所有能用上的特征全扔进模型。结果呢?训练时间长得离谱,分类准确率还没过70%。后来我才明白——特征不在多,在精。你得知道哪些特征对你的任务真正有用。

这一章,我带大家系统梳理一下细胞分类里最常见的三类特征:形态、纹理、强度。这是基础,也是关键。

3.1 形态特征——细胞的「骨架」

形态特征描述的是细胞的几何结构。你想想看,一个正常细胞和一个癌细胞,最直观的区别是什么?形状不一样嘛。

3.1.1 常用的形态特征

  • 面积:细胞或细胞核的像素面积。我经验里,核质比(核面积/细胞面积)是区分良恶性的黄金指标。
  • 周长:边界的总长度。不规则细胞通常周长更长。
  • 圆形度:(4π × 面积) / 周长²。值越接近1,形状越圆。癌细胞往往更不规则,圆形度低。
  • 离心率:拟合椭圆的焦距与长轴之比。反映细胞的拉长程度。
  • 凹凸性:凸包面积与细胞面积的比值。用于描述边界皱褶程度。

实战经验:我接手过一个肺癌细胞分类项目,一开始用了40多个形态特征,结果模型过拟合严重。后来只用核质比 + 圆形度 + 面积三个特征,准确率反而从82%提到91%。

3.1.2 形态特征提取示例

用Python和OpenCV提取形态特征,代码很直接:

import cv2
import numpy as np

# 假设mask是二值化的细胞分割结果
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
    area = cv2.contourArea(cnt)
    perimeter = cv2.arcLength(cnt, True)
    
    if area > 0:
        circularity = 4 * np.pi * area / (perimeter * perimeter)
    
    # 拟合椭圆
    if len(cnt) >= 5:
        ellipse = cv2.fitEllipse(cnt)
        (_, _), (major_axis, minor_axis), _ = ellipse
        eccentricity = np.sqrt(1 - (minor_axis / major_axis) ** 2)
    
    print(f"面积: {area:.1f}, 圆形度: {circularity:.3f}, 离心率: {eccentricity:.3f}")

3.2 纹理特征——细胞的「皮肤」

形态看的是轮廓,纹理看的则是内部细节。为什么会有纹理?因为细胞内部不是均匀的——细胞核染色质分布、胞浆颗粒度,都会形成纹理差异。

我做过一个尿沉渣图像分析项目。正常红细胞的纹理很均匀,但异常细胞(比如镰状红细胞)内部会出现明显的纹理斑块。光靠形态特征完全分不开,加上纹理特征后,效果立竿见影。

3.2.1 主流纹理特征方法

方法 核心思想 适用场景 注意点(我踩过的坑)
GLCM
灰度共生矩阵
统计像素对在某个距离和方向上的灰度共现频率 染色质分布、颗粒度 方向和距离参数非常敏感,我曾经因为距离固定为1错过很多细节
LBP
局部二值模式
比较中心像素与邻域像素的灰度大小 胞浆纹理、膜粗糙度 对旋转敏感,建议用旋转不变LBP
Gabor滤波器 多方向、多尺度的纹理检测 纤维状纹理、方向性纹理 计算量大,维数高,需要降维
Haralick特征 基于GLCM的14个统计量 通用纹理分析 有些特征高度相关,建议做特征选择

3.2.2 GLCM特征提取实战

scikit-image直接封装好了,免去手写矩阵的麻烦:

from skimage.feature import graycomatrix, graycoprops

# image为灰度图像
glcm = graycomatrix(image, distances=[1, 3, 5], 
                    angles=[0, np.pi/4, np.pi/2, 3*np.pi/4],
                    symmetric=True, normed=True)

# 常用特征
contrast = graycoprops(glcm, 'contrast')
dissimilarity = graycoprops(glcm, 'dissimilarity')
homogeneity = graycoprops(glcm, 'homogeneity')
energy = graycoprops(glcm, 'energy')
correlation = graycoprops(glcm, 'correlation')

# 打印距离=1,角度=0时的对比度
print(f"对比度: {contrast[0, 0]:.3f}")

我的建议:纹理特征提取前,记得先做灰度归一化。不同染色批次、不同摄像头导致的亮度差异,会把纹理特征带偏。我吃过这个亏——模型在实验室数据上表现完美,换到临床数据直接崩了,根源就是纹理特征被亮度干扰了。

3.3 强度特征——细胞的「色感」

强度特征,也叫灰度特征。它关注的是像素值的统计分布,比如细胞整体亮不亮、对比度高不高。你可能觉得这太简单了,但强度特征在某些场景下是区分的关键。

举个例子:HE染色切片里,细胞核染成深紫色,胞浆染成淡粉色。核浆之间的强度对比,直接反映染色质量和细胞状态。我参与过一个乳腺癌分级项目,核浆强度比这个单一特征,就把低级别和高级别分开了。

3.3.1 基础强度特征

  • 均值:像素灰度平均值。反映细胞整体亮度。
  • 标准差:灰度离散程度。反映细胞内对比度强弱。
  • 偏度:灰度分布对称性。正值表示分布偏向亮侧。
  • 峰度:分布尖锐程度。高峰度表示灰度集中在某个区间。
  • 分位值:10%、25%、75%、90%分位。用于抵抗异常值干扰。
  • 核浆强度比:核区域均值 / 胞浆区域均值。这个特征我百用不厌。

3.3.2 强度特征提取示例

import numpy as np
from skimage import measure

# cell_mask: 细胞区域二值图
# nucleus_mask: 细胞核区域二值图
# image: 原始灰度图

# 整个细胞区域
cell_pixels = image[cell_mask > 0]
mean_intensity = np.mean(cell_pixels)
std_intensity = np.std(cell_pixels)
skewness = np.mean((cell_pixels - mean_intensity) ** 3) / (std_intensity ** 3)
kurtosis = np.mean((cell_pixels - mean_intensity) ** 4) / (std_intensity ** 4)

# 核浆分离
nucleus_pixels = image[nucleus_mask > 0]
cytoplasm_pixels = image[(cell_mask > 0) & (nucleus_mask == 0)]

if len(nucleus_pixels) > 0 and len(cytoplasm_pixels) > 0:
    nuc_cyto_ratio = np.mean(nucleus_pixels) / np.mean(cytoplasm_pixels)
    print(f"核浆强度比: {nuc_cyto_ratio:.3f}")

3.4 三类特征对比与选择策略

特征类别 描述维度 计算复杂度 对噪声的敏感性 关键特点
形态特征 低(3-10维) 低 低(依赖分割质量) 可解释性最强,最直观
纹理特征 中(10-50维) 中 高(对光照敏感) 细节丰富,区分能力最强
强度特征 低(5-10维) 低 极高(亮度直接影响) 配合归一化使用,效果稳定

避坑指南:我曾经在提取纹理特征时踩过一个坑——直接在全图算GLCM,结果混入了大量背景像素的纹理,模型完全学偏了。正确的做法是:先用分割Mask提取细胞区域,再在区域内计算纹理特征。这个顺序千万别搞反。

3.5 特征提取流程总结

下面这张图概括了特征提取的整体流程,从图像输入到特征向量生成,每一步都要把控好:

细胞特征提取全流程 输入细胞图像 图像预处理(归一化+去噪) 细胞+核分割 三个方向同时提取 形态特征 面积/周长/圆形度/离心率 纹理特征 GLCM/LBP/Gabor/Haralick 强度特征 均值/标准差/偏度/核浆比 特征向量(模型输入) 实战建议:优先提取形态特征(低维稳健),再根据分类效果决定是否加入纹理和强度特征

流程图里讲得很清楚了:图像进来,先预处理,再分割,然后三路特征并行提取,最后汇成一个特征向量给模型。这个结构我用过很多次,稳定可靠。

一个实用技巧:我习惯在提取完特征后,先画一下特征分布直方图或者t-SNE降维可视化。如果两个类别的特征分布重叠严重,那这个特征加进去也是白搭。这一步虽然简单,但能省下后面调参的好多时间。

好,这一章我们就把形态、纹理、强度三类特征讲透了。记住一个原则:先从最稳健的特征入手(形态+基础强度),模型不够好再逐步加纹理。这才是工程思维,而不是一股脑堆特征。