【相关链接】
How To Convert a DICOM Image Into JPG or PNG - PYCAD、中文
【相关知识】
1、PNG和JPEG(JPG)格式各有优缺点,根据不同的应用场景可以选择不同的格式。
从保留图片信息的完整性和减少信息丢失的角度来看,PNG格式比JPEG格式更好。PNG是一种无损压缩格式,可以保留图像的每个像素的完整信息,并且不会引起压缩失真。因此,当需要在图像处理中保留最高质量的图像信息时,通常选择PNG格式。
相比之下,JPEG格式是一种有损压缩格式,压缩时会丢失图像的一些信息,导致图像质量下降。虽然JPEG格式的压缩比较高,文件大小比PNG格式小,但JPEG格式在图像处理中可能会导致信息丢失和质量下降。
总的来说,如果您需要在图像处理中保留最高质量的图像信息,则应选择PNG格式。如果文件大小比较重要,而图像质量不是最高优先级,则可以选择JPEG格式。
2、DICOM(Digital Imaging and Communications in Medicine)是医学图像和相关信息的标准格式。要读取DICOM文件,可以使用DICOM库,例如pydicom
虽然DICOM最初是为CT(计算机断层扫描)图像设计的,但它现在也广泛用于其他医学成像设备产生的图像,包括X射线片,核磁共振(MRI),超声波,PET等。
因此,DICOM格式的文件不一定是CT,也可以是X光片或其他医学成像设备的图像。DICOM格式为各种医学图像提供了一种标准的方式,使它们可以在不同的医学成像设备和软件之间交换和共享。
由.DCM转成.PNG时:DICOM格式的医学影像数据存储了大量的元数据和像素数据,而PNG格式的图像数据只包含像素数据。在转换过程中,需要注意DICOM数据可能包含了压缩编码,需要使用pydicom库进行解码。同时,由于DICOM文件中的像素值可能不是标准的8位灰度值,需要进行归一化处理,确保像素值的范围在0到255之间。
【代码记录】
1、使用pydicom读取DICOM文件信息
中间出现报错:UnicodeEncodeError: 'gbk' codec can't encode character '\xcd' in position 3694: illegal multibyte sequence因为有些Unicode字符无法编码
# -*- coding: utf-8 -*-
import pydicom
import sys
# 将输出编码格式设置为utf-8
sys.stdout.reconfigure(encoding='utf-8')
# 读取DICOM文件
ds = pydicom.dcmread('-0001-0001-0001-W4095L2047.DCM') # .dcm
# 打印DICOM数据集信息
print(ds.__repr__().encode('utf-8').decode('unicode_escape'))
(0018, 1050) Spatial Resolution DS: '0.143' 表示图像的空间分辨率为 0.143mm,空间分辨率是指在图像上相邻两个像素之间的物理距离。
(0028, 0030) Pixel Spacing DS: [0.1408399617591, 0.1408399617591]
Pixel Spacing
和Imager Pixel Spacing
都是描述像素之间间距的DICOM属性,但是它们描述的是不同的像素间距。
Imager Pixel Spacing
描述的是数字图像显示设备(imager)中的像素间距,它是一个由两个数字组成的列表,第一个数字表示行间距,第二个数字表示列间距,单位是mm。
Pixel Spacing
描述的是图像平面(pixel array)中的像素间距,它是一个由两个数字组成的列表,第一个数字表示行间距,第二个数字表示列间距,单位也是mm。在本例中,
Imager Pixel Spacing
的值是[0.143, 0.143]
,表示数字图像显示设备中相邻像素的行间距和列间距都是0.143mm。而Pixel Spacing
的值是[0.1408399617591, 0.1408399617591]
,表示图像平面中相邻像素的行间距和列间距都是0.1408399617591mm。可以看出,两者的值略有不同,可能是由于数字图像显示设备的插值等因素导致的差异。
2、提取多文件夹下.DCM文件到指定统一目录下
一共有80个,但是总是只能提取出22个,Debug之后发现是不同子目录下的最后.DICOM文件名称相同,导致少提取了很多,让医生重新导出要占用就诊时间,那就加一个文件名判断。
(1)只顾提取(.DCM不重名)
# -*- coding: utf-8 -*-
import os
import shutil
# 设置根目录
root_dir = 'F:/0-MINE-coding/0DataProcess/dicom2png/4'
# 设置目标文件夹
target_dir = 'F:/0-MINE-coding/0DataProcess/dicom2png/20230330'
# 遍历目录树
for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
# 如果是.DCM文件
if filename.endswith('.DCM'):
# 拼接完整路径
filepath = os.path.join(dirpath, filename)
# 复制到目标文件夹
shutil.copy2(filepath, target_dir)
(2)如有同名,加个序号(i) os.path.exists()
来判断目标文件夹中是否存在同名文件
import os
import shutil
# 设置根目录
root_dir = 'F:/0-MINE-coding/0DataProcess/dicom2png/4'
# 设置目标文件夹
target_dir = 'F:/0-MINE-coding/0DataProcess/dicom2png/20230330_1'
# 遍历目录树
for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
# 如果是.DCM文件
if filename.endswith('.DCM'):
# 拼接完整路径
filepath = os.path.join(dirpath, filename)
# 如果目标文件夹中已存在同名文件,则在文件名中加入序号
if os.path.exists(os.path.join(target_dir, filename)):
i = 1
while True:
new_filename = filename.split('.DCM')[0] + f' ({i}).DCM'
if not os.path.exists(os.path.join(target_dir, new_filename)):
break
i += 1
shutil.copy2(filepath, os.path.join(target_dir, new_filename))
else:
shutil.copy2(filepath, target_dir)
3、一张.DCM转成.png
先是得到一片漆黑的图片,然后得到一张全白的图片(只有天赋异禀的人才能看得到( •̀ ω •́ )V
可能是像素值的范围设置不正确导致的,将像素值的范围调整到 [0, 255],然后再保存为 PNG 文件。
# -*- coding: utf-8 -*-
import numpy as np
import pydicom
from PIL import Image
# 读取 DICOM 文件
ds = pydicom.dcmread("-0001-0001-0001-W4095L2047.DCM")
# 将像素值的范围调整到 [0, 255]
pixel_array = ds.pixel_array
min_value = np.min(pixel_array)
max_value = np.max(pixel_array)
pixel_array = (pixel_array - min_value) / (max_value - min_value) * 255
pixel_array = pixel_array.astype(np.uint8)
# 创建 PIL Image 对象
image = Image.fromarray(pixel_array)
# 保存为 PNG 文件
image.save("-0001-0001-0001-W4095L2047.png")
4、dicom2png批处理
# -*- coding: utf-8 -*-
import os
import numpy as np
import pydicom
from PIL import Image
# 设置根目录
root_dir = './20230330'
# 设置目标文件夹
target_dir = './20230330_png'
# 遍历目录树
for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
# 如果是.DICOM文件
if filename.endswith('.DCM'):
# 拼接完整路径
filepath = os.path.join(dirpath, filename)
# 读取 DICOM 文件
ds = pydicom.dcmread(filepath)
# 将像素值的范围调整到 [0, 255]
pixel_array = ds.pixel_array
min_value = np.min(pixel_array)
max_value = np.max(pixel_array)
pixel_array = (pixel_array - min_value) / (max_value - min_value) * 255
pixel_array = pixel_array.astype(np.uint8)
# 创建 PIL Image 对象
image = Image.fromarray(pixel_array)
# 保存为 PNG 文件
png_filename = os.path.splitext(filename)[0] + '.png'
png_filepath = os.path.join(target_dir, png_filename)
image.save(png_filepath)