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() | ... | ... |