DICOM images allows for various relationships between the pixel data and intended interpretation of how the image is displayed. The values are found in tag (0028,0004) which lists the Photometric Interpretation of the pixel data.

By using the easily accessible SLIM_SIIM dataset from fastai's list of databases, one can explore the head of the dicom file which contains a list of tags pertaining to various aspects of the data.

Monochrome

pneumothorax_source = untar_data(URLs.SIIM_SMALL)
items = get_dicom_files(pneumothorax_source, recurse=True, folders='sm')
patient_one = dcmread(items[0])
patient_one
(0008, 0005) Specific Character Set              CS: 'ISO_IR 100'
(0008, 0016) SOP Class UID                       UI: Secondary Capture Image Storage
(0008, 0018) SOP Instance UID                    UI: 1.2.276.0.7230010.3.1.4.8323329.6904.1517875201.850819
(0008, 0020) Study Date                          DA: '19010101'
(0008, 0030) Study Time                          TM: '000000.00'
(0008, 0050) Accession Number                    SH: ''
(0008, 0060) Modality                            CS: 'CR'
(0008, 0064) Conversion Type                     CS: 'WSD'
(0008, 0090) Referring Physician's Name          PN: ''
(0008, 103e) Series Description                  LO: 'view: PA'
(0010, 0010) Patient's Name                      PN: '16d7f894-55d7-4d95-8957-d18987f0e981'
(0010, 0020) Patient ID                          LO: '16d7f894-55d7-4d95-8957-d18987f0e981'
(0010, 0030) Patient's Birth Date                DA: ''
(0010, 0040) Patient's Sex                       CS: 'M'
(0010, 1010) Patient's Age                       AS: '62'
(0018, 0015) Body Part Examined                  CS: 'CHEST'
(0018, 5101) View Position                       CS: 'PA'
(0020, 000d) Study Instance UID                  UI: 1.2.276.0.7230010.3.1.2.8323329.6904.1517875201.850818
(0020, 000e) Series Instance UID                 UI: 1.2.276.0.7230010.3.1.3.8323329.6904.1517875201.850817
(0020, 0010) Study ID                            SH: ''
(0020, 0011) Series Number                       IS: "1"
(0020, 0013) Instance Number                     IS: "1"
(0020, 0020) Patient Orientation                 CS: ''
(0028, 0002) Samples per Pixel                   US: 1
(0028, 0004) Photometric Interpretation          CS: 'MONOCHROME2'
(0028, 0010) Rows                                US: 1024
(0028, 0011) Columns                             US: 1024
(0028, 0030) Pixel Spacing                       DS: [0.168, 0.168]
(0028, 0100) Bits Allocated                      US: 8
(0028, 0101) Bits Stored                         US: 8
(0028, 0102) High Bit                            US: 7
(0028, 0103) Pixel Representation                US: 0
(0028, 2110) Lossy Image Compression             CS: '01'
(0028, 2114) Lossy Image Compression Method      CS: 'ISO_10918_1'
(7fe0, 0010) Pixel Data                          OB: Array of 126284 elements

You can specifically call any of the tags, for this dataset the Photometric Interpretation is MONOCHROME2 where the pixel data is represented as a single monochrome image plane.

patient_one.PhotometricInterpretation
'MONOCHROME2'

According to the DICOM Standards Committee this interpretation can only be used when Samples per Pixel (0028, 0002) has a value of 1. We can confirm this:

patient_one.SamplesPerPixel
1
patient_one.show()
1 frame per file

More information about the different types of interpretations can be found here

YBR_FULL_422

Looking at another dataset, this time from the SIIM-ISIC Melanoma Classification competition.

msource = Path('D:/Datasets/Melanoma/test')
mitems = get_dicom_files(msource)
patient_two = dcmread(mitems[0])
patient_two
(0008, 0008) Image Type                          CS: ['DERIVED', 'SECONDARY']
(0008, 0014) Instance Creator UID                UI: 1.3.6.1.4.1.5962.99.3
(0008, 0016) SOP Class UID                       UI: "1.2.840.10008.5.1.4.1.1.77.1.4"
(0008, 0018) SOP Instance UID                    UI: 1.3.6.1.4.1.5962.99.1.7155.4713.1589853456601.1.1.0.0.0
(0008, 0020) Study Date                          DA: '20200519'
(0008, 0023) Content Date                        DA: '20200519'
(0008, 0030) Study Time                          TM: '015736'
(0008, 0033) Content Time                        TM: '015736'
(0008, 0050) Accession Number                    SH: ''
(0008, 0060) Modality                            CS: '"XC"'
(0008, 0070) Manufacturer                        LO: ''
(0008, 0080) Institution Name                    LO: 'ISDIS'
(0008, 0090) Referring Physician's Name          PN: ''
(0008, 1030) Study Description                   LO: 'ISIC 2020 Grand Challenge image'
(0008, 2218)  Anatomic Region Sequence   1 item(s) ---- 
   (0008, 0100) Code Value                          SH: '39937001'
   (0008, 0102) Coding Scheme Designator            SH: 'SCT'
   (0008, 0104) Code Meaning                        LO: 'Skin'
   ---------
(0010, 0010) Patient's Name                      PN: '"ISIC^0052060"'
(0010, 0020) Patient ID                          LO: '"ISIC_0052060"'
(0010, 0030) Patient's Birth Date                DA: ''
(0010, 0040) Patient's Sex                       CS: 'M'
(0010, 1010) Patient's Age                       AS: '065Y'
(0018, 0015) Body Part Examined                  CS: 'SKIN'
(0020, 000d) Study Instance UID                  UI: 1.3.6.1.4.1.5962.99.1.7155.4713.1589853456601.1.2.0
(0020, 000e) Series Instance UID                 UI: 1.3.6.1.4.1.5962.99.1.7155.4713.1589853456601.1.3.0.0
(0020, 0010) Study ID                            SH: 'ISIC_0052060'
(0020, 0011) Series Number                       IS: '"1"'
(0020, 0013) Instance Number                     IS: '"1"'
(0020, 0020) Patient Orientation                 CS: ''
(0028, 0002) Samples per Pixel                   US: 3
(0028, 0004) Photometric Interpretation          CS: 'YBR_FULL_422'
(0028, 0006) Planar Configuration                US: 0
(0028, 0010) Rows                                US: 4000
(0028, 0011) Columns                             US: 6000
(0028, 0100) Bits Allocated                      US: 8
(0028, 0101) Bits Stored                         US: 8
(0028, 0102) High Bit                            US: 7
(0028, 0103) Pixel Representation                US: 0
(0028, 0301) Burned In Annotation                CS: 'YES'
(0028, 2110) Lossy Image Compression             CS: '01'
(0040, 0555)  Acquisition Context Sequence   0 item(s) ---- 
(7fe0, 0010) Pixel Data                          OB: Array of 2513486 elements
patient_two.PhotometricInterpretation
'YBR_FULL_422'
patient_two.SamplesPerPixel
3

In this case the interpretation is YBR_FULL_422 and the pixel data represents a color image described by one luminance (Y) and two chrominance planes (CB and CR). CB and CR values are sampled horizontally at half the Y rate and as a result there are half as many CB and CR values as Y values.

The out of the box show function will not work on this dataset as it does not have Rescale Slope listed in the head so we have to create one

def show_one(file):
    """ function to view a dicom image when Rescale Slope is not noted"""
    pat = dcmread(file)
    trans = Transform(Resize(128))
    dicom_create = PILDicom.create(file)
    dicom_transform = trans(dicom_create)
    return show_image(dicom_transform)
show_one(mitems[0])
<matplotlib.axes._subplots.AxesSubplot at 0x1b0459ffd48>

But why does the image look unnatural?

This is because of the YBR_FULL_422 interpretation so we have to covert the interpretation from YBR_FULL_422 to RGB so that it can look a bit more realistic.

Pydicom provides a means of converting from one color space to another by using convert_color_space where it takes the (pixel array, current color space, desired color space) as attributes. This is done by accessing the pixel_array and then converting to the desired color space

from pydicom.pixel_data_handlers.util import convert_color_space
arr = patient_two.pixel_array
convert = convert_color_space(arr, 'YBR_FULL_422', 'RGB')
show_image(convert)
<matplotlib.axes._subplots.AxesSubplot at 0x1b04b8bc808>

That looks a lot better!