---
title: Inside Dicom
date: 2024-10-29T17:22:02Z
modified: 2026-07-28T11:11:41Z
permalink: "https://www.micheledpierri.com/2024/10/29/inside-dicom/"
type: post
status: publish
excerpt: ""
wpid: 754
categories:
  - Health Informatics
  - Programming
tags:
  - Health Informatics
  - Programming
  - Dicom
  - Medical Imaging
  - Python
featured_image: "https://www.micheledpierri.com/wp-content/uploads/2024/10/inside_dicom_.png"
featured_image_alt: A masked technician in an early 20th-century laboratory examines a long strip of medical film beside a large mechanical projector, surrounded by analog control panels, surgical instruments, and a glowing circular image on the wall.
timestamp: 2026-07-28T11:11:41Z
---

In a [previous blog post](https://www.micheledpierri.com/wp-content/uploads/wp-mfa-exports/post/exploring-dicom.md), we explored how to read the content of a DICOM file, including its numerous tags. These tags provide insights into the study type, characteristics, and all relevant patient and study information.

Now, we’ll focus on the most crucial tag—the one containing the images. A typical study can include anywhere from a few to several hundred DICOM files, usually identifiable by their .dcm extension.

For our practice, we’ll open a single .dcm file containing a frontal projection chest X-ray.

# Environment Setup

Before we begin, it’s essential to install some key libraries. Due to dependency issues, it’s best to create a [dedicated environment](https://www.micheledpierri.com/wp-content/uploads/wp-mfa-exports/post/python-environments.md) for running Python with these libraries. In our environment, we’ve installed numpy, pandas, and matplotlib—common libraries for data management and visualization—as well as the pydicom library discussed in our previous post.

For this specific task, we’ve also installed these additional libraries:

**scipy**: An open-source library for scientific computing in Python, based on numpy. It’s particularly useful for applying image transformation filters.

**opencv (cv2)**: The Open Source Computer Vision Library, which uses machine learning for computer vision tasks. It provides various tools for image processing. In Python, you can access it through the cv2 module.

**pylibjpeg, pylibjpeg-libjpeg, and gdcm**: These libraries are necessary for working with and processing DICOM files.

Our radiographic image is located at IMAGES\\01\\00001.dcm on a diagnostic CD. It contains a frontal projection chest X-ray. The same directory also includes file 00002.dcm, which contains the lateral projection—we won’t be using this for now.

## Loading the image

First, let’s import the necessary libraries:

import pydicom
import matplotlib.pyplot as plt
import numpy as np
```
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> pydicom</span></span>
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> matplotlib.pyplot </span><span style="color: #FF79C6">as</span><span style="color: #F8F8F2"> plt</span></span>
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> numpy </span><span style="color: #FF79C6">as</span><span style="color: #F8F8F2"> np</span></span>
<span class="line"></span>
```

Now, we’ll locate our .dcm file and load the dataset into the _dicom\_data_ variable.

The image data in _dicom\_data_ is stored in the _pixel\_array_ attribute, which we’ll assign to the _image_ variable. This creates a numpy array of rows and columns containing the pixel data that forms the image.

# Specify the path to the DICOM file
dicom_path = "C:\\Dicom\\RX\\IMAGES\\01\\00001"

# Read the DICOM file
dicom_data = pydicom.dcmread(dicom_path)

# Extract the image from the DICOM dataset
image = dicom_data.pixel_array:
```
<span class="line"><span style="color: #6272A4"># Specify the path to the DICOM file</span></span>
<span class="line"><span style="color: #F8F8F2">dicom_path </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">C:</span><span style="color: #FF79C6">\\</span><span style="color: #F1FA8C">Dicom</span><span style="color: #FF79C6">\\</span><span style="color: #F1FA8C">RX</span><span style="color: #FF79C6">\\</span><span style="color: #F1FA8C">IMAGES</span><span style="color: #FF79C6">\\</span><span style="color: #F1FA8C">01</span><span style="color: #FF79C6">\\</span><span style="color: #F1FA8C">00001</span><span style="color: #E9F284">"</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Read the DICOM file</span></span>
<span class="line"><span style="color: #F8F8F2">dicom_data </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> pydicom.dcmread(dicom_path)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Extract the image from the DICOM dataset</span></span>
<span class="line"><span style="color: #F8F8F2">image </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> dicom_data.pixel_array:</span></span>
<span class="line"></span>
```

Let’s extract some key information about our image: its data type, dimensions in pixels, and the range of possible pixel values:

# Information about the array
print("Pixel data type:", image.dtype)
print("Image dimensions:", image.shape)
print("Maximum pixel value:", np.max(image))
print("Minimum pixel value:", np.min(image))
```
<span class="line"><span style="color: #6272A4"># Information about the array</span></span>
<span class="line"><span style="color: #8BE9FD">print</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Pixel data type:</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, image.dtype)</span></span>
<span class="line"><span style="color: #8BE9FD">print</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image dimensions:</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, image.shape)</span></span>
<span class="line"><span style="color: #8BE9FD">print</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Maximum pixel value:</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, np.max(image))</span></span>
<span class="line"><span style="color: #8BE9FD">print</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Minimum pixel value:</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, np.min(image))</span></span>
<span class="line"></span>
```

Pixel data type: uint16 Image

dimensions: (2400, 2880)

Maximum pixel value: 4095

Minimum pixel value: 0

Our image has dimensions of 2400 x 2880 pixels, with each pixel capable of holding a value from 0 to 4095.

The pixel data type indicates a bit depth of 16 unsigned bits (u) per pixel, allowing for 2^16 = 65,536 grayscale values (opacity and brightness) ranging from 0 to 65,535. In contrast, an 8-bit image has a lower depth, with each value on the scale ranging from 0 to 255 (2^8 = 256 values).

However, it’s worth noting that while the data type allows for up to 65,535 values, the actual image in this case only uses values from 0 to 4095. This suggests that the image is effectively using 12 bits of information (2^12 = 4096 possible values), even though it’s stored in a 16-bit format.

Medical images are typically stored in 12- or 16-bit formats. The lowest values (0) correspond to darker areas in the image.

We can visualize the image using matplotlib:

# Display the image
plt.imshow(image, cmap="gray")
plt.axis("off")  # Hide axes for a clean visualization
plt.show()
```
<span class="line"><span style="color: #6272A4"># Display the image</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)  </span><span style="color: #6272A4"># Hide axes for a clean visualization</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

The resulting image will be displayed as follows:

![chest X-ray](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog1.png)

Out of curiosity, let’s extract the values from a small 10×10 pixel area of the image, read the stored values, and reconstruct them based on the grayscale.

# Define the starting position for the square (you can modify it based on your needs)
start_x, start_y = 100, 100  # For example, the top-left pixel of the square

# Extract a 10x10 pixel square from the resized frontal image
square = image[start_y:start_y+10, start_x:start_x+10]

# Display the numerical values of the pixels
fig, axes = plt.subplots(1, 2, figsize=(12, 6))

# First grid: numerical pixel values
axes[0].imshow(square, cmap="gray")
for i in range(10):
    for j in range(10):
        # Insert the pixel value at the center of the cell
        axes[0].text(j, i, int(square[i, j]), ha="center", va="center", color="red", fontsize=10)
axes[0].set_title("Pixel Values")
axes[0].axis("off")  # Remove axes for a clean visualization

# Second grid: grayscale
axes[1].imshow(square, cmap="gray")
axes[1].set_title("Grayscale")
axes[1].axis("off")

# Optimize the layout
plt.tight_layout()
plt.show()
```
<span class="line"><span style="color: #6272A4"># Define the starting position for the square (you can modify it based on your needs)</span></span>
<span class="line"><span style="color: #F8F8F2">start_x, start_y </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">100</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">100</span><span style="color: #F8F8F2">  </span><span style="color: #6272A4"># For example, the top-left pixel of the square</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Extract a 10x10 pixel square from the resized frontal image</span></span>
<span class="line"><span style="color: #F8F8F2">square </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> image[start_y</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2">start_y</span><span style="color: #FF79C6">+</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">, start_x</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2">start_x</span><span style="color: #FF79C6">+</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Display the numerical values of the pixels</span></span>
<span class="line"><span style="color: #F8F8F2">fig, axes </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> plt.subplots(</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">2</span><span style="color: #F8F8F2">, </span><span style="color: #FFB86C; font-style: italic">figsize</span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2">(</span><span style="color: #BD93F9">12</span><span style="color: #F8F8F2">, </span><span style="color: #BD93F9">6</span><span style="color: #F8F8F2">))</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># First grid: numerical pixel values</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">].imshow(square, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #FF79C6">for</span><span style="color: #F8F8F2"> i </span><span style="color: #FF79C6">in</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD">range</span><span style="color: #F8F8F2">(</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">):</span></span>
<span class="line"><span style="color: #F8F8F2">    </span><span style="color: #FF79C6">for</span><span style="color: #F8F8F2"> j </span><span style="color: #FF79C6">in</span><span style="color: #F8F8F2"> </span><span style="color: #8BE9FD">range</span><span style="color: #F8F8F2">(</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">):</span></span>
<span class="line"><span style="color: #F8F8F2">        </span><span style="color: #6272A4"># Insert the pixel value at the center of the cell</span></span>
<span class="line"><span style="color: #F8F8F2">        axes[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">].text(j, i, </span><span style="color: #8BE9FD; font-style: italic">int</span><span style="color: #F8F8F2">(square[i, j]), </span><span style="color: #FFB86C; font-style: italic">ha</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">center</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, </span><span style="color: #FFB86C; font-style: italic">va</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">center</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, </span><span style="color: #FFB86C; font-style: italic">color</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">red</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">, </span><span style="color: #FFB86C; font-style: italic">fontsize</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">10</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">].set_title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Pixel Values</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">0</span><span style="color: #F8F8F2">].axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)  </span><span style="color: #6272A4"># Remove axes for a clean visualization</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Second grid: grayscale</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">].imshow(square, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">].set_title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Grayscale</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">axes[</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">].axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Optimize the layout</span></span>
<span class="line"><span style="color: #F8F8F2">plt.tight_layout()</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![pixels](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog2-1024x512.png)

Various operations can be performed on the pixel matrix that composes the image. Let’s explore a few of them.

# Normalization

When the grayscale range is extensive (in our case, from 0 to 65,535), it’s often beneficial to normalize it to a scale of 0 to 255. This process can enhance the visibility of details perchè con valori di intensità molto distanti potrebbero essere non distinguibili.

When the grayscale range is extensive (in our case, from 0 to 65,535), it’s often beneficial to normalize it to a scale of 0 to 255. This process can enhance the visibility of details, as intensity values that are very far apart might otherwise be indistinguishable to the human eye.

# Normalization between 0 and 255
image_normalized = (image - np.min(image)) / (np.max(image) - np.min(image)) * 255
image_normalized = image_normalized.astype(np.uint8)

# Display the normalized image
plt.imshow(image_normalized, cmap="gray")
plt.title("Normalized Image")
plt.axis("off")
plt.show()```
<span class="line"><span style="color: #6272A4"># Normalization between 0 and 255</span></span>
<span class="line"><span style="color: #F8F8F2">image_normalized </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> (image </span><span style="color: #FF79C6">-</span><span style="color: #F8F8F2"> np.min(image)) </span><span style="color: #FF79C6">/</span><span style="color: #F8F8F2"> (np.max(image) </span><span style="color: #FF79C6">-</span><span style="color: #F8F8F2"> np.min(image)) </span><span style="color: #FF79C6">*</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">255</span></span>
<span class="line"><span style="color: #F8F8F2">image_normalized </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> image_normalized.astype(np.uint8)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Display the normalized image</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_normalized, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Normalized Image</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
```

![chest X-ray  after normalization](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog3-1.png)

# Equalization

This technique adjusts pixel values to better distribute intensities across the image. It’s particularly useful for radiographic images as it enhances the visibility of structures that are otherwise difficult to perceive.

To perform equalization, we’ll use the cv2 library:

import cv2

# Histogram equalization with OpenCV
image_equalized = cv2.equalizeHist(image_normalized)
plt.imshow(image_equalized, cmap="gray")
plt.title("Image with Histogram Equalization")
plt.axis("off")
plt.show()
```
<span class="line"><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> cv2</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Histogram equalization with OpenCV</span></span>
<span class="line"><span style="color: #F8F8F2">image_equalized </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> cv2.equalizeHist(image_normalized)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_equalized, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image with Histogram Equalization</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray after equalization](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog4.png)

## Smoothing or Gaussian Filter

The Gaussian filter averages nearby pixels to reduce sudden value variations and noise. As a result, images appear less detailed but more uniform.

You can import the Gaussian filter from scipy.

from scipy.ndimage import gaussian_filter

# Apply a Gaussian filter to reduce noise
image_smoothed = gaussian_filter(image_normalized, sigma=1)

# Display the image with smoothing
plt.imshow(image_smoothed, cmap="gray")
plt.title("Image with Smoothing (Gaussian Filter)")
plt.axis("off")
plt.show()
```
<span class="line"><span style="color: #FF79C6">from</span><span style="color: #F8F8F2"> scipy.ndimage </span><span style="color: #FF79C6">import</span><span style="color: #F8F8F2"> gaussian_filter</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Apply a Gaussian filter to reduce noise</span></span>
<span class="line"><span style="color: #F8F8F2">image_smoothed </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> gaussian_filter(image_normalized, </span><span style="color: #FFB86C; font-style: italic">sigma</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">1</span><span style="color: #F8F8F2">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Display the image with smoothing</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_smoothed, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image with Smoothing (Gaussian Filter)</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray following application of smoothing](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog5.png)

## Pseudocoloring

Pseudocoloring applies filters to colorize areas in grayscale images, enhancing visual analysis. For instance, the “jet” filter assigns blue to low intensities and red to high intensities, making different regions more distinguishable.

# Apply a "jet" color map for pseudo-coloring
plt.imshow(image_normalized, cmap="jet")
plt.title("Pseudo-Colored Image")
plt.axis("off")
plt.colorbar()  # Add a color bar for reference
plt.show()
```
<span class="line"><span style="color: #6272A4"># Apply a "jet" color map for pseudo-coloring</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_normalized, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">jet</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Pseudo-Colored Image</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.colorbar()  </span><span style="color: #6272A4"># Add a color bar for reference</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray pseudocolored](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog6.png)

Another color scale option is the cool/warm scale:

plt.imshow(image_normalized, cmap="coolwarm")
plt.title("Image with Cool/Warm Coloration")
plt.axis("off")
plt.colorbar()
plt.show()
```
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_normalized, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">coolwarm</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image with Cool/Warm Coloration</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.colorbar()</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray with cool-warm coloration](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog9.png)

## Thresholding

The image is converted to binary, with pixels below a certain threshold becoming black and those above turning white. This process highlights high-density elements like bones in an X-ray.

threshold_value = 128  # Example threshold, to be adapted to the image
image_thresholded = (image_normalized > threshold_value) * 255

plt.imshow(image_thresholded, cmap="gray")
plt.title("Image with Intensity Threshold")
plt.axis("off")
plt.show()
```
<span class="line"><span style="color: #F8F8F2">threshold_value </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">128</span><span style="color: #F8F8F2">  </span><span style="color: #6272A4"># Example threshold, to be adapted to the image</span></span>
<span class="line"><span style="color: #F8F8F2">image_thresholded </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> (image_normalized </span><span style="color: #FF79C6">></span><span style="color: #F8F8F2"> threshold_value) </span><span style="color: #FF79C6">*</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">255</span></span>
<span class="line"></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(image_thresholded, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image with Intensity Threshold</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray with intensity threshold](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog7.png)

## Edge Detection (Canny)

The Canny edge detection algorithm identifies edges in an image based on intensity gradients. It uses two threshold values to determine which edges to keep.

# Apply edge detection using OpenCV's Canny method
edges = cv2.Canny(image_normalized, threshold1=30, threshold2=34)

# Display the detected edges
plt.imshow(edges, cmap="gray")
plt.title("Image with Edge Detection (Canny)")
plt.axis("off")
plt.show()
```
<span class="line"><span style="color: #6272A4"># Apply edge detection using OpenCV's Canny method</span></span>
<span class="line"><span style="color: #F8F8F2">edges </span><span style="color: #FF79C6">=</span><span style="color: #F8F8F2"> cv2.Canny(image_normalized, </span><span style="color: #FFB86C; font-style: italic">threshold1</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">30</span><span style="color: #F8F8F2">, </span><span style="color: #FFB86C; font-style: italic">threshold2</span><span style="color: #FF79C6">=</span><span style="color: #BD93F9">34</span><span style="color: #F8F8F2">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6272A4"># Display the detected edges</span></span>
<span class="line"><span style="color: #F8F8F2">plt.imshow(edges, </span><span style="color: #FFB86C; font-style: italic">cmap</span><span style="color: #FF79C6">=</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">gray</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.title(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">Image with Edge Detection (Canny)</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.axis(</span><span style="color: #E9F284">"</span><span style="color: #F1FA8C">off</span><span style="color: #E9F284">"</span><span style="color: #F8F8F2">)</span></span>
<span class="line"><span style="color: #F8F8F2">plt.show()</span></span>
<span class="line"></span>
```

![chest X-ray after application of edge detection](https://www.micheledpierri.com/wp-content/uploads/2024/10/radiog8-1.png)

---

With the pixel matrix that composes an image at our disposal, we have a wide array of manipulation techniques to enhance its visualization. These techniques allow us to extract more information, highlight specific features, or improve the overall clarity of the image.

In many medical imaging scenarios, we often encounter multiple images of the same patient and anatomical region. This presents exciting opportunities beyond single-image manipulation. We can use these multiple images to [reconstruct three-dimensional volumes,](https://www.micheledpierri.com/wp-content/uploads/wp-mfa-exports/post/dicom-orientation.md) providing a more comprehensive view of the anatomy. Additionally, we can create dynamic sequences or moving images, which can be particularly useful for studying physiological processes or changes over time.

These advanced processing techniques, such as volume reconstruction and dynamic imaging, open up new possibilities for diagnosis, treatment planning, and medical research. They allow healthcare professionals to gain deeper insights into patient anatomy and physiology, potentially leading to more accurate diagnoses and improved patient care