DICOM Processing and Segmentation in Python

DICOM is a pain in the neck.  It also happens to be very helpful.  As clinical radiologists, we expect post-processing, even taking them for granted. However, the magic that occurs behind the scenes is no easy feat, so let’s explore some of that magic.

In this quest, we will be starting from raw DICOM images. We will extract voxel data from DICOM into numpy arrays, and then perform some low-level operations to normalize and resample the data, made possible using information in the DICOM headers.

The remainder of the Quest is dedicated to visualizing the data in 1D (by histogram), 2D, and 3D. Finally, we will create segmentation masks that remove all voxel except for the lungs.

Processing raw DICOM with Python is a little like excavating a dinosaur – you’ll want to have a jackhammer to dig, but also a pickaxe and even a toothbrush for the right situations. Python has all the tools, from pre-packaged imaging process packages handling gigabytes of data at once to byte-level operations on a single voxel.

Update 1/5/2019:

The Kaggle data science bowl 2017 dataset is no longer available. However, for learning and testing purposes you can use the National Lung Screening Trial chest CT dataset.


To follow along, set up your computer using the following Python tutorials: Alternatively, start a free Jupyter notebook from Azure Notebooks.
Howard Chen
Associate Informatics Officer at Cleveland Clinic Imaging Institute
(Howard) Po-Hao Chen, MD MBA is the Associate Informatics Officer at the Cleveland Clinic Imaging Institute and a musculoskeletal radiology subspecialist. He has an interest in data-driven radiology, quality improvement, and innovation. Howard has an MD and MBA from Harvard University, and he finished training with fellowships in musculoskeletal radiology, nuclear medicine, and clinical imaging informatics in June 2018 from University of Pennsylvania.

71 Responses to “DICOM Processing and Segmentation in Python

  • Hi Howard,

    Thanks for the tutorial, I have been looking at the images, and I think I understand most of the preprocessing. However, after the resampling (taking into account we have different pixel spacing and slice thickness), we obtain volumes of different dimensions for each patient. How would you recommend resizing in order to get for all patients a volume of dimensions XxYxZ, with spacing of 1x1x1? For me this makes more sense to be able to compare them..
    Thanks in advance,


    • Hey Diana!

      If I understand the question correctly, you have a set of DICOM images, each with different real-life size (L * W * H mm), all of which you want to be able to resample to the same pixel dimensions (X * Y * Z) while maintaining 1 x 1 x 1 mm voxel sizes. It turns out it is a natural side effect: resampling isotropically means so all voxels are the same size but each exam will be different sizes (this is a common approach) because patients are different sizes. This is because CT scans are commonly obtained at a constant 512 x 512 matrix. Since each patient is different in size, what changes is the “zoom” (field-of-view), so each voxel represents a different number of mm in real life.

      You can imagine that if we scanned an 85-pound patient at the same “zoom” as a 190-pound patient, you wouldn’t want the scan to occupy only the middle 250 voxels with a wide rim of air – you’d want to zoom in at the time of acquisition so that it makes a full use of the 512 x 512. This means that each CT scan actually represents different dimensions in real life even though they are all 512 x 512 x Z slices.

      This is why when we resample to isotropic 1 mm voxels, they all end up being different sizes.

      Think of each examination as having a fixed millimeter-per-voxel conversion factor which is based on patient size and different from exam to exam. IIf we made all the XxYxZ the same for all exams, then the voxel size can no longer be 1 x 1 x 1 mm, and vice versa.

      • Hi Howard,

        Thanks for your fast response, is much clear now what is happening. My aim is to be able to feed a 3d Neural network with the volumes, and this requires that all of them have the same shape. I understand the trade off you mention in the last paragraph, however, is there a transformation you could suggest to be able to get the images in the shape we want?

        Thanks in advance,


        • I see – you may find success in using the resampling method from the blog post and simply hardcoding the new_shape variable (instead of calculating it). This should force all the resampled data to be in the same dimensions.

  • Hi Howard, I’m Minwoo.
    Thank you for this tutorial. I try to do your segmentation tutorial. But I have some problem of your tutorials.
    This problem is that some CT slices don’t make final mask or just one lung mask. Erosion and and dilation process is ok. Then color labels process also is ok. But some CT slices don’t show final mask.
    I’ll waiting for your response.
    Thank you.

    • Hi Minwoo – hope you are making good stride in your DICOM manipulation work!

      The “prop.bbox” code (starting for prop in regions:) in the make_lungmask function is the place you want to take a closer look.

      Essentially the code draws boxes around each of the labeled regions (B = prop.bbox). Then because boxes that represent lungs are more likely to be shaped a certain way than boxes that represent other labels, you can perform the mathematic to determine which label is most likely the lung. In the code, B = (min_row, min_col, max_row, max_col) in absolute pixel locations.

      Therefore, B[2]-B[0] would represent the height of the box that has been drawn.

      Try this reference to understand how bbox works. http://scikit-image.org/docs/dev/api/skimage.measure.html

      The precise numbers are determined empirically, so to get the right masks you may have to try different numbers.

      For instance, if your patients tend to have smaller lungs, then you would adjust the code to get closer to the center of the DICOM image.

      • Thank you Howard.
        I have solved my problem.
        If I have some problem again, See you soon.

  • Eric Voots
    2 years ago


    If we loop through all of the images and process them. What is the best way to load them all to be put into a format to analyze the saved .npy files using PCA, neural network etc..? I.e. not sure how to put all .npy files together for analysis.

  • Hey Eric, npy is a good choice for this, and I would go with a numpy.ndarray so you can have a 3D array. Popular packages like sklearn, tensorflow, and Keras all support Numpy variables.

  • Can you support 3D Plotting using vtk?
    Thank so much.

    • Hi khiem, as you mentioned, VTK does support 3D plotting, and does a very good job at it.

      However, there is no easy way for me to show it on this blog because Jupyter does not directly support VTK, making it difficult to share the outputs.

      • Hi Howard Chen,
        Thank for reply, can you share code in here i will run it.

        • Hey khiem – it’s a little out of scope for this blog post, so maybe in the future I’ll write up something in full about VTK. It’s on my list of things to explore for web-based outputs.

        • Guoqing
          2 years ago

          You can use 3D Slicer, it support VTK and Python, 3D visualization is more simple than using 3D plotting.

  • Wogayehu
    2 years ago

    thank you for the tutorials since am new for deep neural networks i got clear idea about preprocessing and segmentation but does it mean we can feed the result of segmented region of lung to any deep Learning model(deepCNN, DBN, SVM) so on or only for deep CNN?

    • Hey Wogayehu,

      It should be useful for any number of the learning algorithms. The concept of doing segmentation and preprocessing in radiology is to standardize and focus on only the portion of the images you really care about (not always the right thing to do, but it often is). Any learning algorithm can potentially benefit from doing this.

      If you have a background in other learning algorithms like SVM and have used it for statistical learning with standard datasets, you may recall that data preprocessing, normalization, and filtering is often a good thing to do beforehand. Conceptually this may be though of as the imaging equivalent of that.

  • Wogayehu
    2 years ago

    thank you very much Howard for reply
    do you give me python pseudo-code resources sites for DBNs in image recognition specially for medical images?

  • Kassahun G
    2 years ago

    Dear Howard,
    Greetings!! Thank you for sharing such a nice tutorial. I would be happy if I can get the PDF version.

    • Hi,

      I’m glad you’ve found it helpful! We don’t typically publish PDF versions of blog posts. Maybe you can try printing the page from your web browser to a PDF file.


  • Youssef Emad
    2 years ago

    Hey could u please where is the cancer in slide 97 and 112 .. i can’t see it

    • Hi Youssef,

      First let’s take at look at the right-sided lung (that’s actually the patient’s LEFT lung, but it’s just the way CT is displayed in America by convention).

      The cancer is not just on slice 97 and 112, it’s on slices from 97 through 112 (all the slices in between). Remember lung cancer is a 3D object so you should expect to see it on multiple slices. It is best seen on slice 100 as a cloud-looking round thing in the lung. Hope this helps!

  • Hiroshi
    2 years ago

    Hi Chen,

    This is indeed a very useful tutorial. Could you please let me know whether, the images ready to hit the CNN are data saved by

    np.save(output_path + “maskedimages_%d.npy” % (id), imgs)

    • Hi Hiroshi, that’s correct. You would be saving image data as .npy files.

      • Hello Chen,
        I believe imgs are not the maskedimages but still the original imgs? Am i wrong? How can I save the masked imgs?

  • Hi Howard and thank you for this great tutorial,

    I’m working on an automated segmentation and 3D surface reconstruction script for
    cancellous and cortical bone. My problem is that as this is for potential total hip replacement
    cases, it usually involves patients with severe osteoarthritis. Segmentation using thresholding
    results in incomplete bone contours, which in turn result in holes on my reconstructed 3D model. Do you have any suggestions on how I should go about to tackle this issue?

    Many thanks!

  • captcoma
    2 years ago

    Hi Howard,

    Thank you very much for your great tutorial. I am new to Python and I do not know how to implement the “Import Packages” section.
    Do I have to run the code as a script?

    Many thanks for your help

    • import is Python syntax that includes packages. In short, it’s similar to import statements in Java and other languages. When you’re in Jupyter, the notebook will automatically execute your Python code without your having to save it separately as a script. Hope this helps.

  • Guoqing
    2 years ago

    You can use 3D Slicer, it support VTK and Python, 3D visualization is more simple than using 3D plotting.

  • general
    2 years ago

    Amazing tutorial! Thank you for this!

  • Interesting

  • Jeffery
    2 years ago

    Hi Howard,

    I‘m studying segmentation of MR brain-tissue(including segment White Matter、Gray Matter、Cerebrospinal fluid from brain-tissue),and I want to use support vertor machine to segment, I have got the feature vector from pixel, but i don’t konw how to get the labels, because SVM need the labels to complete, In other words, I don’t konw how to extract the labels of each tissue from DICOM files.Many thanks for your help!!!

    • Hi Jeffery – do you mean the ground truth labels for white, gray, and CSF for each pixel? (FYI – it’s technically called a voxel because the pixels have 3 dimensions).

      Unfortunately, radiology tissue type labels don’t come pre-labeled in the DICOM normally, which is why segmentation AI is valuable. Establishing ground truths typically require a human expert who hand-draw regions on each slice. This information is then compiled into a data format the script can read. Then, with the ground truth labels for every image, you can separate your input files into training, validating, and testing sets.

      As you can imagine, creating annotated ground truth is laborious, making annotated datasets very valuable. If you are open to using publically available datasets, take a look at MRBrainS by searching for it on Google.

      Best of luck,

      7 months ago

      Hi jeffery, even i’m working on the same project (BRAIN TUMOR DETECTION USING MRI AND MACHINE LEARNING TECHNIQUES) can you please send the code of the project if you have done successfully It will be very helpful for me to finish my project.
      Thanks in advance !
      Mail ID: sai4vanam@gmail.com

  • Hi Sir,

    Great tutorial Helped a lot, can you please also help how to use convolution neural network to classify stages of lung cancer and increase accuracy….
    Please mail similar kind of tutorial to train the data and classify stages..


  • Hi,
    I am trying to run this code using python 3.6.4 (installed using anaconda) but there is no compatible version of pydicom for 3.6.4.
    I have also tried it with Python 2.7 but then I run into errors while installing sci-kit.

    What should I do?

    • Hi Areeb,
      Anaconda allows you to install a different version of Python. See here. In short, you would just create a new conda environment, like this:

      conda create --name raddq python=3.5

      Then depending on your operating system you can activate it accordingly via either “activate” (Win) or “source activate” (Linux/Mac) commands.

  • Hunar A.Ahmed
    1 year ago

    I have a folder contains 5 Dicom images:
    Shape before resampling (5, 512, 512)
    Shape after resampling (175, 340, 340)
    I know that before resampling number of images is 5 and each image 512×512 (height x width), but after resampling, it showing me 175, is this mean the number of images is now 175 and each image is 340×340 (height x width)? or anything else, I am confusing with that?

    • Yes you probably have 175 resampled slices. If you did isometric resampling, it probably means the distance between your first and last slice was pretty big, so the algorithm tried to fill in the distance in between. Unfortunately since it only had 5 source slices my guess is your resampled images might have some quality issues.

      • Hunar A.Ahmed
        1 year ago

        thank you for your replay Mr.Howard, in your replay,
        you said ‘distance between your first and last slice was pretty big’, is the slice thickness distance between first and last slice or distance between two slices? also, you said ‘algorithm tried to fill in the distance in between’ what you mean by this?
        I use these 5 images folder for test only because I have a low computing power Pc, I have the complete folder image with 133 slices (from LIDC-IDIR) when displaying slice thickness with 5 folder images it shows 30 mm but when I use the 133 folder image it shows 2.5 mm, please can you explain these for me? my resampling code is same as your code.

        • Hunar A.Ahmed
          1 year ago

          sorry, when displaying slice thickness with 5 folder images it shows 35 mm not 30 mm.

  • Bhakti Raul Palkar
    1 year ago

    Why my 3d graph shows everything in white?

  • Thanks for the detailed tutorial. I can no longer access the image set from Kaggle website. Is there an alternate location from where I can download the data?

  • Luddy Indra Purnama, Ign. M.Sc.
    11 months ago

    Dear Howard Chen,
    Thank you for your tutorial, Can you help me to delete noise image from big image. but in your tutorial you pick up lung cancers. I need solidification for big image.

  • Kaggle blocked access to the data. can i get (even fake data) in the same format so the code will run properly?

    Meaning- this paper looks great and i want to follow it and later alter it to my use. i am running on other dicom data that i have. but a lot of the attributes/fields doesnt exit and it makes it impossible to understand and use the code.
    for example:

    slices.sort(key=lambda x: int(x.InstanceNumber))
    produce that error:
    AttributeError: ‘FileDataset’ object has no attribute ‘InstanceNumber’
    please if anyone can send me data to:

    • Hi Assi,

      Consider using the National Lung Screening Trial dataset. I’ve added an update to the blog post to reflect this dataset’s availability.

      Some research datasets have been scrubbed for patient privacy reasons, and sometimes it ends up deleting non-PHI DICOM tags like instance number as well. You can use Python code to test for it:

      #assuming x is an instance of pydicom Dataset class
      if 'InstanceNumber' in x.dir():
          #your code
  • Hi Howard,

    I have to use this tutorial to try to understand and I wish to follow it and modify it later for my use because before I have ever worked with medical data.
    I’m working with the Luna16 dataset which is in a different DICOM format.
    I changed the function load_scan with this function but I can not match the two.

    def load_itk(filename):
    # Reads the image using SimpleITK
    itkimage = sitk.ReadImage(filename)

    # Convert the image to a  numpy array first and then shuffle the dimensions to get axis in the order z,y,x
    ct_scan = sitk.GetArrayFromImage(itkimage)
    # Read the origin of the ct_scan, will be used to convert the coordinates from world to voxel and vice versa.
    origin = np.array(list(reversed(itkimage.GetOrigin())))
    # Read the spacing along each dimension
    spacing = np.array(list(reversed(itkimage.GetSpacing())))
    return ct_scan, origin, spacing

    If you can help me and thank you in advance.

  • Thank you for your reply

  • Hi Howard,

    Following up with the question about the dimension, since the spacing for all the patients are different in mm, if we resample it to a fix spacing, say 1x1x1mm, the output dimension of both resampling for each patient will be different (e.g. Shape before resampling (145, 512, 512) Shape after resampling (362, 370, 370)). For convolutional neural network, we usually need a fix size of data, can you explain a little bit more how to get it to a fix size without resizing/downsample the resampled output?

    Any kind of response will be appreciated, thank you.

    7 months ago

    Hi Howard Chen Sir, thanks for the tutorial which made me to understand how to deal with DICOM files, In the tutorial you have used CT scan image of Lung cancer. I’m currently working my project on BRAIN TUMOR DETECTION USING MRI AND MACHINE LEARNING TECHNIQUES, where i used MRI images of brain.
    I’m not understanding how to preprocess them and then do segmentation. Can you please help me how to do it if you have any tutorial related to my problem to solve it. It would be very helpful if you provide me with code in python language (Spyder).
    anyone who worked on MRI BRAIN TUMOR DICOM help me out.

    Mail ID: sai4vanam@gmail.com

    Any kind of response will be appreciated, Thank you !

  • Hi,
    If you can explain to me better the concept of mask
    thank you in advance

    • Hi Nour,

      The mask is a two dimension array with zeroes and ones. When you do an element-wise multiplication to an image of same dimensions the corresponding 0’s will be zeroes out while the 1’s will take on the pixel value of the image. It is a way to “crop out” and discard areas of an image that you don’t need or to only keep the area that you do need. Hope this helps!

      • Hello Howard,
        Yes thank you that helped me a lot

        so the resized and segmented images will be saved from this line (np.save (output_path + “maskedimages_% d.npy”% (id), imgs)) it’s them we will go to CNN algorithm ??

        Thank you for your answers

        • I believe imgs here should be the numpy array from masked_lung, and then the saved images go to CNN. Is that correct, Howard?

  • Hi, Howard,
    We try to follow your steps to get the 3D image and after we check the dicom file, we almost abandon XD
    A 11.8 TB file is too big for us to download and operate.
    Do you have any smaller file with the similar features?

  • Hello Howard,

    First of all, thanks for your tutorial. I would like to know how to save the images that have undergone the masking process and recreate a 3D volume rendering from these masked images with plotly.

    I tried :

    np.save (output_path + “maskedimages_% d.npy”% (id), np.asarray (masked_lung)) with masked_lung the list of imgs_after_resamp that has been masked.

    And I’m trying to create the plotly dynamic graph with:

    imgs_to_process = np.load (output_path + “maskedimages_% d.npy”% (id))
    v, f = make_mesh (imgs_to_process)
    plotly_3d (v, f)

    But I get the error:

    ValueError Traceback (most recent call last)
          1 imgs_to_process = np.load (output_path + “maskedimages_% d.npy”% (id))
    —-> 2 v, f = make_mesh (imgs_to_process)
          3 plotly_3d (v, f)

    in make_mesh (image, threshold, step_size)
          4 from skimage import measure
    —-> 6 greens, faces, norm, val = measure.marching_cubes_lewiner (p, threshold, step_size = step_size, allow_degenerate = True)
          7 return green, faces

    ~ \ AppData \ Local \ Continuum \ anaconda3 \ lib \ site-packages \ skimage \ measure \ _marching_cubes_lewiner.py in marching_cubes_lewiner (volume, level, spacing, gradient_direction, step_size, allow_degenerate, use_classic)
        133 level = float (level)
        If volume <volume.min () or level> volume.max ():
    -> 135 raise ValueError (“Surface level must be within range data range.”)
        136 # spacing
        137 if len (spacing)! = 3:

    ValueError: Surface level must be within volume range.

    • Hi Celia, sorry I am not sure how to fix your error becuase I don’t see the content that caused it here. It looks like you put through make_mesh a different array so it’d depend on the content of that array. I would probably recommend paying attention to the dimensions of your mask array and make sure dimension is the same as the actual images as a first step. Hope this helps.

  • Rômulo José Bignetti Veloso
    5 months ago

    Hi Howard Chen!

    I need your help in how to call a image, like in this code

    import numpy
    from PIL import Image

    def median_filter(data, filter_size):
    temp = []
    indexer = filter_size // 2
    data_final = []
    data_final = numpy.zeros((len(data),len(data[0])))
    for i in range(len(data)):

        for j in range(len(data[0])):
            for z in range(filter_size):
                if i + z - indexer < 0 or i + z - indexer > len(data) - 1:
                    for c in range(filter_size):
                    if j + z - indexer < 0 or j + indexer > len(data[0]) - 1:
                        for k in range(filter_size):
                            temp.append(data[i + z - indexer][j + k - indexer])
            data_final[i][j] = temp[len(temp) // 2]
            temp = []
    return data_final

    def main():
    img = Image.open(“File name.extension”).convert(“L”)
    arr = numpy.array(Image.open(“File name.extension”))
    removed_noise = median_filter(arr, 4)
    img = Image.fromarray(removed_noise)



    I would love to know how do i can do this with DICOM images, save DICOM images, how to use Pydicom to load a image and then save it for example.

    Thanks for your Attetion!

    • Rômulo, early in this tutorial there is a section on how to read in DICOM images with pydicom. Take a look. Once you get to the pixel data, you can convert to numpy arrays described.

      • Rômulo José Bignetti Veloso
        4 months ago

        Greetings Howard, Thanks for your answer, but i really need a Median Filter for Dicom images, do you got any tips for me? or any code that you know that is close to a Median Filter that i can take as mold to my Science Project? i would really appreciate your help, i’m from Brazil and i have a strong passion for Python programming.

        • Once you have a numpy array, you can easily apply a median filter to it using scipy.signal.medfilt or scipy.ndimage.median_filter

  • Yeong-min Jang
    4 months ago

    Hi, Howard

    I try your ‘DICOM Processing and Segmentation in Python’.

    but part of Helper Functions printed error message.

    Error message is AttributeError: ‘FileDataset’ object has no attribute ‘RescaleIntercept’

    I search google this error, but I could not solve it.

    Can you help me?

  • Hello Howard,

    Amazing tutorial, thank you !
    I have a question about the mask.
    If I wanted to extract the heart instead of the lungs, What would be the differents ?
    I tried to change the mask by shrinking the focus (the middle array in the code) but it didn’t change anything.
    Am I modifying the wrong element ?
    Or is this methode only for lung and it’s not applicable to sof tissues ?
    Thank you in advance

  • Hi
    thank you for this tutorials, interested

  • Have issues when I run the helper functions:

    StopIteration Traceback (most recent call last)
    ~/anaconda3/lib/python3.7/site-packages/dicom/filereader.py in data_element_generator(fp, is_implicit_VR, is_little_endian, stop_when, defer_size, encoding)
    206 fp.seek(value_tell – rewind_length)
    –> 207 raise StopIteration


    The above exception was the direct cause of the following exception:

    RuntimeError Traceback (most recent call last)
    1 id=0
    —-> 2 patient = load_scan(data_path)
    3 imgs = get_pixels_hu(patient)

    in load_scan(path)
    5 def load_scan(path):
    —-> 6 slices = [dicom.read_file(path + ‘/’ + s) for s in os.listdir(path)]
    7 slices.sort(key = lambda x: int(x.InstanceNumber))
    8 try:

    in (.0)
    5 def load_scan(path):
    —-> 6 slices = [dicom.read_file(path + ‘/’ + s) for s in os.listdir(path)]
    7 slices.sort(key = lambda x: int(x.InstanceNumber))
    8 try:

    ~/anaconda3/lib/python3.7/site-packages/dicom/filereader.py in read_file(fp, defer_size, stop_before_pixels, force)
    612 try:
    613 dataset = read_partial(fp, stop_when, defer_size=defer_size,
    –> 614 force=force)
    615 finally:
    616 if not caller_owns_file:

    ~/anaconda3/lib/python3.7/site-packages/dicom/filereader.py in read_partial(fileobj, stop_when, defer_size, force)
    519 is_little_endian = True
    520 if preamble:
    –> 521 file_meta_dataset = _read_file_meta_info(fileobj)
    522 transfer_syntax = file_meta_dataset.TransferSyntaxUID
    523 if transfer_syntax == dicom.UID.ImplicitVRLittleEndian:

    ~/anaconda3/lib/python3.7/site-packages/dicom/filereader.py in _read_file_meta_info(fp)
    445 fp.seek(fp_save)
    446 file_meta = read_dataset(fp, is_implicit_VR=False,
    –> 447 is_little_endian=True, stop_when=not_group2)
    448 fp_now = fp.tell()
    449 if expected_ds_start and fp_now != expected_ds_start:

    ~/anaconda3/lib/python3.7/site-packages/dicom/filereader.py in read_dataset(fp, is_implicit_VR, is_little_endian, bytelength, stop_when, defer_size, parent_encoding)
    303 try:
    304 while (bytelength is None) or (fp.tell() – fpStart < bytelength):
    –> 305 raw_data_element = next(de_gen)
    306 # Read data elements. Stop on some errors, but return what was read
    307 tag = raw_data_element.tag

    RuntimeError: generator raised StopIteration

  • Hello Howard,

    I have some puzzles about the following codes, which convert pixel values to HU:

    intercept = scans[0].RescaleIntercept
    slope = scans[0].RescaleSlope

    if slope != 1:
    image = slope * image.astype(np.float64)
    image = image.astype(np.int16)

    I try to print the values of intercept and slope, and find their values are not real numbers but objects belonging to ‘pydicom.valuerep.DSfloat’. In this case, the if-statement will never be executed.

    Could you give me some explanations? Thanks!

  • Thanks so much for this, it has been super useful.

    Here are some of the minor modifications I have made to the code to get it to run in June 2019 with Python 3:

    • Add brackets to print statements if using Python 3.
    • "spacing = map(float, ([scan[0].SliceThickness] + scan[0].PixelSpacing))"
    "spacing = map(float, ([scan[0].SliceThickness] + list(scan[0].PixelSpacing)))"
    • Replace "marching_cubes" with "marching_cubes.marching_cubes_lewiner"
    • Change "mesh.set_axis_bgcolor" to "mesh.set_facecolor"
    • Change "from plotly.tools import FigureFactory as ff" to "from plotly import figure_factory as FF"
    • I'm not sure this line is necessary:  from plotly.graph_objs import *
    • Hello, Luke!

      Thanks for your modification. I fix all the bugs. But I have a none-bug problem. I would appreciate if you could give me a hand.

      I tried to save resampled 3D image as DCM files using the following codes:

      img_s, img_r, img_c = image.shape #image is the 3D image after resampling
      image = image.astype(np.uint16)
      slice_tmp = slice # slice=slices[0]
      slice_tmp.SliceThickness = 1.0
      slice_tmp.SpacingBetweenSlices = 1.0
      slice_tmp.Rows = img_r
      slice_tmp.Columns = img_c
      slice_tmp.PixelData = image[1].tobytes()

      Then I used the MicroDicom viewer to display the saved dcm file, but found it is just a binary image (but the pixel values of image[1] are not binary) and I cannot adjust the window width and center. Do you have any idea?

  • hersheys
    2 months ago

    Hi Howard,

    Amazing insight for 3d visualization. Could you please help me with the command line ‘make_mesh(image, threshold=-300, step_size=1):’ Why are you setting the threshold to -300? If i want to visualise the soft tissue(organs of my CT image of abdomen) how do i change this part of the code accordingly?

Trackbacks & Pings

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.