extract_suv_from_mask.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Thu Sep 29 14:51:09 2022
  4. @author: katja
  5. """
  6. import numpy
  7. import os
  8. import pandas as pd
  9. import nibabel
  10. import csv
  11. import matplotlib.pyplot as plt
  12. def organ_percentile(img, mask, level, p):
  13. #ORGAN_PERCENTILE - computes suv_x the pth percentile of the distribution of
  14. # image intensity values in img from within some ROI mask
  15. #
  16. # Inputs:
  17. # img - image. ndarray
  18. # mask - ROI mask. Must be same dimension as img. Must be binary ndarray
  19. # p - percentile. Between 0-100
  20. #
  21. # Outputs:
  22. # suv_x - percentile of distribution. Defined by:
  23. #
  24. # suv_x
  25. # p/100 = ∫ H(x) dx
  26. # 0
  27. #
  28. # where H(x) is the normalized distribution of image values within mask
  29. #img = np.array(img)
  30. #mask = np.array(mask)
  31. h = img[mask == level]
  32. print("Extracting SUV% for organ", level)
  33. #histo=[]
  34. # col=["red", "green", "yellow","pink", "brown", "darkblue", "black", "purple"]
  35. # i=level
  36. # plt.hist(h, color= col[i-1],bins=50, range=(0,6))
  37. # plt.title("Histogram of SUV values for "+ str(level))
  38. # plt.show()
  39. suv_x = numpy.percentile(h, p)
  40. return suv_x
  41. def main():
  42. path = r"C:/Users/strah/OneDrive/Namizje/Raziskave/Melanoma/Retrospective/" #path to folder in which patient images are
  43. inputCSV = os.path.join(path, 'cases_retroMManon.csv') #input csv file that has the path to each patient image
  44. #Returns concatinated sequnces of evenly spaced numbers over a specified interval - for SUV percentile
  45. pv=numpy.concatenate((numpy.linspace(10,50,5),
  46. numpy.linspace(55,80,6),
  47. numpy.linspace(82,90,5),
  48. numpy.linspace(91,100,10)))
  49. pvi=pv.astype(int) #have to be indigers to be able to append to name
  50. col_names = ["SUV" + str(x) for x in pvi]
  51. flists = []
  52. with open(inputCSV, 'r') as inFile: #goes trough the whole csv file and makes an flist (list)
  53. cr = csv.DictReader(inFile, lineterminator='\n')
  54. flists = [row for row in cr]
  55. alldata=[]
  56. histo=[]
  57. for idx, entry in enumerate(flists, start=1): #
  58. PET = entry['Image']
  59. Seg = entry['Mask']
  60. Visit = entry['Visit']
  61. ID = entry['ID']
  62. #open PET image and segmentation
  63. niPET=nibabel.load(PET)
  64. niSeg=nibabel.load(Seg)
  65. print(" Processing Patient, Visit , (Image: , Mask:)", idx, len(flists), Visit, entry['Image'], entry['Mask'])
  66. #In nnU-Net (organ segmentation are numbered):
  67. #1 liver #DM
  68. #2 spleen #DM
  69. #3 lungs #DM
  70. #4 thyroid #DM
  71. #5 bowel # DM 16
  72. #6 pancreas
  73. #7 bladder
  74. #8 kidneys
  75. #extract SUV percentiles from PET image with mask - segmentation
  76. for level in [1,2,3,4,5,6,7,8]:
  77. v=organ_percentile(niPET.get_fdata(),niSeg.get_fdata(),level,pv)
  78. mat=[level,ID, Visit]
  79. mat=numpy.concatenate((mat,v))
  80. alldata.append(mat)
  81. # plt.hist(histo, bins=5, range=(0,6))
  82. # plt.title("Histogram of SUV values for Spleen")
  83. # plt.show()
  84. #print("Percentile, value: ", mat)
  85. #print(alldata)
  86. # plt.hist(h, bins=50, range=(0,6))
  87. # plt.show()
  88. Names=["Organ", "PatientID", "Visit"]
  89. Names=numpy.concatenate((Names,col_names))
  90. #make a dataframe to write the data than in excel - that can be read by another script
  91. df=pd.DataFrame(alldata,columns=Names)
  92. df.to_excel('C:/Users/strah/OneDrive/Namizje/Raziskave/Melanoma/Retrospective/percentilesAnon.xlsx', index=None) #path to where you want to save excel
  93. print("Done.")
  94. if __name__ == '__main__':
  95. main()