Get rid of DICOM images in Python

To put it simply, DICOM images are images that are handled on the communication protocol (DICOM) for exchanging medical images between devices, and various additional information (patient information, patient information, etc.) to the images. It is the type of device, the information of the image itself, and various metadata).

When a doctor performs an examination such as CT or MRI, some hospitals may ask you to use the image as data. If the format at this time is the extension .dcm, it is a DICOM image.

Preparing to work with DICOM in Python

If you want to work with DICOM images in Python, it seems that you will use pydicom.

% anaconda show conda-forge/pydicom
Using Anaconda API: https://api.anaconda.org
Name:    pydicom
Summary: Pure python package for DICOM medical file reading and writing
Access:  public
Package Types:  conda
Versions:
   + 0.9.9

To install this package with conda run:
     conda install --channel https://conda.anaconda.org/conda-forge pydicom

That's why `conda install -c https://conda.anaconda.org/conda-forge pydicom`.

Prepare a sample DICOM image

If you unfortunately don't have your own MRI image, download a sample image. There is DICOM Image Library on the Osirix site, which is famous as a DICOM Viewer, so get a suitable one from here. For the time being, I downloaded an MRI image of a brain tumor called BRAINIX. If you unzip this .zip file, you will see images (T1 weighted, etc.) that have been processed in various ways for the interpretation doctor to see after imaging with MRI. Among them, "T1-3D-FFE-C" I decided to use 100 files in the folder "-\ 801 /".

Read DICOM images

Below is an example of how to load an image using the pydicom function.

Read one DICOM image and refer to the metadata

Load the image and display the DICOM header.

import dicom

d = dicom.read_file('BRAINIX/IM-0001-0075.dcm')
print(d)

By the way, if you want to display specific metadata, do as follows.

print(d.Manufacturer)

Apparently, the device manufacturer is "Philips Medical Systems".

print(d[0x0018, 0x0050])

Apparently, the Slice thickness is 1.5mm.

20161030_002.png

In this way, DICOM metadata has a key name called a tag, and the keys are numbered. And with pydicom, you can display either the key name or the number.

Read one DICOM image and display the image

Since the substance of the image part of the DICOM image can be extracted in the array format of numpy, it can be displayed by using either opencv or matplotlib.

Kobito.MQX9VW.png

Reads multiple DICOM images and converts them into one continuous tomographic image

By the way, the BRAINIX image used this time is a series of 100 images with a thickness of 1.5 mm. These 100 images can be read and imported into one 3D array.

import dicom
from matplotlib import pyplot as plt
%matplotlib inline

root_dir = './BRAINIX'
dcms = []
for d, s, fl in os.walk(root_dir):
    for fn in fl:
        if ".dcm" in fn.lower():
            dcms.append(os.path.join(d, fn))
ref_dicom = dicom.read_file(dcms[0])
d_array = np.zeros((ref_dicom.Rows, ref_dicom.Columns, len(dcms)), dtype=ref_dicom.pixel_array.dtype)
for dcm in dcms:
    d = dicom.read_file(dcm)
    d_array[:, :, dcms.index(dcm)] = d.pixel_array

In short, all the files under the BRAINIX folder with the extension .dcm are read, and the contents are copied in order to a three-dimensional array called d_array.

If you want to display any slice, for example the 50th slice, just do `pyplt.imshow (d_array [:, :, 49])`. Now that it has been read into a 3D array, it is possible to display 3 cross sections.

import os
import dicom
from matplotlib import pyplot as plt
%matplotlib inline

#Read the dcm file under the BRAINIX folder
root_dir = './BRAINIX'
dcms = []
for d, s, fl in os.walk(root_dir):
    for fn in fl:
        if ".dcm" in fn.lower():
            dcms.append(os.path.join(d, fn))
ref_dicom = dicom.read_file(dcms[0])
d_array = np.zeros((ref_dicom.Rows, ref_dicom.Columns, len(dcms)), dtype=ref_dicom.pixel_array.dtype)
for dcm in dcms:
    d = dicom.read_file(dcm)
    d_array[:, :, dcms.index(dcm)] = d.pixel_array

#3 Cross section display
print(d_array.shape)
plt.subplot(1, 3, 1)
plt.imshow(d_array[127, :, :])
plt.subplot(1, 3, 2)
plt.imshow(d_array[:, 127, :])
plt.subplot(1, 3, 3)
plt.imshow(d_array[:, :, 49])

20161030_003.png

Process and save DICOM images

If you want to process the read DICOM image and save it by overwriting the original DICOM image, you need to edit the array of pixel_array.

However, the original image does not change just by editing the array of pixel_array. This is because the actual image data of the DICOM image is stored in an array called PixelData, and the interface for reading it is pixel_array. Therefore, if the contents of the edited pixel_array are saved in an array called img, for example, it is necessary to write back the contents to Pixel Data.

d = dicom.read_file(dcm)
img = d.pixel_array
#Processing of img
d.PixelData = img.tostring()
d.save_as(dcm)

Try cropping a DICOM image into a circle

I don't know what it is, but I'll try the work of "cutting out the DICOM image only in the center part with a circle with a diameter half the length and width of the image".

With the following code, an image with a diameter of half the length and width of the image is 1 inside and 0 outside. If the radius is r, the vertical and horizontal size of the image can be obtained from ref_dicom.pixel_array.shape, so set 1/4 of that size.

r = ref_dicom.pixel_array.shape[0] / 4
x, y = np.indices((ref_dicom.Rows, ref_dicom.Columns))
circle = (x - (ref_dicom.Columns / 2))**2 + (y - (ref_dicom.Rows / 2))**2 < r**2
mask = circle.astype(int)

Multiplying this mask, the inside of the circle is 1 and the outside is 0, so you can cut out a circle.

###Read multiple DICOM image files and cut out the center part in a circle

import os
import dicom
from matplotlib import pyplot as plt
%matplotlib inline

#Read the dcm file under the BRAINIX folder
root_dir = './BRAINIX'
dcms = []
for d, s, fl in os.walk(root_dir):
    for fn in fl:
        if ".dcm" in fn.lower():
            dcms.append(os.path.join(d, fn))
ref_dicom = dicom.read_file(dcms[0])

#Create a mask to cut out into a circle
r = ref_dicom.pixel_array.shape[0] / 4
x, y = np.indices((ref_dicom.Rows, ref_dicom.Columns))
circle = (x - (ref_dicom.Columns / 2))**2 + (y - (ref_dicom.Rows / 2))**2 < r**2
mask = circle.astype(int)

#Perform mask processing on all images
d_array = np.zeros((ref_dicom.Rows, ref_dicom.Columns, len(dcms)), dtype=ref_dicom.pixel_array.dtype)
for dcm in dcms:
    d = dicom.read_file(dcm)
    img = d.pixel_array * mask
    d_array[:, :, dcms.index(dcm)] = img

#3 Cross section display
plt.figure(figsize=(8, 6))
plt.subplot(1, 3, 1)
plt.imshow(d_array[127, :, :])
plt.subplot(1, 3, 2)
plt.imshow(d_array[:, 127, :])
plt.subplot(1, 3, 3)
plt.imshow(d_array[:, :, 49])

20161030_004.png


When dealing with DICOM images in Python, it looks like this.

Today's code

Recommended Posts

Get rid of DICOM images in Python
Getting rid of DICOM images in Python Part 2
Pixel manipulation of images in Python
Working with DICOM images in Python
Get date in Python
Get a glimpse of machine learning in Python
Get YouTube Comments in Python
Base64 encoding images in Python 3
How to get the number of digits in Python
Get last month in python
[python] Get the list of classes defined in the module
Get rid of python's KeyError
Equivalence of objects in Python
Get the size (number of elements) of UnionFind in Python
Get Terminal size in Python
Explicitly get EOF in python
Faster loading of Python images
Get Evernote notes in Python
Implementation of quicksort in Python
Get the URL of the HTTP redirect destination in Python
manage to get rid of heavy pyls in vim-lsp
Get Japanese synonyms in Python
Displaying DICOM images in rudimentary Python as a medical professional
How to get rid of server custom emoji in message.content
Get the number of specific elements in a python list
Get rid of dirty data with Python and regular expressions
Get index of nth largest / smallest value in list in Python
How to get a list of built-in exceptions in python
Get the index of each element of the confusion matrix in Python
Get index of nth largest / smallest value in list in Python
Number recognition in images with Python
Get rid of slow scp -pr
Get data from Quandl in Python
How to collect images in Python
MySQL-automatic escape of parameters in python
Handling of JSON files in Python
Implementation of life game in Python
Waveform display of audio in Python
Extract text from images in Python
Get, post communication memo in Python
Get the desktop path in Python
Law of large numbers in python
Get the host name in Python
Reversible scrambling of integers in Python
Get started with Python in Blender
[python] Get the rank of the values in List in ascending / descending order
Python techniques for those who want to get rid of beginners
Get a list of files in a folder with python without a path
Get the title and delivery date of Yahoo! News in Python
Get the number of readers of a treatise on Mendeley in Python
Get additional data in LDAP with python
Get exchange rates from open exchange rates in Python
Check the behavior of destructor in Python
Get Suica balance in Python (using libpafe)
(Bad) practice of using this in Python
General Theory of Relativity in Python: Introduction
How to get rid of long comprehensions
Mosaic images in various shapes (Python, OpenCV)
Output tree structure of files in Python
Comparison of Japanese conversion module in Python3
Summary of various for statements in Python