lesliemwubbel

Lecture 001 - code

Jan 23rd, 2021
4,554
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.22 KB | None | 0 0
  1. import numpy as np
  2. from pydicom import dcmread
  3.  
  4. DICOM_file_path = 'D:\DICOM files\PAT001\D0150.dcm'
  5.  
  6. DICOM_file = dcmread(DICOM_file_path)
  7. print(DICOM_file)
  8.  
  9. ## DICOM_file is FileDataSet object with attributes that match the meta data
  10. print("class object from pydicom ->", type(DICOM_file))
  11.  
  12.  
  13. # plot the image using matplotlib
  14. import matplotlib.pyplot as plt
  15.  
  16. plt.imshow(DICOM_file.pixel_array, cmap=plt.cm.gray)
  17. plt.show()
  18.  
  19. ## Lets see pixel values
  20. print(DICOM_file.pixel_array)
  21. # from DataScienceDeck.preprocessing.preprocessing import load_scan
  22.  
  23. # pathway = 'D:\DICOM files\PAT001'
  24.  
  25. # x = load_scan(pathway)
  26. # print(x)
  27.  
  28. # from DataScienceDeck.preprocessing.preprocessing import load_scan
  29. import numpy as np
  30. import os
  31. from pydicom import dcmread
  32.  
  33. def load_scan(path):
  34.     print("Loading scan", path)
  35.     slices = [dcmread(path + '/' + s) for s in os.listdir(path)]
  36.     slices.sort(key = lambda x: float(x.ImagePositionPatient[2]))
  37.  
  38.     if slices[0].ImagePositionPatient[2] == slices[1].ImagePositionPatient[2]:
  39.         sec_num = 2;
  40.         while slices[0].ImagePositionPatient[2] == slices[sec_num].ImagePositionPatient[2]:
  41.             sec_num = sec_num+1;
  42.         slice_num = int(len(slices) / sec_num)
  43.         slices.sort(key = lambda x:float(x.InstanceNumber))
  44.         slices = slices[0:slice_num]
  45.         slices.sort(key = lambda x:float(x.ImagePositionPatient[2]))
  46.  
  47.     try:
  48.         slice_thickness = np.abs(slices[0].ImagePositionPatient[2] - slices[1].ImagePositionPatient[2])
  49.     except:
  50.         slice_thickness = np.abs(slices[0].SliceLocation - slices[1].SliceLocation)
  51.        
  52.     for s in slices:
  53.         s.SliceThickness = slice_thickness
  54.        
  55.     return slices # list of DICOM
  56.  
  57. pathway = 'D:\DICOM files\PAT001'
  58.  
  59. All_DICOM_FILES = load_scan(pathway)
  60. #print(All_DICOM_FILES)
  61.  
  62. # Now here we can for loop over all the DICOM files
  63. pixel_ds = []
  64.  
  65. for files in All_DICOM_FILES:
  66.     pixel_numpy = files.pixel_array
  67.     pixel_ds.append(pixel_numpy)
  68.  
  69. print(pixel_ds)
  70.  
  71. def get_pixels_hu(slices):
  72.     print("get pixels converted to HU")
  73.     image = np.stack([s.pixel_array for s in slices])
  74.     # Convert to int16 (from sometimes int16),
  75.     # should be possible as values should always be low enough (<32k)
  76.     image = image.astype(np.int16)
  77.    
  78.     # Convert to Hounsfield units (HU)
  79.     for slice_number in range(len(slices)):        
  80.         intercept = slices[slice_number].RescaleIntercept ## DICOM metadata attribute call
  81.         slope = slices[slice_number].RescaleSlope         ## DICOM metadata attribute call
  82.        
  83.         if slope != 1:
  84.             image[slice_number] = slope * image[slice_number].astype(np.float64)
  85.             image[slice_number] = image[slice_number].astype(np.int16)
  86.            
  87.         image[slice_number] += np.int16(intercept)
  88.  
  89.     case_pixels = np.array(image, dtype=np.int16)
  90.     pixel_spacing = np.array([slices[0].SliceThickness, slices[0].PixelSpacing[0], slices[0].PixelSpacing[1]], dtype=np.float32)
  91.     return case_pixels, pixel_spacing
  92.  
  93.  
  94. ####  get_pixels_hus converting pixel values to HU values
  95. patient_pixels, pixel_spacing = get_pixels_hu(All_DICOM_FILES)
  96.  
  97. #### Code plots the slice 150
  98. import matplotlib.pyplot as plt
  99. plt.hist(patient_pixels[150].flatten(), bins=80, color='c')
  100. plt.xlabel("Hounsfield Units (HU)")
  101. plt.ylabel("Frequency")
  102. plt.show()
  103.  
  104. plt.imshow(patient_pixels[150], cmap=plt.cm.gray)
  105. plt.show()
  106.  
  107. ### cide runs for slice 1
  108. plt.hist(patient_pixels[1].flatten(), bins=80, color='c')
  109. plt.xlabel("Hounsfield Units (HU)")
  110. plt.ylabel("Frequency")
  111. plt.show()
  112. # # Show some slice in the middle
  113. plt.imshow(patient_pixels[1], cmap=plt.cm.gray)
  114. plt.show()
  115.  
  116. ## mount google drive, be careful limited space on my google drive
  117. from google.colab import drive
  118. drive.mount('/content/drive/')
  119.  
  120. !pip install pydicom
  121. #https://www.raddq.com/dicom-processing-segmentation-visualization-in-python/
  122. #https://www.kaggle.com/sentdex/first-pass-through-data-w-3d-convnet
  123. #https://numpy.org/doc/stable/reference/index.html#module-numpy
  124. #https://docs.scipy.org/doc/scipy/reference/ndimage.html#module-scipy.ndimage
  125. #https://docs.scipy.org/doc/scipy/reference/tutorial/general.html
  126.  
  127. import numpy as np
  128. import pydicom
  129. import matplotlib as mpl
  130. import matplotlib.pyplot as plt
  131. import numpy as np
  132. import scipy.io
  133.  
  134. from pydicom import dcmread
  135.  
  136.  
  137. ## skimage algorithms for image processing
  138. from skimage import morphology
  139. from skimage import measure
  140. from skimage.transform import resize
  141. from sklearn.cluster import KMeans
  142.  
  143. ## plotly
  144. from plotly import __version__
  145. from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
  146. from plotly.tools import FigureFactory as FF
  147. from plotly.graph_objs import *
  148. import plotly.graph_objects as go
  149. init_notebook_mode(connected=True)
  150.  
  151. from sklearn.cluster import KMeans
  152.  
  153.  
  154. def make_lungmask(img, display=False):
  155.     row_size= img.shape[0]
  156.     col_size = img.shape[1]
  157.     mean = np.mean(img)
  158.     std = np.std(img)
  159.     img = (img-mean)/std # Subtracts mean and divide standard deviation from each element ## Standardises the whole data
  160.  
  161.     # Find the average pixel value near the lungs
  162.     # to renormalize washed out images
  163.     middle = img
  164.     # middle = img[int(col_size/5):int(col_size/5*4),int(row_size/5):int(row_size/5*4)]
  165.     print(middle)
  166.     print(middle.shape)
  167.    
  168.     mean = np.mean(middle)  
  169.     max = np.max(img)
  170.     min = np.min(img)
  171.  
  172.     # To improve threshold finding, I'm moving the
  173.     # underflow and overflow on the pixel spectrum
  174.     img[img==max]=mean # Goes through the list and if anything equals max, it changes its value to mean.
  175.     img[img==min]=mean # Goes through the list and if anything equals min, it changes its value to mean.
  176.  
  177.     # Using Kmeans to separate foreground (soft tissue / bone) and background (lung/air)
  178.     #sensitive to outliers and noise Kmeans could be really bad
  179.     # https://www.youtube.com/watch?v=_aWzGGNrcic
  180.     kmeans = KMeans(n_clusters=2).fit(np.reshape(middle,[np.prod(middle.shape),1]))
  181.     centers = sorted(kmeans.cluster_centers_.flatten())
  182.    
  183.     threshold = np.mean(centers)
  184.     thresh_img = np.where(img<threshold,1.0,0.0)  # threshold the image
  185.  
  186.  
  187.     # First erode away the finer elements, then dilate to include some of the pixels surrounding the lung.  
  188.     # We don't want to accidentally clip the lung.
  189.  
  190.     eroded = morphology.erosion(thresh_img,np.ones([3,3]))
  191.     dilation = morphology.dilation(eroded,np.ones([8,8]))
  192.  
  193.   ## START here
  194.     labels = measure.label(dilation)
  195.     # Different labels are displayed in different colors
  196.  
  197.     label_vals = np.unique(labels)
  198.     ## ok region props what is this
  199.     regions = measure.regionprops(labels)
  200.     good_labels = []
  201.    
  202. # what is this SECTION OF CODE??
  203. # why is it ommitting half the lung
  204.     for prop in regions:
  205.         B = prop.bbox
  206.         good_labels.append(prop.label)
  207.  
  208.         # if B[2]-B[0]<row_size/10*9 and B[3]-B[1]<col_size/10*9 and B[0]>row_size/5 and B[2]<col_size/5*4:
  209.         #     good_labels.append(prop.label)
  210.     mask = np.ndarray([row_size,col_size],dtype=np.int8)
  211.     mask[:] = 0
  212.  
  213.     #  After just the lungs are left, we do another large dilation
  214.     #  in order to fill in and out the lung mask
  215.     for N in good_labels:
  216.         mask = mask + np.where(labels==N,1,0)
  217.     mask = morphology.dilation(mask,np.ones([10,10])) # one last dilation
  218.  
  219.     if (display):
  220.         fig, ax = plt.subplots(3, 2, figsize=[12, 12])
  221.         ax[0, 0].set_title("Original")
  222.         ax[0, 0].imshow(img, cmap='gray')
  223.         ax[0, 0].axis('off')
  224.         ax[0, 1].set_title("Threshold")
  225.         ax[0, 1].imshow(thresh_img, cmap='gray')
  226.         ax[0, 1].axis('off')
  227.         ax[1, 0].set_title("After Erosion and Dilation")
  228.         ax[1, 0].imshow(dilation, cmap='gray')
  229.         ax[1, 0].axis('off')
  230.         ## Labels so after labels some parts disppear at the 1-30
  231.         ax[1, 1].set_title("Color Labels")
  232.         ax[1, 1].imshow(labels)
  233.         ax[1, 1].axis('off')
  234.  
  235.         ## cuts off body cavity at 50 - 140 WHY!!?!?!
  236.         ax[2, 0].set_title("Final Mask")
  237.         ax[2, 0].imshow(mask, cmap='gray')
  238.         ax[2, 0].axis('off')
  239.         ax[2, 1].set_title("Apply Mask on Original")
  240.         ax[2, 1].imshow(mask*img, cmap='gray')
  241.         ax[2, 1].axis('off')
  242.        
  243.         plt.show()
  244.     return mask*img
  245.  
  246. #data_dir = "/content/drive/My Drive/Vessel Outline storage/Input_data/Stats data/data_filePAT001.npy"
  247. data_dir = "/content/drive/My Drive/Vessel Outline storage/Input data/Stats data/data_filePAT001.npy"
  248.  
  249. ## PAT001
  250. img_after_samples = np.load(data_dir)
  251.  
  252. #print(img_after_samples)
  253. ## size of array also
  254. len_of_img = len(img_after_samples)
  255. print("Number of slices" ,len_of_img)
  256. #print(img_after_samples) ## 3D dimsions
  257. ## step though by changing this number in img_after_samples
  258. ## could implement slice range with for loop for number in img_after_samples
  259. slice_num = 140
  260. slice_single = img_after_samples[slice_num]
  261. print(slice_single)
  262. print(slice_single.shape)
  263. #print("Slice number: ", slice_num + 1)
  264. slice_one = make_lungmask(slice_single, display=True)
  265.  
  266. #for img in img_after_samples:
  267.  #make_lungmask(img, display=True)
  268. #https://scikit-learn.org/stable/modules/generated/sklearn.cluster.SpectralClustering.html
  269.  
Advertisement
Add Comment
Please, Sign In to add comment