Commit 5bba74303d5585b93b167010b5c83269d1cafa2c
1 parent
829e75d1
Exists in
command-line
Add option to import every group of DICOM images
Showing
2 changed files
with
57 additions
and
12 deletions
Show diff stats
app.py
| @@ -26,6 +26,8 @@ import sys | @@ -26,6 +26,8 @@ import sys | ||
| 26 | import shutil | 26 | import shutil |
| 27 | import traceback | 27 | import traceback |
| 28 | 28 | ||
| 29 | +import re | ||
| 30 | + | ||
| 29 | if sys.platform == 'win32': | 31 | if sys.platform == 'win32': |
| 30 | import _winreg | 32 | import _winreg |
| 31 | else: | 33 | else: |
| @@ -270,6 +272,9 @@ def parse_comand_line(): | @@ -270,6 +272,9 @@ def parse_comand_line(): | ||
| 270 | action="store", | 272 | action="store", |
| 271 | dest="dicom_dir") | 273 | dest="dicom_dir") |
| 272 | 274 | ||
| 275 | + parser.add_option("--import-all", | ||
| 276 | + action="store") | ||
| 277 | + | ||
| 273 | parser.add_option("-s", "--save", | 278 | parser.add_option("-s", "--save", |
| 274 | help="Save the project after an import.") | 279 | help="Save the project after an import.") |
| 275 | 280 | ||
| @@ -296,7 +301,7 @@ def use_cmd_optargs(options, args): | @@ -296,7 +301,7 @@ def use_cmd_optargs(options, args): | ||
| 296 | # If import DICOM argument... | 301 | # If import DICOM argument... |
| 297 | if options.dicom_dir: | 302 | if options.dicom_dir: |
| 298 | import_dir = options.dicom_dir | 303 | import_dir = options.dicom_dir |
| 299 | - Publisher.sendMessage('Import directory', import_dir) | 304 | + Publisher.sendMessage('Import directory', {'directory': import_dir, 'gui': not options.no_gui}) |
| 300 | 305 | ||
| 301 | if options.save: | 306 | if options.save: |
| 302 | Publisher.sendMessage('Save project', os.path.abspath(options.save)) | 307 | Publisher.sendMessage('Save project', os.path.abspath(options.save)) |
| @@ -305,6 +310,14 @@ def use_cmd_optargs(options, args): | @@ -305,6 +310,14 @@ def use_cmd_optargs(options, args): | ||
| 305 | check_for_export(options) | 310 | check_for_export(options) |
| 306 | 311 | ||
| 307 | return True | 312 | return True |
| 313 | + elif options.import_all: | ||
| 314 | + import invesalius.reader.dicom_reader as dcm | ||
| 315 | + for patient in dcm.GetDicomGroups(options.import_all): | ||
| 316 | + for group in patient.GetGroups(): | ||
| 317 | + Publisher.sendMessage('Import group', {'group': group, 'gui': not options.no_gui}) | ||
| 318 | + check_for_export(options, suffix=group.title, remove_surfaces=False) | ||
| 319 | + Publisher.sendMessage('Remove masks', [0]) | ||
| 320 | + return True | ||
| 308 | 321 | ||
| 309 | # Check if there is a file path somewhere in what the user wrote | 322 | # Check if there is a file path somewhere in what the user wrote |
| 310 | # In case there is, try opening as it was a inv3 | 323 | # In case there is, try opening as it was a inv3 |
| @@ -320,13 +333,29 @@ def use_cmd_optargs(options, args): | @@ -320,13 +333,29 @@ def use_cmd_optargs(options, args): | ||
| 320 | return False | 333 | return False |
| 321 | 334 | ||
| 322 | 335 | ||
| 323 | -def check_for_export(options): | 336 | +def sanitize(text): |
| 337 | + text = str(text).strip().replace(' ', '_') | ||
| 338 | + return re.sub(r'(?u)[^-\w.]', '', text) | ||
| 339 | + | ||
| 340 | + | ||
| 341 | +def check_for_export(options, suffix='', remove_surfaces=False): | ||
| 342 | + suffix = sanitize(suffix) | ||
| 343 | + | ||
| 324 | if options.export: | 344 | if options.export: |
| 325 | if not options.threshold: | 345 | if not options.threshold: |
| 326 | print("Need option --threshold when using --export.") | 346 | print("Need option --threshold when using --export.") |
| 327 | exit(1) | 347 | exit(1) |
| 328 | - threshold_range = tuple([int(n) for n in options.threshold.split('-')]) | ||
| 329 | - export(options.export, threshold_range) | 348 | + threshold_range = tuple([int(n) for n in options.threshold.split(',')]) |
| 349 | + | ||
| 350 | + if suffix: | ||
| 351 | + if options.export.endswith('.stl'): | ||
| 352 | + path_ = '{}-{}.stl'.format(options.export[:-4], suffix) | ||
| 353 | + else: | ||
| 354 | + path_ = '{}-{}.stl'.format(options.export, suffix) | ||
| 355 | + else: | ||
| 356 | + path_ = options.export | ||
| 357 | + | ||
| 358 | + export(path_, threshold_range, remove_surface=remove_surfaces) | ||
| 330 | elif options.export_to_all: | 359 | elif options.export_to_all: |
| 331 | # noinspection PyBroadException | 360 | # noinspection PyBroadException |
| 332 | try: | 361 | try: |
| @@ -334,15 +363,15 @@ def check_for_export(options): | @@ -334,15 +363,15 @@ def check_for_export(options): | ||
| 334 | 363 | ||
| 335 | for threshold_name, threshold_range in Project().presets.thresh_ct.iteritems(): | 364 | for threshold_name, threshold_range in Project().presets.thresh_ct.iteritems(): |
| 336 | if isinstance(threshold_range[0], int): | 365 | if isinstance(threshold_range[0], int): |
| 337 | - path_ = u'{}-{}.stl'.format(options.export_to_all, threshold_name) | ||
| 338 | - export(path_, threshold_range) | 366 | + path_ = u'{}-{}-{}.stl'.format(options.export_to_all, suffix, threshold_name) |
| 367 | + export(path_, threshold_range, remove_surface=True) | ||
| 339 | except: | 368 | except: |
| 340 | traceback.print_exc() | 369 | traceback.print_exc() |
| 341 | finally: | 370 | finally: |
| 342 | exit(0) | 371 | exit(0) |
| 343 | 372 | ||
| 344 | 373 | ||
| 345 | -def export(path_, threshold_range): | 374 | +def export(path_, threshold_range, remove_surface=False): |
| 346 | import invesalius.constants as const | 375 | import invesalius.constants as const |
| 347 | 376 | ||
| 348 | Publisher.sendMessage('Set threshold values', threshold_range) | 377 | Publisher.sendMessage('Set threshold values', threshold_range) |
| @@ -362,6 +391,8 @@ def export(path_, threshold_range): | @@ -362,6 +391,8 @@ def export(path_, threshold_range): | ||
| 362 | } | 391 | } |
| 363 | Publisher.sendMessage('Create surface from index', surface_options) | 392 | Publisher.sendMessage('Create surface from index', surface_options) |
| 364 | Publisher.sendMessage('Export surface to file', (path_, const.FILETYPE_STL)) | 393 | Publisher.sendMessage('Export surface to file', (path_, const.FILETYPE_STL)) |
| 394 | + if remove_surface: | ||
| 395 | + Publisher.sendMessage('Remove surfaces', [0]) | ||
| 365 | 396 | ||
| 366 | 397 | ||
| 367 | def print_events(data): | 398 | def print_events(data): |
invesalius/control.py
| @@ -61,6 +61,7 @@ class Controller(): | @@ -61,6 +61,7 @@ class Controller(): | ||
| 61 | 61 | ||
| 62 | def __bind_events(self): | 62 | def __bind_events(self): |
| 63 | Publisher.subscribe(self.OnImportMedicalImages, 'Import directory') | 63 | Publisher.subscribe(self.OnImportMedicalImages, 'Import directory') |
| 64 | + Publisher.subscribe(self.OnImportGroup, 'Import group') | ||
| 64 | Publisher.subscribe(self.OnShowDialogImportDirectory, | 65 | Publisher.subscribe(self.OnShowDialogImportDirectory, |
| 65 | 'Show import directory dialog') | 66 | 'Show import directory dialog') |
| 66 | Publisher.subscribe(self.OnShowDialogImportOtherFiles, | 67 | Publisher.subscribe(self.OnShowDialogImportOtherFiles, |
| @@ -440,10 +441,11 @@ class Controller(): | @@ -440,10 +441,11 @@ class Controller(): | ||
| 440 | #----------- to import by command line --------------------------------------------------- | 441 | #----------- to import by command line --------------------------------------------------- |
| 441 | 442 | ||
| 442 | def OnImportMedicalImages(self, pubsub_evt): | 443 | def OnImportMedicalImages(self, pubsub_evt): |
| 443 | - directory = pubsub_evt.data | ||
| 444 | - self.ImportMedicalImages(directory) | 444 | + directory = pubsub_evt.data['directory'] |
| 445 | + gui = pubsub_evt.data['gui'] | ||
| 446 | + self.ImportMedicalImages(directory, gui) | ||
| 445 | 447 | ||
| 446 | - def ImportMedicalImages(self, directory): | 448 | + def ImportMedicalImages(self, directory, gui=True): |
| 447 | patients_groups = dcm.GetDicomGroups(directory) | 449 | patients_groups = dcm.GetDicomGroups(directory) |
| 448 | name = directory.rpartition('\\')[-1].split('.') | 450 | name = directory.rpartition('\\')[-1].split('.') |
| 449 | print "patients: ", patients_groups | 451 | print "patients: ", patients_groups |
| @@ -451,7 +453,7 @@ class Controller(): | @@ -451,7 +453,7 @@ class Controller(): | ||
| 451 | if len(patients_groups): | 453 | if len(patients_groups): |
| 452 | # OPTION 1: DICOM | 454 | # OPTION 1: DICOM |
| 453 | group = dcm.SelectLargerDicomGroup(patients_groups) | 455 | group = dcm.SelectLargerDicomGroup(patients_groups) |
| 454 | - matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0, 0], gui=True) | 456 | + matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0, 0], gui=gui) |
| 455 | self.CreateDicomProject(dicom, matrix, matrix_filename) | 457 | self.CreateDicomProject(dicom, matrix, matrix_filename) |
| 456 | else: | 458 | else: |
| 457 | # OPTION 2: NIfTI, Analyze or PAR/REC | 459 | # OPTION 2: NIfTI, Analyze or PAR/REC |
| @@ -474,6 +476,18 @@ class Controller(): | @@ -474,6 +476,18 @@ class Controller(): | ||
| 474 | self.LoadProject() | 476 | self.LoadProject() |
| 475 | Publisher.sendMessage("Enable state project", True) | 477 | Publisher.sendMessage("Enable state project", True) |
| 476 | 478 | ||
| 479 | + def OnImportGroup(self, pubsub_evt): | ||
| 480 | + group = pubsub_evt.data['group'] | ||
| 481 | + gui = pubsub_evt.data['gui'] | ||
| 482 | + self.ImportGroup(group, gui) | ||
| 483 | + | ||
| 484 | + def ImportGroup(self, group, gui=True): | ||
| 485 | + matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0, 0], gui=gui) | ||
| 486 | + self.CreateDicomProject(dicom, matrix, matrix_filename) | ||
| 487 | + | ||
| 488 | + self.LoadProject() | ||
| 489 | + Publisher.sendMessage("Enable state project", True) | ||
| 490 | + | ||
| 477 | #------------------------------------------------------------------------------------- | 491 | #------------------------------------------------------------------------------------- |
| 478 | 492 | ||
| 479 | def LoadProject(self): | 493 | def LoadProject(self): |
| @@ -788,7 +802,7 @@ class Controller(): | @@ -788,7 +802,7 @@ class Controller(): | ||
| 788 | n_slices = len(filelist) | 802 | n_slices = len(filelist) |
| 789 | resolution_percentage = utils.calculate_resizing_tofitmemory(int(sx), int(sy), n_slices, bits/8) | 803 | resolution_percentage = utils.calculate_resizing_tofitmemory(int(sx), int(sy), n_slices, bits/8) |
| 790 | 804 | ||
| 791 | - if resolution_percentage < 1.0: | 805 | + if resolution_percentage < 1.0 and gui: |
| 792 | re_dialog = dialog.ResizeImageDialog() | 806 | re_dialog = dialog.ResizeImageDialog() |
| 793 | re_dialog.SetValue(int(resolution_percentage*100)) | 807 | re_dialog.SetValue(int(resolution_percentage*100)) |
| 794 | re_dialog_value = re_dialog.ShowModal() | 808 | re_dialog_value = re_dialog.ShowModal() |