PNG、JPG如何转Dicom(dcm),那些年我踩过的坑(Python版)

这篇具有很好参考价值的文章主要介绍了PNG、JPG如何转Dicom(dcm),那些年我踩过的坑(Python版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        Dicom作为医学影像的常见数据格式,是每个深耕于医疗AI的同学无法跳过的一个坑。虽然我只是一名扎根于算法部署方面的小白。但是也不可避免地接触到这类数据。这不,最近接到算法同学给出的算法,需要我自己找公开数据集进行测试。可是Dicom数据集并不常见(PS:测了1000张还嫌不够,大无语),因此只能将目光聚焦于PNG、JPG类型的数据集(直接用PNG、JPG训练的除外)。

        但是PNG、JPG类型的数据转Dicom并不容易,一不小心你就会收获“非标准Dicom”,网上的一些教程我也尝试了,很遗憾:转出来的Dicom不是黑不溜秋,就是无法识别。要么就是c++写的,编译来编译去,令人心烦。也尝试过用现成的Dicom数据,然后使用PNG、JPG的Data替换其中的Pixel Data。但是都无功而返!

        于是乎,我潜心钻研(东Copy西Copy),完成了这份python版本的PNG、JPG转Dicom。

目录

1.Dicom数据格式简介

2.PNG、JPG转Dicom(以PNG为例)

3.进一步完善Dicom 

4.结果展示


1.Dicom数据格式简介

        首先,在你尝试着将PNG、JPG类型的数据转换成Dicom数据之前,你可能需要浅浅了解一下Dicom数据的基本格式。

png转dicom,python,人工智能,健康医疗

(1)preamble(前导):不重要,主要是为了向后兼容性和可扩展性而保留的若干个字节。

(2)prefix(前缀):不重要,主要是确认该文件是否符合DICOM标准。前导和前缀是可选的,对于DICOM文件来说,并不是必需的。

(3)File Meta Information(文件元信息头):重要!!!文件元信息头是DICOM文件的必要部分,其中包含了一些关键信息,如DICOM版本号、文件字节顺序、数据元素编码方式等。

(4)DataElements(数据元素):重要!!!是DICOM文件中包含的实际医学图像和相关信息的部分。

2.PNG、JPG转Dicom(以PNG为例)

        OK,知道了Dicom的数据结构,我们就能够针对主要的部分来转换我们的PNG、JPG。废话不多说,上代码!如果你不想看接下来的分析,你只需要修改main函数中的路径即可。

import os
import pydicom
from PIL import Image

def png_to_dicom(input_png_path, output_dcm_path, patient_name="Anonymous", study_description="PNG to DICOM"):
    for fileNames in os.listdir(input_png_path):
        input_filename = os.path.basename(fileNames).split('.')[0]
        output_filename = input_filename + ".dcm"
        input_filepath = input_png_path + fileNames
        output_dcmpath = output_dcm_path + output_filename

        # 读取PNG图像
        img = Image.open(input_filepath)

        # 将PNG图像转换为灰度图像(单通道)
        pixel_array = img.convert("L")

        # 创建一个空的FileDataset对象,并添加DICOM数据集元素
        ds = pydicom.dataset.FileDataset(output_dcm_path, {}, file_meta=pydicom.dataset.Dataset())  # 创建文件元信息头对象
        # 添加DICOM文件元信息头
        ds.file_meta.FileMetaInformationGroupLength = 184
        ds.file_meta.FileMetaInformationVersion = b'\x00\x01'
        ds.file_meta.MediaStorageSOPClassUID = '1.2.840.10008.5.1.4.1.1.1.1'
        ds.file_meta.MediaStorageSOPInstanceUID = '1.2.410.200048.2858.20230531153328.1.1.1'
        ds.file_meta.TransferSyntaxUID = '1.2.840.10008.1.2'
        ds.file_meta.ImplementationClassUID = '1.2.276.0.7230010.3.0.3.5.4'
        ds.file_meta.ImplementationVersionName = 'ANNET_DCMBK_100'

        # 添加DICOM数据集元素
        ds.PatientName = patient_name
        ds.StudyDescription = study_description
        ds.Columns, ds.Rows = img.size
        ds.SamplesPerPixel = 1
        ds.BitsAllocated = 8
        ds.BitsStored = 8
        ds.HighBit = 7
        ds.PixelRepresentation = 0
        # 数据显示格式
        ds.PhotometricInterpretation = "MONOCHROME2"
        ds.PixelData = pixel_array.tobytes()  # 直接使用灰度图像的字节数据

        # 保存DICOM数据集到文件
        ds.is_little_endian = True
        ds.is_implicit_VR = True  # 使用隐式VR

        ds.save_as(output_dcmpath)
        print(output_dcmpath)


if __name__ == "__main__":
    # 输入PNG图像路径和输出DICOM图像路径
    input_png_path = "Your_Input_PNG_Path"
    output_dcm_path = "Your_Output_Dicom_Path"

    # 将PNG转换为DICOM
    png_to_dicom(input_png_path, output_dcm_path)

让我们来详细分析一下这部分代码:

(1)FileMetaInformationGroupLength:指定File Meta Information部分的长度,随意啦,别太离谱就行。

(2)FileMetaInformationVersion:表示File Meta Information部分的版本号。

(3)MediaStorageSOPClassUID:定义了影像的数据类型,每种类型有唯一的UID标识。如“1.2.840.10008.5.1.4.1.1.1.1”代表的是“Digital X-Ray Image Storage - For Presentation”

(4)MediaStorageSOPClassUID:唯一标识一个特定的影像数据实例。

(5)TransferSyntaxUID:表示DICOM图像数据的传输语法,它指定了数据在网络传输中的编码方式。每种方式有唯一的UID标识,比如“1.2.840.10008.1.2”代表的是“Implicit VR Little Endian”。

(6)ImplementationClassUID :用于标识实现DICOM标准的应用程序或设备的唯一标识符。

(7)ImplementationVersionName: 实现DICOM标准的应用程序或设备的版本名称或标识。

        看到这里你可能会问“你这乱七八糟的一堆数字,我怎么知道什么意思?” 聪明的我早就想到了,首先随便选一张标准的Dicom数据,然后执行如下代码:

import pydicom
dataset = pydicom.dcmread("Your_Dicom_Path", force=True)
print(dataset.file_meta)

        然后你会看到下面一堆信息,如果你想更换MediaStorageSOPClassUID和TransferSyntaxUID,那你就要自己去查对应的UID喽,所以以下内容我不建议你自己换,除非你知道你要干嘛:

png转dicom,python,人工智能,健康医疗

3.进一步完善Dicom 

         哈哈哈哈,没想到还有吧!实际上,通过第2步,你已经可以获得一张用于展示的Dicom数据格式了。但是仅此而已,如果你想要做算法或者跟我一样,去验证别人的算法。那么,这一步是必不可少的。

        在第2步中,我们为新的Dicom添加了File Meta Information(文件元信息头)和部分DataElements(主要是Pixel Data)。因此这份Dicom是可以正常被读取、浏览的。但是,如果是用于算法训练或者验证算法,是需要确保这份Dicom数据的唯一性的。

        为了便于理解,确保Dicom数据唯一性的代码,我另起了一个新的py文件:

import os
import pydicom

# 源文件夹和目标文件夹路径
source_folder = 'Your_Input_Dicom_Path'
target_folder = 'Your_Output_Dicom_Path'

patient_pid = 20230726001
accession_number = 202307261001
study_uid = 2023072620001
seriesNumber = 1
seriesInstanceUID = "1.2.410.200048.2858.20230529094313.1"
modality = "CR"
pixelSpacing = [0.160145, 0.160114]
instanceNumber = 1
bodyPartExamined = "CHEST"

# 遍历源文件夹中的文件
for filename in os.listdir(source_folder):
    if filename.endswith('.dcm'):
        # 构建源文件路径和目标文件路径
        source_file = os.path.join(source_folder, filename)
        target_file = os.path.join(target_folder, filename)

        # 加载源DCM文件
        dcm_data = pydicom.dcmread(source_file, force=True)

        # 添加患者PID、Accession Number和Study UID等信息
        dcm_data.PatientID = str(patient_pid)
        dcm_data.AccessionNumber = str(accession_number)
        dcm_data.StudyInstanceUID = str(study_uid)
        dcm_data.SeriesNumber = seriesNumber
        dcm_data.SeriesInstanceUID = seriesInstanceUID
        dcm_data.Modality = modality
        dcm_data.PixelSpacing = pixelSpacing
        dcm_data.BodyPartExamined = bodyPartExamined
        dcm_data.InstanceNumber = instanceNumber

        # 将文件名作为患者名
        file_name_without_extension = os.path.splitext(filename)[0]
        dcm_data.PatientName = file_name_without_extension

        # 保存修改后的DCM文件到目标文件夹
        dcm_data.save_as(target_file)

        # 递增计数器
        patient_pid += 1
        accession_number += 1
        study_uid += 1
    else:
        print("error!")

同样的,我们来详细解析以下这部分代码 。

(1)patient_pid:患者的唯一标识符,你怎么开心怎么写。

(2)accession_numbe:分配给患者检查的唯一标识号码,唯一地标识特定的检查或一组医学影像,你怎么开心怎么写。

(3)study_uid:对应医学影像研究的ID,你怎么开心怎么写。

(4)seriesNumber:标识图像所属系列的编号,建议按照我这个来。

(5)seriesInstanceUID:唯一标识一个影像系列,建议按照我这个来,或者你找一张标准的Dicom,参考它怎么写。

(6)modality:用于获取图像的影像学模态,建议按照我这个来,或者你找一张标准的Dicom,参考它怎么写。

(7)pixelSpacing:像素在行和列方向上的物理间距,建议按照我这个来,或者你找一张标准的Dicom,参考它怎么写。

(8)instanceNumber:分配给图像中个别实例的唯一编号,通常用于区分一个系列中的不同图像,你怎么开心怎么写。

(9)bodyPartExamined:检查部位,根据实际写,你也可以不写。

4.结果展示

        需要说的是,PNG、JPG亦或是其它类型的数据,在转成Dicom的过程中不可避免地会出现一定的损失。如果在Dicom数据充足的情况下,无论是算法训练还是验证,都建议使用Dicom(直接用PNG训练的除外)。PNG、JPG转Dicom实属无奈之举啊!

png转dicom,python,人工智能,健康医疗文章来源地址https://www.toymoban.com/news/detail-723024.html

到了这里,关于PNG、JPG如何转Dicom(dcm),那些年我踩过的坑(Python版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【代码 | 格式转换】Dicom转png

     【相关链接】 How To Convert a DICOM Image Into JPG or PNG - PYCAD、中文 【相关知识】 1、PNG和JPEG(JPG)格式各有优缺点,根据不同的应用场景可以选择不同的格式。 从保留图片信息的完整性和减少信息丢失的角度来看,PNG格式比JPEG格式更好。 PNG 是一种无损压缩格式,可以保留图像

    2024年02月08日
    浏览(48)
  • 我的创作纪念日——你知道这5年我是怎么过的吗?

    第一篇博客记忆犹新,是与CSDN结下了第一缕缘分。 前期的博客都被打上“改进质量”的标签,到后来的高质量文字的撰写,见证了自己撰写能力的一步一步地提高,正可谓不积跬步无以至千里。 如下图所示: 这5年,在CSDN中我都干了些什么? 实战项目中的经验分享 日常学

    2024年02月09日
    浏览(44)
  • 微信小程序如何实现自定义导航栏、导航栏手机适配(获取导航栏、状态栏高度和胶囊位置)以及踩过的坑

    背景:不用官方默认的导航栏,想用自己自定义的 实现效果: :顶部状态栏、顶部导航栏、顶部状态导航栏、胶囊 原理: 自定义导航栏无非就是求得导航栏高度,并让内容容器垂直方向居中于导航栏高度 1.获取手机系统状态栏高度 2.获取胶囊位置(包括高度) 3.求得

    2024年03月12日
    浏览(62)
  • MongoDB踩过的坑

    目录 ‘mongodump‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件 备份数据库 启动MongoDB服务 可视化工具:MongoDB Compass 由于目标计算机积极拒绝,无法连接  BSONObj size: xxxx is invalid. Size must be between 0 and 16793600 (16MB) mongodb默认时没有mogodump.exe工具和mongorestore.exe工具

    2024年02月16日
    浏览(45)
  • 安装whisper模块踩过的坑

    如果你和我一样,通过以下命令安装whisper 但却出现了 fatal: unable to access \\\'https://github.com/openai/whisper.git/\\\': OpenSSL SSL_read: Connection was reset, errno 10054 那么只需要 在运行 pip install 之前在运行以下的命令,再次重新 pip install ... 即可 原因: 安装whisper需要先安装rust环境依赖。 官方在

    2024年02月15日
    浏览(48)
  • Java将JPG/PNG图片转换为WEBP格式,以及WEBP转换成JPG/PNG格式

    越来越多的网站采用了webp格式的图片,webp占用空间小,传送更快,画质不降低。经常会遇到图片格式转换的需求,我们可以借助第三方的包,通过Java实现来PG/PNG图片转换为WEBP格式,以及WEBP转换成JPG/PNG格式。 1.maven项目依赖 在pom.xml加入下面的内容 2.代码分享

    2024年02月08日
    浏览(47)
  • 记录一下postman汉化踩过的坑

    postman安装后会频繁的进行更新,每次更新后我们会发现,postman界面就会回到原来的英文界面。这是由于汉化包的版本和postman的版本不一致导致的。 postman汉化包的更新滞后于postman的更新,如果要成功将postman汉化,就要下载以前的版本保证postman的版本和汉化包的版本一致。

    2024年02月15日
    浏览(49)
  • Spark搭建日志,记录一些踩过的坑

    本人在Centos中使用三个虚拟机(node1,node2,node3)搭建hadoop与Spark分布式环境(具体见后记中的Hadoop安装),本文记录一些踩过的坑 解决办法:sudo chown -R 用户名 /spark(spark或者hadoop所在目录) 原理:文件的初始所有者不是用户名(如root),要把spark目录的初始所有者更换为自

    2024年03月14日
    浏览(85)
  • 关于python的mediapipe库踩过的坑

      大家好,我是csdn的博主: lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主 lqj_本人擅长微信小程序,前端,vue,等方面的知识 https://blog.csdn.net/lbcyllqj?spm=1000.2115.3001.5343 哔哩哔哩欢迎关注: 小淼前端 小淼前端的个人空间_哔哩哔哩_bilibil

    2024年01月17日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包