JuliaHealth / DICOM.jl

Julia package for reading and writing DICOM (Digital Imaging and Communications in Medicine) files
MIT License
56 stars 21 forks source link

Pixel Data Not Found #91

Open Dale-Black opened 3 months ago

Dale-Black commented 3 months ago

I will try to get around to diagnosing this issue, but for some reason the pixel data from this image (from a new photon counting CT) is not found using DICOM.jl but works fine with pydicom

Here is my Julia attempt:

using DICOM: @tag_str, dcm_parse

function rescale_dcm(dcm_path)
    dcm = dcm_parse(dcm_path)
    header = dcm.meta
    pixel_array = header[tag"Pixel Data"]

    ...

end

low_energy_image = rescale_dcm(path_70_keV)

Which errors:

KeyError: key (0x7fe0, 0x0010) not found

Stack trace
Here is what happened, the most recent locations are first:

getindex @ dict.jl:498
(::Main.var"workspace#30".var"#rescale_dcm#1")(dcm_path::String) @ [This cell: line 7](http://0.0.0.0:1235/edit?id=91b38720-4b92-11ef-2fef-6d356e0327f4#98202d78-20f0-4259-a919-1e24f3450fd4)
    header = dcm.meta
    pixel_array = header[tag"Pixel Data"]
[Show more...](http://0.0.0.0:1235/edit?id=91b38720-4b92-11ef-2fef-6d356e0327f4#)

Whereas with pydicom (via PythonCall)

function rescale_pydicom(dcm_filepath)
    # Read the DICOM file
    data = pydicom.dcmread(dcm_filepath)

    # Get the pixel array
    pixel_array = data.pixel_array

    # Get RescaleSlope and RescaleIntercept, with default values as second args
    rescale_slope = pygetattr(data, "RescaleSlope", 1.0)
    rescale_intercept = pygetattr(data, "RescaleIntercept", 0.0)

    image = (pixel_array * rescale_slope) + rescale_intercept

    return pyconvert(Array{Float64}, image)
end

this works completely fine.

MonoE 70keV 200mA.dcm.zip

notZaki commented 3 months ago

Newer Siemens units use enhanced DICOM by default when exporting, and it looks like DICOM.jl struggles to read the deeply nested sequences in the header. So it trips up before reaching the pixel data. I'll try to take a look as well.

Edit: On a closer look, the nested sequences are being parsed, so maybe it's a specific element in a sequence causing the issue.

Dale-Black commented 3 months ago

Oh wow thank you for being so quick to respond. I appreciate you looking into this very much!

notZaki commented 3 months ago

The current (unreleased) master tries to quickly/temporarily fix this.

I tried the following:

dcm = dcm_parse(path_70_kev)
rescale!(dcm)

# Using Plots
heatmap(dcm.PixelData, aspect_ratio=1, color=:grays, yflip=true, clim=(-1000, 2000), axis=false, grid=false)

and it approximately matches what I see in a dicom viewer. Let me know if it works for you.

Dale-Black commented 3 months ago

Great, this works and has the correct pixel data!