How to mask a DICOM image?

757 Views Asked by At

I would like to analyze only "Bone" regions extracted from Head CT.

For that, I read the DICOM files and masked regions where pixel values were less than 200 by filling in "0".

However, because "0" means "water" in the DICOM image, I don't know whether this is an appropriate way or not.

import pydicom
import numpy as np

dcm_img = pydicom.dcmread("0000200.dcm")
dcm_arr = dcm_img.pixel_array
masked_arr = np.where(dcm_arr < 200, 0, dcm_arr)
1

There are 1 best solutions below

5
simon On

From your question, it is not quite clear to me how exactly you want to analyze the bone regions in your CT image, so it is hard to provide a tailored answer. Generally though, I would not set values to zero in the image, because – as you said – each value in a CT image is associated with specific tissue properties (also, very generally in image processing, it is usually not a good idea to conflate image and masking information).

Instead, I would probably work with a masked array, masking out all the values that lie below the bone threshold, like so:

from numpy.ma import masked_array
...
masked_arr = masked_array(data=dcm_arr, mask=dcm_arr < 200)

With this, you could then use the operations that a masked array provides, such as masked_arr.mean(), which calculates the mean of all voxels that have not been masked out (which is why we masked the values below the threshold).

Alternatively, but very similar, I would probably create a new (regular) Numpy array, containing a boolean mask that marks all the values that do lie above the bone threshold (e.g. is_bone = dcm_arr >= 200), which I would later use for filtering values in my analyses.

In any case, I would try to keep the mask values and the actual CT voxel values separate.