dicom-viewer / app.py
Prgckwb
add sample data
f96a71c
import gradio as gr
import numpy as np
import polars as pl
import pydicom
from PIL import Image
from pydicom.errors import InvalidDicomError
def read_and_preprocess_dicom(file_path: str):
"""
Function to read and preprocess DICOM files
:param file_path: Path to the DICOM file
:return: Image data (in PIL format) and metadata (in pandas DataFrame format)
"""
try:
# Read the DICOM file
dicom_data = pydicom.dcmread(file_path)
except InvalidDicomError:
raise gr.Error("The uploaded file is not a valid DICOM file.")
# Get the pixel data
try:
pixel_array = dicom_data.pixel_array
except AttributeError:
raise gr.Error("The uploaded DICOM file has no pixel data.")
# Normalize the pixel data to 8-bit and convert to a PIL image
if pixel_array.dtype != np.uint8:
pixel_array = ((pixel_array - np.min(pixel_array)) / (np.max(pixel_array) - np.min(pixel_array)) * 255).astype(
np.uint8)
image = Image.fromarray(pixel_array)
# Collect metadata in dictionary format and convert to DataFrame
metadata_dict = {elem.name: str(elem.value) for elem in dicom_data.iterall() if elem.name != 'Pixel Data'}
df_metadata = pl.DataFrame({
"Key": list(metadata_dict.keys()),
"Value": list(metadata_dict.values())
})
return image, df_metadata.to_pandas() # Convert to pandas DataFrame for Gradio compatibility
def build_interface():
"""
Function to build the Gradio interface
"""
theme = gr.themes.Soft(
primary_hue=gr.themes.colors.emerald,
secondary_hue=gr.themes.colors.emerald
)
with gr.Blocks(title='DICOM Viewer', theme=theme) as demo:
gr.Markdown(
"""
# DICOM Viewer
This app reads a DICOM file and displays the image and metadata.
"""
)
with gr.Column():
file_path = gr.File(label="Input DICOM Data")
with gr.Row():
dicom_image = gr.Image(type="pil", label="DICOM Image")
dicom_meta = gr.Dataframe(headers=None, label="Metadata")
inputs = [file_path]
outputs = [dicom_image, dicom_meta]
file_path.upload(fn=read_and_preprocess_dicom, inputs=inputs, outputs=outputs)
clear_button = gr.ClearButton(components=inputs + outputs, )
example = gr.Examples(
['assets/sample.dcm'],
inputs=inputs,
outputs=outputs,
fn=read_and_preprocess_dicom,
cache_examples=True
)
return demo
if __name__ == '__main__':
demo = build_interface()
demo.launch()