Python第三方库之MedPy

news2024/12/22 20:11:53

1.MedPy简介

MedPy 是一个图像处理库和针对医学(如高维)图像处理的脚本集合,此处主要讨论利用该库计算常见的医学图像分割任务评价指标,如Dice、Jaccard、Hausdorff Distance、Sensitivity、Specificity、Positive predictive value等。

论文表格的表头一般使用评价指标的英文全称首字母大写简写,如PPV代表阳性预测值,故此处也给出。

  • Dice相似系数(Dice Similarity Coefficient,DSC)或Dice系数(Dice Coefficient,DC)

    最常用的一项评价指标,用于有效衡量分割算法预测标签与真实标注标签的空间重叠程度,其对应值越大表示分割精度越高。
    D C = 2 ∣ A ∩ B ∣ ∣ A ∣ + ∣ B ∣ DC=\frac{2|A\cap B|}{|A|+|B|} DC=A+B2AB

  • Jaccard相似系数(Jaccard Similarity Coefficient,JSC)或Jaccard系数(Jaccard Coefficient,JC)

    与 Dice 相似系数指标相似,也是一种衡量两幅图像相似程度的指标,其由实际分割结果与真实标签的交集同二者并集的比值得出,反映了分割方法的准确程度,其值越高,分割结果越准确。

  • 豪斯多夫距离(Hausdorff distance,HD)

    表示预测分割区域边界与真实肿瘤区域边界之间的最大距离,其值越小代表脑肿瘤边界分割误差越小、质量越好。
    d H ( X , Y ) = max ⁡ { d X Y , d Y X } = max ⁡ { max ⁡ x ∈ X mind ⁡ y ∈ Y ( x , y ) , max ⁡ y ∈ Y min ⁡ x ∈ X d ( x , y ) } d_H(X, Y)=\max \left\{d_{X Y}, d_{Y X}\right\}=\max \left\{\max _{x \in X} \operatorname{mind}_{y \in Y}(x, y), \max _{y \in Y} \min _{x \in X} d(x, y)\right\} dH(X,Y)=max{dXY,dYX}=max{xXmaxmindyY(x,y),yYmaxxXmind(x,y)}

  • 95% 豪斯多夫距离(95% Hausdorff distance,HD95)

    为了排除一些离群点造成的不合理距离,保持整体数值稳定性,一般选择从小到大排名前 95%的距离作为实际豪斯多夫距离,称之为 95% 豪斯多夫距离。

  • 灵敏度(Sensitivity)

    也称真阳性率(True Positive Rate)和召回率(Recall),表示预测为正的肿瘤标签占真实肿瘤标签的比例,其值越大,漏检率越低。

  • 特异度(Specificity)

    也称真阴性率,表示预测为正的背景标签占所有真实背景标签的比例,其值越高则误诊率越低。

  • 阳性预测值(Positive Predictive Value,PPV)

    也称精确度,指在所有样本的预测结果中,真阳性占所有阳性样本的比例,其值越大越好。

2.MedPy安装

medpy安装较为简单,此处以Ubuntu 18.04.5 LTS系统的root用户为例,其他情况详见参考文献安装即可。

为了启用graph-cut包,我们需要安装下列软件包

sudo apt-get install libboost-python-dev build-essential

然后使用阿里云镜像源高速安装medpy

sudo pip install medpy -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

3.MedPy常用函数

3.1 medpy.io.load(image)

加载图像并返回包含图像像素内容以及头部对象的 ndarray

import os
from medpy.io import load,save
# 文件夹路径和文件名
dirname="/dataset/RSNA_ASNR_MICCAI_BraTS2021_TrainingData_16July2021/BraTS2021_00000/"
basename="BraTS2021_00000_seg.nii.gz"
full_path=os.path.join(dirname,basename)
# 加载脑肿瘤标记图像返回图像数据数组和头部信息
image_data, image_header = load(full_path)
print("图像数据类型为{},图像数据形状为{}".format(type(image_data),image_data.shape))

在这里插入图片描述

# 获取一个切片数组
slice_0=image_data[:,:,77]
print("切片数组的形状为{},切片数组的数据类型为{}".format(slice_0.shape,slice_0.dtype))

在这里插入图片描述

# 转置显示灰度图
plt.imshow(slice_0.T, cmap="gray")

在这里插入图片描述

# 将纵坐标设置为对数尺度,等宽区间数量设置为为8个绘制切片数组灰度直方图
plt.hist(image_data.flatten(), bins=8, log=True)

在这里插入图片描述

3.2 medpy.metric.binary.dc(result, reference)

计算二值图像之间的Dice系数(也称为索伦森指数)

首先编辑第三方库源代码在最后追加一行输出语句,保存退出后重启kernel。该输出语句指示此时调用的numpy定义,若调用dc函数前有输出,则表示调用依赖numpy的函数,否则调用依赖jax.numpy的兼容函数实现加速运算

vim /opt/conda/lib/python3.7/site-packages/medpy/metric/binary.py

然后定义统一的一个数组大小参数,最后使用魔术命令%%timeit评估CPU和GPU计算两种方法的运行效率

# 设置数组形状为10000*10000的元组
tup=(10000,10000)
  • 调用依赖numpy的函数

    %%timeit
    from medpy.metric.binary import dc
    import numpy as np
    # 设置伪随机数种子
    seed=np.random.seed(6)
    # 定义预测结果和真实标记数组
    predict=np.random.randint(0,4,size=tup)
    ground_truth=np.random.randint(0,4,size=tup)
    # 计算Dice相似系数
    dice1=dc(predict,ground_truth)
    print("Dice相似系数为{}".format(dice1))
    

在这里插入图片描述

  • 调用依赖jax.numpy的兼容函数

    %%timeit
    from medpy.metric.binary import dc
    import jax.numpy as numpy # 重载numpy定义使得dc函数底层可以加速计算
    from jax import random
    # 设置伪随机数种子
    rng1=random.PRNGKey(1)
    rng2=random.PRNGKey(2)
    # 定义预测结果和真实标记数组
    predict=random.randint(key=rng1,shape=tup,minval=0,maxval=4)
    ground_truth=random.randint(key=rng2,shape=tup,minval=0,maxval=4)
    # 计算Dice相似系数
    dice2=dc(predict,ground_truth)
    print("Dice相似系数为{}".format(dice2))
    

在这里插入图片描述

3.3 medpy.metric.binary.jc(result, reference)

计算两个图像中二值对象间的Jaccard系数,下面通过两种方式计算

  • 直接调用第三方库函数计算jaccard系数
%%timeit
from medpy.metric.binary import jc
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=tup,minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=tup,minval=0,maxval=4)
# 直接计算Jaccard相似系数
jaccard=jc(predict,ground_truth)
print("Jaccard相似系数为{}".format(jaccard))

在这里插入图片描述

  • 通过Dice系数和Jaccard系数的如下关系推导计算

KaTeX parse error: Undefined control sequence: \nonumber at position 29: …c{Dice}{2-Dice}\̲n̲o̲n̲u̲m̲b̲e̲r̲ ̲

%%timeit
from medpy.metric.binary import dc
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=tup,minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=tup,minval=0,maxval=4)
# 通过Dice相似系数推导Jaccard相似系数
dice=dc(predict,ground_truth)
jaccard=dice/(2-dice)
print("通过Dice相似系数推导Jaccard相似系数为{}".format(jaccard))

在这里插入图片描述

  • 对比两种计算结果、源代码实现、运行效率可知,两种方式结果一样但通过Dice系数推导Jaccard系数运行效率更高,其原因是将一个统计非零值的 O ( n ) O(n) O(n)时间复杂度的函数替换成了 O ( 1 ) O(1) O(1)时间复杂度的简单推导。

3.4 medpy.metric.binary.hd(result,reference,voxelspacing=None,connectivity=1,)

计算两个图像中二值对象之间的(对称)豪斯多夫距离(HD)。它被定义为对象之间的最大表面距离。

%%timeit
from medpy.metric.binary import hd,hd95
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算豪斯多夫距离
hausdorff_distance=hd(predict,ground_truth)
print("豪斯多夫距离为{}".format(hausdorff_distance))

在这里插入图片描述

3.5 medpy.metric.binary.hd95(result,reference,voxelspacing=None,connectivity=1,)

计算两个图像中二值对象之间的(对称)豪斯多夫距离 (HD) 的第 95 个百分位数。与豪斯多夫距离相比,该指标对于小异常值稍微稳定一些,通常用于生物医学分割挑战。

%%timeit
from medpy.metric.binary import hd,hd95
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算95%豪斯多夫距离
hausdorff_distance95=hd95(predict,ground_truth)
print("95%豪斯多夫距离为{}".format(hausdorff_distance95))

在这里插入图片描述

3.6 medpy.metric.binary.recall(result, reference)

返回召回率

%%timeit
from medpy.metric.binary import recall
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算召回率/灵敏度/真阳性率
sensitivity=recall(predict,ground_truth)
print("召回率/灵敏度/真阳性率为{}".format(sensitivity))

在这里插入图片描述

3.7 medpy.metric.binary.sensitivity(result, reference)

返回灵敏度,内部实现直接调用recall

%%timeit
from medpy.metric.binary import sensitivity
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算召回率/灵敏度/真阳性率
recall=sensitivity(predict,ground_truth)
print("召回率/灵敏度/真阳性率为{}".format(recall))

在这里插入图片描述

3.8medpy.metric.binary.true_positive_rate(result, reference)

返回真阳性率,内部实现直接调用recall

%%timeit
from medpy.metric.binary import true_positive_rate
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算召回率/灵敏度/真阳性率
sensitivity=true_positive_rate(predict,ground_truth)
print("召回率/灵敏度/真阳性率为{}".format(sensitivity))

在这里插入图片描述

3.9medpy.metric.binary.specificity(result, reference)

返回特异度

%%timeit
from medpy.metric.binary import specificity
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算特异度/真阴性率
tnr=specificity(predict,ground_truth)
print("特异度/真阴性率为{}".format(tnr))

在这里插入图片描述

3.10medpy.metric.binary.true_negative_rate(result, reference)

返回真阴性率

%%timeit
from medpy.metric.binary import true_negative_rate
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算特异度/真阴性率
specifity=true_negative_rate(predict,ground_truth)
print("特异度/真阴性率为{}".format(specifity))

在这里插入图片描述

3.11medpy.metric.binary.precision(result, reference)

返回精确度

%%timeit
from medpy.metric.binary import precision
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算精确度/阳性预测值
Precision=precision(predict,ground_truth)
print("精确度/阳性预测值为{}".format(Precision))

在这里插入图片描述

3.12 medpy.metric.binary.positive_predictive_value(result, reference)

返回阳性预测值

%%timeit
from medpy.metric.binary import positive_predictive_value
import jax.numpy as numpy
from jax import random
# 设置伪随机数种子
rng1=random.PRNGKey(1)
rng2=random.PRNGKey(2)
# 定义预测结果和真实标记数组
predict=random.randint(key=rng1,shape=(50,50),minval=0,maxval=4)
ground_truth=random.randint(key=rng2,shape=(50,50),minval=0,maxval=4)
# 计算精确度/阳性预测值
ppv=positive_predictive_value(predict,ground_truth)
print("精确度/阳性预测值为{}".format(ppv))

在这里插入图片描述

3.13 medpy.io.save(arr, filename, hdr=False, force=True, use_compression=False)

使用“hdr”中编码的信息将图像“arr”保存为文件名。目标图像格式由“文件名”后缀确定。如果“force”参数设置为 true,以静默方式覆盖已存在的映像。否则将引发错误。

import os
from medpy.io import load,save
# 文件夹路径和文件名
dirname="/dataset/RSNA_ASNR_MICCAI_BraTS2021_TrainingData_16July2021/BraTS2021_00000/"
basename="BraTS2021_00000_seg.nii.gz"
full_path=os.path.join(dirname,basename)
# 加载脑肿瘤标记图像返回图像数据数组和头部信息
image_data, image_header = load(full_path)
# 将图像数据保存为BraTS2021_00000_seg.nii
save(image_data,"BraTS2021_00000_seg.nii")

在这里插入图片描述

4.参考文献

  • MedPy — MedPy 0.4.0 documentation

  • Precision_and_recall

  • Sensitivity_and_specificity

  • Confusion_matrix#Table_of_confusion

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker部署的redis集群 添加节点(扩容)

上篇博文完成了在 docker 中部署 redis 多主多从集群:点这里 这篇博文说一下如何在集群基础上继续添加节点,也就是给集群扩容 博文中的命令出现的 111.111.111.111 均换成实际 IP 执行 创建要添加的一主一从容器 这里创建一个6377主节点和一个6378从节…

ArgoDB 5.1 正式发布:多模融合、实时分析和数据安全多重升级

Transwarp ArgoDB是星环科技自主研发的高性能分布式分析型数据库,在PB级数据量上提供极致的数据分析能力。ArgoDB支持标准SQL语法和分布式事务,提供高并发高速数据写入、复杂查询、多模分析、数据联邦、隐私计算和动态脱敏等能力。基于星环科技ArgoDB数据…

怎么自由裁剪图片大小?分享一款在线图片编辑工具

工作的时候常常需要用图片编辑工具把图片裁剪为我们想要的大小,但下载处理图片软件又耗费时间,那么有没有比较快捷的修改图片的方法呢?其实我们可以用在线图片处理(在线ps 图片编辑制作工具 免费照片编辑器_压缩图)工具…

日期插件(默认显示当前日期)---年月

方法&#xff1a;加载页面时将当前日期赋值 <!-- 选择年月--> <div class"form-group"><label class"col-sm-2 control-label is-required">时间&#xff1a;</label><button id"bin0"><< </button&g…

Nvidia 驱动安装

由于使用unreal engine editor 开发,需要安装nvidia 独显驱动,遇到各种坑,在此记录,方便自己以后再次遇到,也希望能帮助他人辟坑 系统: Ubuntu18.04 显卡:Geforce GTX 1650 UE版本:5.1.0 1. 自动安装 sudo ubuntu-drivers devices 推荐安装470 sudo ubuntu-drivers autoi…

Redis哨兵模式原理剖析,监控、选主、通知客户端你真的懂了吗?

哨兵启动后只指定了master的地址&#xff0c;要想知道整个集群中完整的拓扑关系怎么做呢&#xff1f; 哨兵每隔10秒会向每个master节点发送 info 命令&#xff0c; info 命令返回的信息中&#xff0c;包含了主从拓扑关系&#xff0c;其中包括每个slave的地址和端口号。有了这些…

[附源码]计算机毕业设计汽配管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

10. 获取操作系统版本和位数

1. linux如何查看系统版本 (1) 查看系统版本&#xff1a;uname -a (2) 查看内核版本信息&#xff1a;less /proc/version (3) 查看发行版本信息&#xff1a;less /etc/issue (4) 查看发行版详细信息&#xff1a;lsb_release -a 2. 怎么查看linux是32位还是64 系统 (1) getco…

Web3中文|以太坊创始人V神:关注技术,而不是价格

全球第二大数字货币交易所 FTX 轰然倒下&#xff0c;可以说是牵连甚广&#xff0c;不止是小资族&#xff0c;不少资深玩家都在这次事件中亏损数百、数千万美元。Solana、BlockFi等都在此次事件中受到巨大冲击。 基于BNB Chain的去中心化金融&#xff08;DeFi&#xff09;协议A…

Mac 上好用的远程桌面软件:Splashtop

市场分析表明&#xff0c; Mac电脑的市场份额正在增加 。在相关新闻中&#xff0c;全球远程桌面软件市场正在经历巨大的增长 。 远程桌面软件允许你通过互联网连接到一个特定的计算机&#xff0c;并用一个单独的设备来控制它。然后你就可以使用任何应用程序&#xff0c;访问主…

笔试强训48天——day23

文章目录一. 单选1.下面程序段的时间复杂度为&#xff08;&#xff09;2. 下列关于线性链表的叙述中&#xff0c;正确的是&#xff08; &#xff09;3. 下列描述的不是链表的优点是&#xff08; &#xff09;4. 向一个栈顶指针为h的带头结点的链栈中插入指针s所指的结点时,应执…

纺织进入“寒冬”,纺织企业利用APS生产排产加强生产管

进入11月&#xff0c;对于纺服产业链而言&#xff0c;大体“金九银十”的旺季订单已经结束。实际上&#xff0c;经历了前三季度的疲弱表现&#xff0c;市场整体已经对四季度缺乏信心。的确从整个下游行业来看&#xff0c;纺织出口形势依然严峻&#xff0c;预计11月份纺织行业也…

图像增强之灰度变换

前言 图像增强是图像处理常用最常用的方法&#xff0c; 目录前言引言为什么进行空间域增强什么是图像增强如何进行图像增强空间域增强灰度变换线性变换简单的黑白转换灰度拉伸分段线性变换非线性变换对数变换幂次变换直方图均衡引言 为什么进行空间域增强 什么是图像增强 按…

天宇优配|多家房企发布再融资预案,最牛地产股九连板

多家上市房企抢先发布再融资预案&#xff1b;氢能工业车辆产线有新进展&#xff0c;燃料电池本钱或有下降空间。 房地产板块掀涨停潮 12月5日&#xff0c;房地产板块再度走高&#xff0c;掀起涨停潮&#xff0c;阳光股份、招商积余、沙河股份、粤宏远A等涨停&#xff1b;所属地…

uView教程-骨架屏搭建 #低代码 #小程序 #uView

当小程序没有加载完时会出现一个基础的骨架效果&#xff0c; 页面加载完之后骨架会消失掉&#xff0c; 这个效果怎么做的呢&#xff1f; 今天由我来带领大家学习如何使用骨架屏&#xff0c; 在guiplan低代码开发工具中&#xff0c; 选中要添加骨架的元素&#xff0c; 比如…

Lecture1:从图像分类引出概念

目录 1.我们如何处理图像分配这个任务 2.图像分类远古方法----利用曼哈顿距离&#xff1a;L1距离 3.图像分类远古方法----利用欧几里得距离&#xff1a;L2距离 4.超参数 1.我们如何处理图像分配这个任务 我们要给计算机一张图片&#xff0c;让它识别出这是一只猫&#xff1…

【区块链 | 预言机】从零开始使用Chainlink预言机(2)- 智能合约中使用更安全的随机数-代码实战

智能合约中使用更安全的随机数(代码实战篇) Chainlink最近推出一款革命性的产品,VRF—Verifiable Random Function可验证随机数,给智能合约带来了真正安全的随机数。本文我们就来介绍一下如何在智能合约中使用VRF吧。 我们先简要介绍一下Chainlink VFR的工作流程。 首先,…

科普:什么是ChatGPT?(文末有彩蛋)

科普&#xff1a;什么是ChatGPT&#xff1f;(文末有彩蛋) ChatGPT介绍 ChatGPT是OpenAI开发的一个大型预训练语言模型。它是GPT-3模型的变体&#xff0c;GPT-3经过训练&#xff0c;可以在对话中生成类似人类的文本响应。ChatGPT 旨在用作聊天机器人&#xff0c;我们可以对其进…

STM32F103定时计算方法

//TIM2时钟配置 void TIM2_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器TIM2初始化 TIM_TimeBaseStructure.TIM_Period 499; //装载值(4991)500us TIM_TimeBaseStructure.TIM_Prescaler 63; //预分频&am…

WuThreat ITDR 可以快速构建多场景的身份认证与威胁检测能力

什么是WuThreat身份安全云&#xff1f; WuThreat 身份安全云融入身份认证和身份威胁检测与响应&#xff08;ITDR&#xff09;的技术&#xff0c;快速为企业的Web、APP等业务构建一体化多身份场景的认证与安全解决方案。WuThreat在身份认证与威胁检测领域是全球的创新领导者&am…