def _anonymize_files(dicom_directory_in, dicom_directory_out, fields_to_keep): """ See anonymize_file for more information. series_UID and instance_UID will create a new UID respectively for the series for each directory or for the instance for each file. Note that for a multi-series dataset it is thus required that each series is in its own directory. """ # Make sure we have absolute paths dicom_directory_in = os.path.abspath(dicom_directory_in) dicom_directory_out = os.path.abspath(dicom_directory_out) # looping over all files for root, _, file_names in os.walk(dicom_directory_in): # New directory for file_name in file_names: # Create instance_UID fields_to_keep['SOPInstanceUID'] = dicom.UID.generate_uid() dicom_file_in = os.path.join(root, file_name) current_dir = root[len(dicom_directory_in) + 1:] dicom_file_out = os.path.join(dicom_directory_out, current_dir, file_name) if is_dicom_file(dicom_file_in): logging.info("Processing " + dicom_file_in) _anonymize_file(dicom_file_in, dicom_file_out, fields_to_keep) else: logging.info("Skipping " + dicom_file_in + ", no dicom file")
def test_is_dicom_file(self): input_file = os.path.join(test_data.GENERIC_COMPRESSED, 'IM-0001-0001-0001.dcm') assert is_dicom_file(input_file) temporary_directory = tempfile.mkdtemp() try: # test for empty file non_dicom1 = os.path.join(temporary_directory, 'non_dicom.dcm') open(non_dicom1, 'a').close() assert not is_dicom_file(non_dicom1) # test for non empty file non_dicom2 = os.path.join(temporary_directory, 'non_dicom2.dcm') with open(non_dicom2, 'w') as file_2: file_2.write(''.join(random.SystemRandom().choice(string.digits) for _ in range(300))) assert not is_dicom_file(non_dicom2) finally: shutil.rmtree(temporary_directory)
def compress_directory(dicom_directory): """ This function can be used to convert a folder of jpeg compressed images to an uncompressed ones :param dicom_directory: directory of dicom files to compress """ if is_compressed(dicom_directory): return if _which('gdcmconv') is None and _which('gdcmconv.exe') is None: raise ConversionError('GDCMCONV_NOT_FOUND') print('Compressing dicom files in %s' % dicom_directory) for root, _, files in os.walk(dicom_directory): for dicom_file in files: if common.is_dicom_file(os.path.join(root, dicom_file)): compress_dicom(os.path.join(root, dicom_file))
def decompress_directory(dicom_directory): """ This function can be used to convert a folder of jpeg compressed images to an uncompressed ones :param dicom_directory: directory with dicom files to decompress """ if not is_compressed(dicom_directory): return if settings.gdcmconv_path is None and _which( 'gdcmconv') is None and _which('gdcmconv.exe') is None: raise ConversionError('GDCMCONV_NOT_FOUND') logger.info('Decompressing dicom files in %s' % dicom_directory) for root, _, files in os.walk(dicom_directory): for dicom_file in files: if common.is_dicom_file(os.path.join(root, dicom_file)): decompress_dicom(os.path.join(root, dicom_file))
def _get_first_header(dicom_directory): """ Function to get the first dicom file form a directory and return the header Useful to determine the type of data to convert :param dicom_directory: directory with dicom files """ # looping over all files for root, _, file_names in os.walk(dicom_directory): # go over all the files and try to read the dicom header for file_name in file_names: file_path = os.path.join(root, file_name) # check wither it is a dicom file if not common.is_dicom_file(file_path): continue # read the headers return dicom.read_file(file_path, stop_before_pixels=True) # no dicom files found raise ConversionError('NO_DICOM_FILES_FOUND')
def convert_directory(dicom_directory, output_folder, compression=True, reorient=True): """ This function will order all dicom files by series and order them one by one :param compression: enable or disable gzip compression :param reorient: reorient the dicoms according to LAS orientation :param output_folder: folder to write the nifti files to :param dicom_directory: directory with dicom files """ # sort dicom files by series uid dicom_series = {} for root, _, files in os.walk(dicom_directory): for dicom_file in files: file_path = os.path.join(root, dicom_file) # noinspection PyBroadException try: if common.is_dicom_file(file_path): # read the dicom as fast as possible # (max length for SeriesInstanceUID is 64 so defer_size 100 should be ok) if convert_dicom.is_compressed(file_path): convert_dicom.decompress_dicom(file_path) dicom_headers = dicom.read_file(file_path, defer_size=100, stop_before_pixels=False) if not _is_valid_imaging_dicom(dicom_headers): print("Skipping: %s" % file_path) continue print("Organizing: %s" % file_path) if dicom_headers.SeriesInstanceUID not in dicom_series: dicom_series[dicom_headers.SeriesInstanceUID] = [] dicom_series[dicom_headers.SeriesInstanceUID].append( dicom_headers) except: # Explicitly capturing all errors here to be able to continue processing all the rest print("Unable to read: %s" % file_path) traceback.print_exc() # start converting one by one for series_id, dicom_input in iteritems(dicom_series): base_filename = "" # noinspection PyBroadException try: # construct the filename for the nifti base_filename = _remove_accents('%s' % dicom_input[0].SeriesNumber) if 'SequenceName' in dicom_input[0]: base_filename = _remove_accents( '%s_%s' % (dicom_input[0].SeriesNumber, dicom_input[0].SequenceName)) elif 'ProtocolName' in dicom_input[0]: base_filename = _remove_accents( '%s_%s' % (dicom_input[0].SeriesNumber, dicom_input[0].ProtocolName)) print('--------------------------------------------') print('Start converting ', base_filename) if compression: nifti_file = os.path.join(output_folder, base_filename + '.nii.gz') else: nifti_file = os.path.join(output_folder, base_filename + '.nii') convert_dicom.dicom_array_to_nifti(dicom_input, nifti_file, reorient) gc.collect() except: # Explicitly capturing app exceptions here to be able to continue processing print("Unable to convert: %s" % base_filename) traceback.print_exc()