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 | 26 | import shutil |
| 27 | 27 | import traceback |
| 28 | 28 | |
| 29 | +import re | |
| 30 | + | |
| 29 | 31 | if sys.platform == 'win32': |
| 30 | 32 | import _winreg |
| 31 | 33 | else: |
| ... | ... | @@ -270,6 +272,9 @@ def parse_comand_line(): |
| 270 | 272 | action="store", |
| 271 | 273 | dest="dicom_dir") |
| 272 | 274 | |
| 275 | + parser.add_option("--import-all", | |
| 276 | + action="store") | |
| 277 | + | |
| 273 | 278 | parser.add_option("-s", "--save", |
| 274 | 279 | help="Save the project after an import.") |
| 275 | 280 | |
| ... | ... | @@ -296,7 +301,7 @@ def use_cmd_optargs(options, args): |
| 296 | 301 | # If import DICOM argument... |
| 297 | 302 | if options.dicom_dir: |
| 298 | 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 | 306 | if options.save: |
| 302 | 307 | Publisher.sendMessage('Save project', os.path.abspath(options.save)) |
| ... | ... | @@ -305,6 +310,14 @@ def use_cmd_optargs(options, args): |
| 305 | 310 | check_for_export(options) |
| 306 | 311 | |
| 307 | 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 | 322 | # Check if there is a file path somewhere in what the user wrote |
| 310 | 323 | # In case there is, try opening as it was a inv3 |
| ... | ... | @@ -320,13 +333,29 @@ def use_cmd_optargs(options, args): |
| 320 | 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 | 344 | if options.export: |
| 325 | 345 | if not options.threshold: |
| 326 | 346 | print("Need option --threshold when using --export.") |
| 327 | 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 | 359 | elif options.export_to_all: |
| 331 | 360 | # noinspection PyBroadException |
| 332 | 361 | try: |
| ... | ... | @@ -334,15 +363,15 @@ def check_for_export(options): |
| 334 | 363 | |
| 335 | 364 | for threshold_name, threshold_range in Project().presets.thresh_ct.iteritems(): |
| 336 | 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 | 368 | except: |
| 340 | 369 | traceback.print_exc() |
| 341 | 370 | finally: |
| 342 | 371 | exit(0) |
| 343 | 372 | |
| 344 | 373 | |
| 345 | -def export(path_, threshold_range): | |
| 374 | +def export(path_, threshold_range, remove_surface=False): | |
| 346 | 375 | import invesalius.constants as const |
| 347 | 376 | |
| 348 | 377 | Publisher.sendMessage('Set threshold values', threshold_range) |
| ... | ... | @@ -362,6 +391,8 @@ def export(path_, threshold_range): |
| 362 | 391 | } |
| 363 | 392 | Publisher.sendMessage('Create surface from index', surface_options) |
| 364 | 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 | 398 | def print_events(data): | ... | ... |
invesalius/control.py
| ... | ... | @@ -61,6 +61,7 @@ class Controller(): |
| 61 | 61 | |
| 62 | 62 | def __bind_events(self): |
| 63 | 63 | Publisher.subscribe(self.OnImportMedicalImages, 'Import directory') |
| 64 | + Publisher.subscribe(self.OnImportGroup, 'Import group') | |
| 64 | 65 | Publisher.subscribe(self.OnShowDialogImportDirectory, |
| 65 | 66 | 'Show import directory dialog') |
| 66 | 67 | Publisher.subscribe(self.OnShowDialogImportOtherFiles, |
| ... | ... | @@ -440,10 +441,11 @@ class Controller(): |
| 440 | 441 | #----------- to import by command line --------------------------------------------------- |
| 441 | 442 | |
| 442 | 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 | 449 | patients_groups = dcm.GetDicomGroups(directory) |
| 448 | 450 | name = directory.rpartition('\\')[-1].split('.') |
| 449 | 451 | print "patients: ", patients_groups |
| ... | ... | @@ -451,7 +453,7 @@ class Controller(): |
| 451 | 453 | if len(patients_groups): |
| 452 | 454 | # OPTION 1: DICOM |
| 453 | 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 | 457 | self.CreateDicomProject(dicom, matrix, matrix_filename) |
| 456 | 458 | else: |
| 457 | 459 | # OPTION 2: NIfTI, Analyze or PAR/REC |
| ... | ... | @@ -474,6 +476,18 @@ class Controller(): |
| 474 | 476 | self.LoadProject() |
| 475 | 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 | 493 | def LoadProject(self): |
| ... | ... | @@ -788,7 +802,7 @@ class Controller(): |
| 788 | 802 | n_slices = len(filelist) |
| 789 | 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 | 806 | re_dialog = dialog.ResizeImageDialog() |
| 793 | 807 | re_dialog.SetValue(int(resolution_percentage*100)) |
| 794 | 808 | re_dialog_value = re_dialog.ShowModal() | ... | ... |