Organ-aware 3D lesion segmentation dataset and pipeline for abdominal CT analysis (ACM Multimedia 2025 candidate)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ImagetoRT.py 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import tempfile
  2. import datetime
  3. import numpy as np
  4. import pydicom
  5. from pydicom.dataset import Dataset, FileDataset
  6. from organList import * # "Organ" and "color_table"
  7. class ImagetoRT():
  8. def __init__(self, DataBase, DICOMInformation, DICOM_RT, AILabel):
  9. print('init RT Info.')
  10. self.DataBase = DataBase
  11. # self.items = items
  12. self.DICOMInformation = DICOMInformation
  13. self.numberOfImage = len(DICOMInformation)
  14. self.itemLen = len(AILabel)
  15. self.DataBaseLen = len(DataBase)
  16. self.DICOM_RT = DICOM_RT
  17. self.ROINumberStart = len(AILabel)
  18. self.AILabel = [ 'MONAI_'+labelName for labelName in AILabel]
  19. #print(self.AILabel)
  20. def __call__(self):
  21. self.setStructureSetROISequence()
  22. self.setROIContourSequence()
  23. self.setRTROIObservationsSequence()
  24. # self.setReferencedFrameOfReferenceSequence()
  25. print('set done.')
  26. return self.DICOM_RT
  27. def setROIContourSequence(self):
  28. print('set ROI Contour Sequence.' )
  29. ROINumber = 500
  30. #print(len(self.DICOM_RT.ROIContourSequence))
  31. for i in range(self.DataBaseLen):
  32. MyROIContourSequence = pydicom.Dataset()
  33. ROINumber = ROINumber + 1
  34. MyROIContourSequence.ROINumber = ROINumber
  35. MyROIContourSequence.ReferencedROINumber = ROINumber
  36. MyROIContourSequence.ObservationNumber = ROINumber
  37. organ = str(self.DataBase[i][0])
  38. ContourSequence = self.getContourSequence(self.DataBase[i][0])
  39. #print(ContourSequence)
  40. MyROIContourSequence.ContourSequence = ContourSequence
  41. # color = self.DisplayColor(organ)
  42. color = color_table[organ]
  43. MyROIContourSequence.ROIDisplayColor = color
  44. self.DICOM_RT.ROIContourSequence.append(MyROIContourSequence)
  45. # print(MyROIContourSequence)
  46. # def DisplayColor(self ,organ):
  47. # if organ == 'AILung-L' or organ == 'AILung-R' :
  48. # color = [255,174,53]
  49. # elif organ == 'AILiver' :
  50. # color = [243,201,73]
  51. # elif organ == 'AIStomach' :
  52. # color = [160,0,160]
  53. # elif organ == 'AIEsophagus' :
  54. # color = [170,255,170]
  55. # elif organ == 'AIHeart' :
  56. # color = [176,255,255]
  57. # elif organ == 'AIKidney-L' or organ == 'AIKidney-R' :
  58. # color = [0,102,0]
  59. # return color
  60. def getDataCoordination(self, name):
  61. l = len(self.DataBase)
  62. # assert l==self.itemLen, 'MONAI_tag沒對應到資料夾'
  63. for i in range(self.itemLen):
  64. #print(self.DataBase[i][0])
  65. if(self.DataBase[i][0] == name):
  66. data = self.DataBase[i][1]
  67. break
  68. return data
  69. def getSOPInstanceUID(self, z_axis):
  70. SOPInstanceUID = -1
  71. for i in range(self.numberOfImage):
  72. # print(i)
  73. # print(self.DICOMInformation[i].SliceLocation, z_axis)
  74. # print(self.DICOMInformation[i].SOPInstanceUID)
  75. if(self.DICOMInformation[i].SliceLocation == z_axis):
  76. SOPInstanceUID = self.DICOMInformation[i].SOPInstanceUID
  77. break
  78. return SOPInstanceUID
  79. def getContourSequence(self, itemName):
  80. print('get Contour Sequence.' )
  81. #print(itemName)
  82. contourData = self.getDataCoordination(itemName)
  83. AllContourSequence = []
  84. # slice
  85. for numberOfContour in range(len(contourData)-1, -1, -1):
  86. # print(numberOfContour)
  87. data = contourData[numberOfContour]
  88. # contour pixel point
  89. for i in range(len(data)):
  90. pixelData = np.array(data[i]).reshape(-1)
  91. z_axis = pixelData[2]
  92. contourImageSequence = pydicom.Dataset()
  93. contourImageSequence.ReferencedSOPClassUID = "1.2.840.10008.5.1.4.1.1.2"
  94. contourImageSequence.ReferencedSOPInstanceUID = self.getSOPInstanceUID(z_axis)
  95. contourSequence = pydicom.Dataset()
  96. contourSequence.ContourImageSequence = [contourImageSequence]
  97. contourSequence.ContourGeometricType = "CLOSED_PLANAR"
  98. contourSequence.NumberOfContourPoints = len(data[i])
  99. contourSequence.ContourData = list(pixelData)
  100. AllContourSequence.append(contourSequence)
  101. return AllContourSequence
  102. def setRTROIObservationsSequence(self):
  103. print('set RT ROI Observations Sequence.' )
  104. ROINumber = 500
  105. for i in range(self.DataBaseLen):
  106. ROINumber = ROINumber + 1
  107. RTROIObservations = Dataset()
  108. RTROIObservations.ObservationNumber = ROINumber
  109. RTROIObservations.ROIInterpreter = ""
  110. RTROIObservations.RTROIInterpretedType = "ORGAN"
  111. RTROIObservations.ReferencedROINumber = ROINumber
  112. RTROIObservations.ROIObservationLabel = self.DataBase[i][0]
  113. self.DICOM_RT.RTROIObservationsSequence.append(RTROIObservations)
  114. def setStructureSetROISequence(self):
  115. print('set Structure Set ROI Sequence.')
  116. ROINumber = 500
  117. # items = self.items
  118. for i in range(self.DataBaseLen):
  119. ROINumber = ROINumber + 1
  120. structureSetROI = Dataset()
  121. structureSetROI.ROIGenerationAlgorithm = 'MANUAL'
  122. structureSetROI.ROIName = self.DataBase[i][0]
  123. #print(structureSetROI.ROIName)
  124. structureSetROI.ROINumber = ROINumber
  125. structureSetROI.ReferencedFrameOfReferenceUID = self.DICOMInformation[0].FrameOfReferenceUID
  126. self.DICOM_RT.StructureSetROISequence.append(structureSetROI)
  127. # def setReferencedFrameOfReferenceSequence(self):
  128. # print('set Referenced Frame Of Reference Sequence.')
  129. # ReferencedFrameOfReference = Dataset()
  130. # ReferencedFrameOfReference.FrameOfReferenceUID = self.DICOMInformation[0].FrameOfReferenceUID
  131. # rtReferencedStudySequence = self.getRTReferencedStudySequence()
  132. # ReferencedFrameOfReference.RTReferencedStudySequence = [rtReferencedStudySequence]
  133. # self.ds.ReferencedFrameOfReferenceSequence.append(ReferencedFrameOfReference)
  134. # def getRTReferencedStudySequence(self):
  135. # RTReferencedStudy = Dataset()
  136. # RTReferencedSeries = Dataset()
  137. # contourImageSequence = self.getContourImageSequence()
  138. # RTReferencedSeries.ContourImageSequence = contourImageSequence
  139. # RTReferencedSeries.SeriesInstanceUID = "1.3.12.2.1107.5.1.4.29309.30000015101602373771800000464"
  140. # RTReferencedStudy.RTReferencedSeriesSequence = [RTReferencedSeries]
  141. # RTReferencedStudy.ReferencedSOPClassUID = "1.2.840.10008.3.1.2.3.2"
  142. # RTReferencedStudy.ReferencedSOPInstanceUID = "1.2.410.200010.886.1140030012.68041014924942071"
  143. # return RTReferencedStudy
  144. # def getContourImageSequence(self):
  145. # contourImageSequence = []
  146. # for i in range(self.numberOfImage):
  147. # contourImage = Dataset()
  148. # contourImage.ReferencedSOPClassUID = self.DICOMInformation[i].file_meta.MediaStorageSOPClassUID
  149. # contourImage.ReferencedSOPInstanceUID = self.DICOMInformation[i].file_meta.MediaStorageSOPInstanceUID
  150. # contourImageSequence.append(contourImage)
  151. # return contourImageSequence