def BuildJsonInstanceFromPng( self, image: bytes, sop_class_uid: Text) -> dicom_json.ObjectWithBulkData: """Builds and returns a DICOM instance from a PNG. This function will create a new DICOM study and series. Converts all incoming images to grayscale. Args: image: Image bytes of DICOM instance. sop_class_uid: UID of the SOP class for DICOM instance. Returns: DICOM JSON Object containing JSON and bulk data of the Secondary Capture. """ study_uid = self.GenerateUID() series_uid = self.GenerateUID() instance_uid = self.GenerateUID() metadata_json = {} dicom_json.Insert(metadata_json, tags.PLANAR_CONFIGURATION, 0) # Converts colored images to grayscale. dicom_json.Insert(metadata_json, tags.PHOTOMETRIC_INTERPRETATION, 'MONOCHROME2') dicom_json.Insert(metadata_json, tags.SOP_CLASS_UID, sop_class_uid) dicom_json.Insert(metadata_json, tags.STUDY_INSTANCE_UID, study_uid) dicom_json.Insert(metadata_json, tags.SERIES_INSTANCE_UID, series_uid) dicom_json.Insert(metadata_json, tags.SPECIFIC_CHARACTER_SET, _ISO_CHARACTER_SET) dicom_json.Insert(metadata_json, tags.SOP_INSTANCE_UID, instance_uid) dicom_json.Insert(metadata_json, tags.TRANSFER_SYNTAX_UID, _EXPLICIT_VR_LITTLE_ENDIAN) dicom_json.Insert(metadata_json, tags.MEDIA_STORAGE_SOP_CLASS_UID, sop_class_uid) dicom_json.Insert(metadata_json, tags.MEDIA_STORAGE_SOP_INSTANCE_UID, instance_uid) # Assures URI is unique. uri = '{}/{}/{}'.format(study_uid, series_uid, instance_uid) metadata_json[tags.PIXEL_DATA.number] = { 'vr': tags.PIXEL_DATA.vr, 'BulkDataURI': uri } bulkdata = dicom_web.DicomBulkData( uri=uri, data=image, content_type='image/png; transfer-syntax=""') return dicom_json.ObjectWithBulkData(metadata_json, [bulkdata])
def testObjectWithBulkData(self): """Tests methods of ObjectWithBulkData class.""" # Construct dicom_json.ObjectWithBulkData object dicom_dict = dict() instance_uid = 'instance_uid' study_uid = 'study_uid' series_uid = 'series_uid' dicom_json.Insert(dicom_dict, tags.SOP_INSTANCE_UID, instance_uid) dicom_json.Insert(dicom_dict, tags.STUDY_INSTANCE_UID, study_uid) dicom_json.Insert(dicom_dict, tags.SERIES_INSTANCE_UID, series_uid) bulkdata = dicom_web.DicomBulkData( uri='uri', data=bytearray('image_array', encoding='utf8'), content_type='type') bulkdata_list = [bulkdata] dicom_object = dicom_json.ObjectWithBulkData(dicom_dict, bulkdata_list) # Test properties self.assertEqual(dicom_object.instance_uid, instance_uid) self.assertEqual(dicom_object.series_uid, series_uid) self.assertEqual(dicom_object.study_uid, study_uid)
def CreateMockStudyJsonResponse(study_uid: Text) -> Dict[Text, Any]: """Creates a Dict representing a DICOM JSON response to a Study Level QIDO.""" study_json = {} dicom_json.Insert(study_json, tags.ACCESSION_NUMBER, _ACCESSION_NUMBER) dicom_json.Insert(study_json, tags.STUDY_INSTANCE_UID, study_uid) dicom_json.Insert(study_json, tags.STUDY_ID, _STUDY_ID) dicom_json.Insert(study_json, tags.STUDY_DATE, _STUDY_DATE) dicom_json.Insert(study_json, tags.STUDY_DESCRIPTION, _STUDY_DESCRIPTION) dicom_json.Insert(study_json, tags.REFERRING_PHYSICIAN_NAME, _REFERRING_PHYSICIAN_NAME) dicom_json.Insert(study_json, tags.STUDY_TIME, _STUDY_TIME) dicom_json.Insert(study_json, tags.PATIENT_BIRTH_DATE, _PATIENT_BIRTH_DATE) dicom_json.Insert(study_json, tags.PATIENT_BIRTH_TIME, _PATIENT_BIRTH_TIME) dicom_json.Insert(study_json, tags.PATIENT_NAME, _PATIENT_NAME) dicom_json.Insert(study_json, tags.PATIENT_ID, _PATIENT_ID) dicom_json.Insert(study_json, tags.PATIENT_SEX, _PATIENT_SEX) dicom_json.Insert(study_json, tags.PATIENT_AGE, _PATIENT_AGE) dicom_json.Insert(study_json, tags.PATIENT_SIZE, _PATIENT_SIZE) dicom_json.Insert(study_json, tags.PATIENT_WEIGHT, _PATIENT_WEIGHT) dicom_json.Insert(study_json, tags.NAME_OF_PHYSICIAN_READING_STUDY, _NAME_OF_PHYSICIAN_READING) dicom_json.Insert(study_json, tags.ADMITTING_DIAGNOSES_DESCRIPTION, _ADMITTING_DIAGNOSES_DESCRIPTION) dicom_json.Insert(study_json, tags.ISSUER_OF_PATIENT_ID, _ISSUER_OF_PATIENT_ID) dicom_json.Insert(study_json, tags.OTHER_PATIENT_IDS, _OTHER_PATIENT_IDS) dicom_json.Insert(study_json, tags.OTHER_PATIENT_NAMES, _OTHER_PATIENT_NAMES) dicom_json.Insert(study_json, tags.ETHNIC_GROUP, _ETHNIC_GROUP) dicom_json.Insert(study_json, tags.OCCUPATION, _OCCUPATION) dicom_json.Insert(study_json, tags.ADDITIONAL_PATIENT_HISTORY, _ADDITIONAL_PATIENT_HISTORY) dicom_json.Insert(study_json, tags.PATIENT_COMMENTS, _PATIENT_COMMENTS) procedure_sequence = {} dicom_json.Insert(procedure_sequence, tags.CODE_VALUE, _CODE_VALUE) dicom_json.Insert(procedure_sequence, tags.CODE_SCHEME_DESIGNATOR, _CODE_SCHEME_DESIGNATOR) dicom_json.Insert(procedure_sequence, tags.CODE_SCHEME_VERSION, _CODE_SCHEME_VERSION) dicom_json.Insert(procedure_sequence, tags.CODE_MEANING, _CODE_MEANING) dicom_json.Insert(study_json, tags.PROCEDURE_CODE_SEQUENCE, procedure_sequence) referenced_study_sequence = {} dicom_json.Insert(referenced_study_sequence, tags.REFERENCED_SOP_CLASS_UID, _REFERENCED_SOP_CLASS_UID) dicom_json.Insert(referenced_study_sequence, tags.REFERENCED_SOP_INSTANCE_UID, _REFERENCED_SOP_INSTANCE_UID) dicom_json.Insert(study_json, tags.REFERENCED_STUDY_SEQUENCE, referenced_study_sequence) referenced_patient_sequence = {} dicom_json.Insert(referenced_patient_sequence, tags.REFERENCED_SOP_CLASS_UID, _REFERENCED_SOP_CLASS_UID) dicom_json.Insert(referenced_patient_sequence, tags.REFERENCED_SOP_INSTANCE_UID, _REFERENCED_SOP_INSTANCE_UID) dicom_json.Insert(study_json, tags.REFERENCED_PATIENT_SEQUENCE, referenced_patient_sequence) return study_json
def CreateMockSRDict(sr_text: Text) -> Dict[Text, Any]: """Creates a DICOM JSON dictionary representing a structured report.""" sr_dict = CreateMockStudyJsonResponse(_STUDY_UID) dicom_json.Insert(sr_dict, tags.SOP_CLASS_UID, tag_values.BASIC_TEXT_SR_CUID) dicom_json.Insert(sr_dict, tags.MODALITY, tag_values.SR_MODALITY) dicom_json.Insert(sr_dict, tags.SERIES_INSTANCE_UID, _SR_SERIES_UID) dicom_json.Insert(sr_dict, tags.SPECIFIC_CHARACTER_SET, dicom_builder._ISO_CHARACTER_SET) dicom_json.Insert(sr_dict, tags.SOP_INSTANCE_UID, _SR_INSTANCE_UID) content_json = {} dicom_json.Insert(content_json, tags.RELATIONSHIP_TYPE, 'CONTAINS') dicom_json.Insert(content_json, tags.VALUE_TYPE, 'TEXT') dicom_json.Insert(content_json, tags.TEXT_VALUE, sr_text) dicom_json.Insert(sr_dict, tags.CONTENT_SEQUENCE, content_json) dicom_json.Insert(sr_dict, tags.TRANSFER_SYNTAX_UID, dicom_builder._IMPLICIT_VR_LITTLE_ENDIAN) dicom_json.Insert(sr_dict, tags.MEDIA_STORAGE_SOP_CLASS_UID, tag_values.BASIC_TEXT_SR_CUID) dicom_json.Insert(sr_dict, tags.MEDIA_STORAGE_SOP_INSTANCE_UID, _SR_INSTANCE_UID) return sr_dict
def _CreateMockInstanceMetadata() -> Dict[Text, Any]: instance_metadata = {} dicom_json.Insert(instance_metadata, tags.STUDY_INSTANCE_UID, 1) dicom_json.Insert(instance_metadata, tags.SERIES_INSTANCE_UID, 2) dicom_json.Insert(instance_metadata, tags.SOP_INSTANCE_UID, 3) return instance_metadata
def BuildJsonSR( self, report_text: Text, metadata_json: Dict[Text, Any]) -> dicom_json.ObjectWithBulkData: """Builds and returns a Basic Text DICOM JSON Structured Report instance. This function will create a new DICOM series. Args: report_text: Text string to use for the Basic Text DICOM SR. metadata_json: Dict of tags (including study-level information) to add. Returns: DICOM JSON Object containing the Structured Report. """ # Dicom StowJsonRs expects a list with DICOM JSON as elements. # Add study level tags to the SR. dataset = metadata_json.copy() series_uid = self.GenerateUID() instance_uid = self.GenerateUID() dicom_json.Insert(dataset, tags.SOP_CLASS_UID, tag_values.BASIC_TEXT_SR_CUID) dicom_json.Insert(dataset, tags.MODALITY, tag_values.SR_MODALITY) dicom_json.Insert(dataset, tags.SERIES_INSTANCE_UID, series_uid) dicom_json.Insert(dataset, tags.SPECIFIC_CHARACTER_SET, _ISO_CHARACTER_SET) logging.log( logging.INFO, 'Creating DICOM JSON SR with Series UID: %s and Instance UID: %s', series_uid, instance_uid) dicom_json.Insert(dataset, tags.SOP_INSTANCE_UID, instance_uid) content_dataset = {} dicom_json.Insert(content_dataset, tags.RELATIONSHIP_TYPE, 'CONTAINS') dicom_json.Insert(content_dataset, tags.VALUE_TYPE, 'TEXT') dicom_json.Insert(content_dataset, tags.TEXT_VALUE, report_text) dicom_json.Insert(dataset, tags.CONTENT_SEQUENCE, content_dataset) dicom_json.Insert(dataset, tags.TRANSFER_SYNTAX_UID, _IMPLICIT_VR_LITTLE_ENDIAN) dicom_json.Insert(dataset, tags.MEDIA_STORAGE_SOP_CLASS_UID, tag_values.BASIC_TEXT_SR_CUID) dicom_json.Insert(dataset, tags.MEDIA_STORAGE_SOP_INSTANCE_UID, instance_uid) return dicom_json.ObjectWithBulkData(dataset)
def BuildJsonSC(self, image_array: np.ndarray, metadata_json: Dict[Text, Any], series_uid: Text) -> dicom_json.ObjectWithBulkData: """Builds and returns a DICOM Secondary Capture. Args: image_array: Image array (RGB) to embed in DICOM instance. metadata_json: Dict of tags (including study-level information) to add. series_uid: UID of the series to create the SC in. Returns: DICOM JSON Object containing JSON and bulk data of the Secondary Capture. """ # Copy over any study and instance level tags. instance_uid = self.GenerateUID() metadata_json = metadata_json.copy() dicom_json.Insert(metadata_json, tags.SOP_CLASS_UID, tag_values.SECONDARY_CAPTURE_CUID) dicom_json.Insert(metadata_json, tags.MODALITY, tag_values.OT_MODALITY) dicom_json.Insert(metadata_json, tags.SERIES_INSTANCE_UID, series_uid) dicom_json.Insert(metadata_json, tags.SPECIFIC_CHARACTER_SET, _ISO_CHARACTER_SET) dicom_json.Insert(metadata_json, tags.SOP_INSTANCE_UID, instance_uid) dicom_json.Insert(metadata_json, tags.TRANSFER_SYNTAX_UID, _IMPLICIT_VR_LITTLE_ENDIAN) dicom_json.Insert(metadata_json, tags.MEDIA_STORAGE_SOP_CLASS_UID, tag_values.SECONDARY_CAPTURE_CUID) dicom_json.Insert(metadata_json, tags.MEDIA_STORAGE_SOP_INSTANCE_UID, instance_uid) # Assures URI is unique. study_uid = dicom_json.GetValue(metadata_json, tags.STUDY_INSTANCE_UID) uri = '{}/{}/{}'.format(study_uid, series_uid, instance_uid) metadata_json[tags.PIXEL_DATA.number] = { 'vr': tags.PIXEL_DATA.vr, 'BulkDataURI': uri } dicom_json.Insert(metadata_json, tags.PHOTOMETRIC_INTERPRETATION, 'RGB') dicom_json.Insert(metadata_json, tags.SAMPLES_PER_PIXEL, 3) # Indicates we store pixel data as R1,G1,B1,R2,G2,B2... dicom_json.Insert(metadata_json, tags.PLANAR_CONFIGURATION, 0) dicom_json.Insert(metadata_json, tags.ROWS, image_array.shape[0]) dicom_json.Insert(metadata_json, tags.COLUMNS, image_array.shape[1]) dicom_json.Insert(metadata_json, tags.BITS_ALLOCATED, 8) dicom_json.Insert(metadata_json, tags.BITS_STORED, 8) dicom_json.Insert(metadata_json, tags.HIGH_BIT, 7) dicom_json.Insert(metadata_json, tags.PIXEL_REPRESENTATION, 0) bulkdata = dicom_web.DicomBulkData( uri=uri, data=image_array.tobytes(), content_type='application/octet-stream') return dicom_json.ObjectWithBulkData(metadata_json, [bulkdata])
def testBuildJsonSC(self, *_): num_rows = 10 num_columns = 10 hufloat = np.ones([num_rows, num_columns, 1]) image_position_tag_value = '1' study_time_tag_value = '2' study_instance_uid = '1.2.3.4' series_uid = '5.6.7' study_dict = {} dicom_json.Insert(study_dict, tags.IMAGE_POSITION, image_position_tag_value) dicom_json.Insert(study_dict, tags.STUDY_TIME, study_time_tag_value) dicom_json.Insert(study_dict, tags.STUDY_INSTANCE_UID, study_instance_uid) study_dict_copy = study_dict.copy() builder = dicom_builder.DicomBuilder() dicom_json_sc = builder.BuildJsonSC(hufloat, study_dict, series_uid) # Ensure the study_dict is not affected by the builder. self.assertEqual(study_dict, study_dict_copy) # Test the UIDs. self.assertEqual(dicom_json_sc.instance_uid, _UID1) dicom_dict = dicom_json_sc.dicom_dict # Test study/series level tags. self._AssertJsonTag(dicom_dict, tags.STUDY_INSTANCE_UID, study_instance_uid) self._AssertJsonTag(dicom_dict, tags.SERIES_INSTANCE_UID, series_uid) self._AssertJsonTag(dicom_dict, tags.STUDY_TIME, study_time_tag_value) self._AssertJsonTag(dicom_dict, tags.MODALITY, tag_values.OT_MODALITY) # Test instance level tags. self._AssertJsonTag(dicom_dict, tags.SPECIFIC_CHARACTER_SET, dicom_builder._ISO_CHARACTER_SET) self._AssertJsonTag(dicom_dict, tags.MEDIA_STORAGE_SOP_INSTANCE_UID, dicom_json_sc.instance_uid) self._AssertJsonTag(dicom_dict, tags.MEDIA_STORAGE_SOP_CLASS_UID, tag_values.SECONDARY_CAPTURE_CUID) self._AssertJsonTag(dicom_dict, tags.SOP_CLASS_UID, tag_values.SECONDARY_CAPTURE_CUID) self._AssertJsonTag(dicom_dict, tags.TRANSFER_SYNTAX_UID, dicom_builder._IMPLICIT_VR_LITTLE_ENDIAN) # Test positional tags. self._AssertJsonTag(dicom_dict, tags.IMAGE_POSITION, image_position_tag_value) # Test image tags. self._AssertJsonTag(dicom_dict, tags.PHOTOMETRIC_INTERPRETATION, 'RGB') self._AssertJsonTag(dicom_dict, tags.SAMPLES_PER_PIXEL, 3) self._AssertJsonTag(dicom_dict, tags.PLANAR_CONFIGURATION, 0) self._AssertJsonTag(dicom_dict, tags.ROWS, num_rows) self._AssertJsonTag(dicom_dict, tags.COLUMNS, num_columns) self._AssertJsonTag(dicom_dict, tags.BITS_ALLOCATED, 8) self._AssertJsonTag(dicom_dict, tags.BITS_STORED, 8) self._AssertJsonTag(dicom_dict, tags.HIGH_BIT, 7) self._AssertJsonTag(dicom_dict, tags.PIXEL_REPRESENTATION, 0) bulkdata_uri = '{}/{}/{}'.format(study_instance_uid, series_uid, _UID1) self.assertEqual(dicom_dict[tags.PIXEL_DATA.number]['BulkDataURI'], bulkdata_uri) # Test image bulkdata. bulkdata = dicom_json_sc.bulkdata_list[0] self.assertEqual(bulkdata.uri, bulkdata_uri) self.assertEqual(bulkdata.data, hufloat.tobytes()) self.assertEqual(bulkdata.content_type, 'application/octet-stream')