[Code | Format conversion] Dicom to png

 【Related Links】

How To Convert a DICOM Image Into JPG or PNG - PYCAD中文

【related information】

1. PNG and JPEG (JPG) formats each have their own advantages and disadvantages. Different formats can be selected according to different application scenarios.

From the perspective of retaining the integrity of picture information and reducing information loss, the PNG format is better than the JPEG format. PNG is a lossless compression format that retains the complete information of each pixel of the image and does not cause compression artifacts. Therefore, when the highest quality image information needs to be preserved in image processing, the PNG format is usually chosen.

In contrast, the JPEG format is a lossy compression format that loses some information of the image during compression, resulting in a decrease in image quality. Although the JPEG format has a higher compression ratio and a smaller file size than the PNG format, the JPEG format may cause information loss and quality degradation during image processing.

Overall, if you need to retain the highest quality image information during image processing, you should choose the PNG format. If file size is important and image quality is not the highest priority, you can choose the JPEG format.

2. DICOM (Digital Imaging and Communications in Medicine) is a standard format for medical images and related information. To read DICOM files you can use a DICOM library such as pydicom

Although DICOM was originally designed for CT (computed tomography) images, it is now also widely used for images produced by other medical imaging equipment, including X-ray films, magnetic resonance imaging (MRI), ultrasound, PET, etc.

Therefore, files in DICOM format are not necessarily CT, but can also be images from X-rays or other medical imaging equipment. The DICOM format provides a standard way for various medical images to be exchanged and shared between different medical imaging devices and software.

When converting from .DCM to .PNG: Medical imaging data in DICOM format stores a large amount of metadata and pixel data, while image data in PNG format only contains pixel data. During the conversion process, it should be noted that the DICOM data may contain compression encoding and needs to be decoded using the pydicom library. At the same time, since the pixel values ​​in the DICOM file may not be standard 8-bit grayscale values, normalization processing is required to ensure that the pixel values ​​range from 0 to 255.

【Code record】

1. Use pydicom to read DICOM file information

An error occurred in the middle: UnicodeEncodeError: 'gbk' codec can't encode character '\xcd' in position 3694: illegal multibyte sequence because some Unicode characters cannot be encoded.

# -*- 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' means the spatial resolution of the image is 0.143mm. The spatial resolution refers to the physical distance between two adjacent pixels on the image.
(0028, 0030) Pixel Spacing DS: [0.1408399617591, 0.1408399617591]

Pixel Spacingand Imager Pixel Spacingare both DICOM attributes that describe the spacing between pixels, but they describe different pixel spacings.

Imager Pixel SpacingIt describes the pixel pitch in a digital image display device (imager). It is a list of two numbers. The first number represents the row spacing, and the second number represents the column spacing. The unit is mm.

Pixel SpacingIt describes the pixel spacing in the image plane (pixel array). It is a list composed of two numbers. The first number represents the row spacing, and the second number represents the column spacing. The unit is also mm.

In this example, Imager Pixel Spacingthe value of is [0.143, 0.143], indicating that the row spacing and column spacing of adjacent pixels in a digital image display device are both 0.143mm. The Pixel Spacingvalue is [0.1408399617591, 0.1408399617591], indicating that the row spacing and column spacing of adjacent pixels in the image plane are both 0.1408399617591mm. It can be seen that the two values ​​are slightly different, which may be due to factors such as interpolation of the digital image display device.

2. Extract .DCM files from multiple folders to the specified unified directory

There are 80 in total, but only 22 can always be extracted. After debugging, it was found that the last .DICOM files in different subdirectories have the same name, resulting in a lot less extraction. It will take up time for the doctor to re-export, so add one. File name judgment.

(1) Just extract (.DCM does not have the same name)

# -*- 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) If there is a file with the same name, add a serial number (i)        os.path.exists() to determine whether a file with the same name exists in the target folder.

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. Convert a .DCM to .png

First, you get a dark picture, and then you get a completely white picture (only those with extraordinary talents can see it ( •̀ ω •́ )V

It may be caused by incorrect setting of the pixel value range. Adjust the pixel value range to [0, 255] and then save it as a PNG file.

# -*- 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 batch processing

# -*- 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)

Guess you like

Origin blog.csdn.net/sinat_40759442/article/details/129881770