当前位置:   article > 正文

论文笔记——Fast GPU-Enabled Color Normalization for Digital Pathology_structure-preserving color normalization and spars

structure-preserving color normalization and sparse stain separation for his

根据自己的理解写的,不对的地方请指正!

本篇文章主要讨论的是染色归一化技术

涉及两篇论文:

《Structure-Preserving Color Normalization and Sparse Stain Separation for Histological Images》和《Fast GPU-Enabled Color Normalization for Digital Pathology》

第一篇就是经典的SPCN 染色归一化技术,主要学习其中的基础理论知识和数学公式的推导。

第二篇是在第一篇的基础上做了一些改进,并加入了GPU加速。

后面会贴复现的代码和两者的对比。

本文截图均来自论文

为什么要染色归一化?

 大致来说就是以下几点:

  • 不同的染色试剂会引起颜色的差异(显而易见)
  • 同一种染色试剂,使用的量不同,也会导致颜色的差异
  • 同一种染色试剂,颜色会随着时间的推移而变化
  • 同一个切片,使用不同的扫描仪 也会得到不同的颜色

所以,使用染色归一化技术 可以增加模型的性能。

染色归一化过程

基本概念

 structure-preserving color normalization,SPCN 指的是结构保留式的染色归一化技术。

首先,我们先理解论文中出现的几个专业名词。

1. 染色分离  stain separation

原文中是这么说的,Thus, estimation of stain density maps and color appearances i.e., stain separation is central to many color normalization techniques including the proposed techniques presented here, which transforms the RGB channels of a histological image into an absorption or density map for each stain. 

我理解的大概意思就是可以把RGB图像拆解成 染色基础矩阵染色密度图

2.  比尔- 朗伯定律 Beer-Lambert law

原文,Stained tissue attenuates light in a certain spectrum depending on the type and amount of stain it has absorbed.

大概意思就是 染色的组织会衰减特定光谱中的光,具体取决于其吸收的染色剂的类型和数量。

数学推理过程

对于一张病理切片,其每个像素的RGB值可以称为整张图像的强度,用 符号I表示。

使用仪器扫描制作切片时,使用的光照强度 I_{0},假设为255。

所以其 相对光密度矩阵(观察矩阵)V 

 然后将V 进行染色分离,分为染色基础矩阵W 和染色密度图H ,其中W 的形状是m*r,H的形状是r*n,m是通道数 (RGB 三个通道),n是像素的个数,r是染色剂的数量

 整合公式,染色后的图像 就可以有以下公式得到

染色基础矩阵W 是通过无监督的稀疏字典学习 得到的,

染色密度图H 是通过稀疏非负矩阵分解(sparse non-negative matrix factorization, SNMF)得到,


上面是用到的一些基本公式,下面我们说一下SPCN。

SPCN是一种结构保留式的染色归一化技术,结构保留 就体现在染色密度上,

具体思路是 先选一张染色效果标准的图像,计算得出对应的 W_{t} 和H_{t},称为目标 target

然后将你需要染色归一化的图像 计算其对应的 W_{s} 和H_{s} ,称为源 source

为了将源图像的颜色向目标图像的颜色靠拢,先利用H_{t} 对H_{s} 进行正则化,其中 RM表示99%分位点。

然后,保留了源图像的染色密度,相当于保留了源图像的结构,只更换了染色基础矩阵。

注意:这里是W_{t}

 最后,将染色后的光密度图 恢复

 具体流程图如下:

SPCN缺点

1. SPCN 在颜色基础估计中偶尔会出现错误,会给WSI的背景提供彩色色调

具有显著背景部分的图像,这在极端情况下导致标准化后背景中的强烈色调。

2. 提取染色颜色原型的不一致:当由于少数非常暗的细胞核或大比例的浅色背景导致一种染色缺乏密度变化时。

 在一种染色占主导地位的情况下,SPCN 会导致中间空白处出现颜色。

3. 无意的染色交换:得到的染色密度Hs在两种颜色基础W中交换。

 由于两种染色中都存在显著的蓝色成分,SPCN显示出染色颜色基础的交换。

GPU加速

第二篇论文是改进了一些SPCN的缺点,并使用了GPU加速

具体操作如下:

1. 修改i0,取大于每个通道220像素的前100,000个,并取80%位置的值

2. SPCN是对每个patch独立处理,采用全部非白区域(小于220)的方差,并取非白区域的99%位置的值

3. SPCN使用蓝色通道的中值作为W,改进后利用红色和蓝色两个通道的差异来选选取W

4. 找最多20个非白区域代替整体,提升效率

5. 少量加速,纵向读patch

6. 使用所有patch 99%位置值的中位数

代码

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # @File : SPCN.py
  4. # @Time : 2023/8/7
  5. # @Author : gzz
  6. # @Description : 提取染色参数
  7. import numpy as np
  8. import pickle
  9. from multiprocessing import Pool
  10. import spams
  11. import cv2
  12. import os
  13. import openslide
  14. def intensity_norm(img_array, p=None):
  15. """
  16. 亮度归一化,图片95%亮度位置拉伸到255
  17. :param img_array: 需要亮度拉伸的图片
  18. :param p: 拉伸阈值
  19. :return: 亮度拉伸后的图片
  20. """
  21. if p:
  22. img_array = np.clip(img_array * 255.0 / p, 0, 255).astype(np.uint8)
  23. else:
  24. p = np.percentile(img_array, 95)
  25. img_array = np.clip(img_array * 255.0 / p, 0, 255).astype(np.uint8)
  26. return img_array
  27. def getParameter(img, mask=None):
  28. V = getV(img, mask)
  29. W = getW(V)
  30. H = getH(V, W)
  31. return W, H
  32. def getV(img, mask=None):
  33. if mask is not None:
  34. V0 = img[mask == 255].T
  35. V0[V0 == 0] = 1
  36. V0 = np.log(255 / V0)
  37. else:
  38. I0 = img.reshape((-1, 3)).T
  39. I0[I0 == 0] = 1
  40. V0 = np.log(255 / I0)
  41. return V0
  42. def getW(V):
  43. W = spams.trainDL(np.asfortranarray(V), K=2, lambda1=0.01, iter=5000, mode=2,
  44. modeD=0, posAlpha=True, posD=True, verbose=False, numThreads=1)
  45. W = W / np.linalg.norm(W, axis=0)[None, :]
  46. if W[0, 0] < W[0, 1]:
  47. W = W[:, [1, 0]]
  48. return W
  49. def getH(V, W):
  50. H = spams.lasso(np.asfortranarray(V), np.asfortranarray(W), mode=2, lambda1=0.03, pos=True,
  51. verbose=False, numThreads=1).toarray()
  52. return H
  53. if __name__ == '__main__':
  54. img_ds32=cv2.imread(path)
  55. img_ds32 = cv2.cvtColor(img_ds32, cv2.COLOR_BGR2RGB)
  56. img_lashen = intensity_norm(img_ds32)
  57. Ws, Hs = getParameter(img_lashen)

GPU加速的代码 大家自己想想怎么改,我懒的写了,以后补上

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/953944
推荐阅读
相关标签
  

闽ICP备14008679号