def generate_qc(fn_in, fn_seg, args, path_qc): """Generate a QC entry allowing to quickly review the segmentation process.""" import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice from spinalcordtoolbox.resample.nipy_resample import resample_file # Resample to fixed resolution (see #2063) tmp_folder = sct.TempFolder() fn_in_r = os.path.join(tmp_folder.path_tmp, 'img_r.nii.gz') # Orient to RPI and retrieve pixel size in IS direction (z) im_fn = Image(fn_in).change_orientation('RPI').save(fn_in_r) resample_file(fn_in_r, fn_in_r, '0.5x0.5x' + str(im_fn.dim[6]), 'mm', 'nn', 0) fn_seg_r = os.path.join(tmp_folder.path_tmp, 'seg_r.nii.gz') Image(fn_seg).change_orientation('RPI').save(fn_seg_r) resample_file(fn_seg_r, fn_seg_r, '0.5x0.5x' + str(im_fn.dim[6]), 'mm', 'nn', 0) # TODO: investigate the following issue further (Julien 2018-12-01): # fn_in_r and fn_seg_r should be in nii.gz format, otherwise qcslice.Axial outputs an memmap instead of # an array. qc.add_entry( src=fn_in, process="sct_deepseg_sc", args=args, path_qc=path_qc, plane='Axial', qcslice=qcslice.Axial([Image(fn_in_r), Image(fn_seg_r)]), qcslice_operations=[qc.QcImage.listed_seg], qcslice_layout=lambda x: x.mosaic(), )
def generate_qc(fn_in, fn_seg, args, path_qc): """ Generate a QC entry allowing to quickly review the segmentation process. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice from spinalcordtoolbox.resample.nipy_resample import resample_file # Resample to fixed resolution (see #2063) tmp_folder = sct.TempFolder() fn_in_r = os.path.join(tmp_folder.path_tmp, 'img_r.nii.gz') # Orient to RPI and retrieve pixel size in IS direction (z) im_fn = Image(fn_in).change_orientation('RPI').save(fn_in_r) resample_file(fn_in_r, fn_in_r, '0.5x0.5x' + str(im_fn.dim[6]), 'mm', 'nn', 0) fn_seg_r = os.path.join(tmp_folder.path_tmp, 'seg_r.nii.gz') Image(fn_seg).change_orientation('RPI').save(fn_seg_r) resample_file(fn_seg_r, fn_seg_r, '0.5x0.5x' + str(im_fn.dim[6]), 'mm', 'nn', 0) qc.add_entry( src=fn_in, process="sct_propseg", args=args, path_qc=path_qc, plane='Axial', qcslice=qcslice.Axial([Image(fn_in_r), Image(fn_seg_r)]), qcslice_operations=[qc.QcImage.listed_seg], qcslice_layout=lambda x: x.mosaic(), )
def generate_qc(fn_in, fn_labeled, args, path_qc): """ Generate a quick visualization of vertebral labeling """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice def label_vertebrae(self, mask): """ Draw vertebrae areas, then add text showing the vertebrae names. """ import matplotlib.pyplot as plt import scipy.ndimage self.listed_seg(mask) ax = plt.gca() a = [0.0] data = mask for index, val in np.ndenumerate(data): if val not in a: a.append(val) index = int(val) if index in self._labels_regions.values(): color = self._labels_color[index] y, x = scipy.ndimage.measurements.center_of_mass( np.where(data == val, data, 0)) # Draw text with a shadow x += 10 label = list(self._labels_regions.keys())[list( self._labels_regions.values()).index(index)] ax.text(x, y, label, color='black', clip_on=True) x -= 0.5 y -= 0.5 ax.text(x, y, label, color=color, clip_on=True) qc.add_entry( src=fn_in, process='sct_label_vertebrae', args=args, path_qc=path_qc, plane='Sagittal', dpi=100, qcslice=qcslice.Sagittal([Image(fn_in), Image(fn_labeled)]), qcslice_operations=[label_vertebrae], qcslice_layout=lambda x: x.single(), )
def generate_qc(fn_in, fn_seg, args, path_qc): """Generate a QC entry allowing to quickly review the segmentation process.""" import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice qc.add_entry( src=fn_in, process="sct_deepseg_sc", args=args, path_qc=path_qc, plane='Axial', qcslice=qcslice.Axial([Image(fn_in), Image(fn_seg)]), qcslice_operations=[qc.QcImage.listed_seg], qcslice_layout=lambda x: x.mosaic(), )
def generate_qc(fn_in, fn_wm, args, path_qc): """ Generate a QC entry allowing to quickly review the warped template. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice qc.add_entry( src=fn_in, process="sct_warp_template", args=args, path_qc=path_qc, plane='Axial', qcslice=qcslice.Axial([Image(fn_in), Image(fn_wm)]), qcslice_operations=[qc.QcImage.template], qcslice_layout=lambda x: x.mosaic(), )
def generate_qc(fname_in, fname_out, args, path_qc): """ Generate a QC entry allowing to quickly review the PMJ position """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice def highlight_pmj(self, mask): """ Hook to show a rectangle where PMJ is on the slice """ import matplotlib.pyplot as plt import matplotlib.patches as patches y, x = np.where(mask == 50) ax = plt.gca() img = np.full_like(mask, np.nan) ax.imshow(img, cmap='gray', alpha=0) rect = patches.Rectangle((x - 10, y - 10), 20, 20, linewidth=2, edgecolor='lime', facecolor='none') ax.add_patch(rect) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) qc.add_entry( src=fname_in, process="sct_detect_pmj", args=args, path_qc=path_qc, plane="Sagittal", qcslice=qcslice.Sagittal([Image(fname_in), Image(fname_out)]), qcslice_operations=[highlight_pmj], qcslice_layout=lambda x: x.single(), )
def generate_qc(fn_input, fn_centerline, fn_output, args, path_qc): """ Generate a QC entry allowing to quickly review the straightening process. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice # Just display the straightened spinal cord img_out = Image(fn_output) foreground = qcslice.Sagittal([img_out]).single()[0] qc.add_entry( src=fn_input, process="sct_straighten_spinalcord", args=args, path_qc=path_qc, plane="Sagittal", foreground=foreground, )
def generate_qc(fname_data, fname_template2anat, fname_seg, args, path_qc): """ Generate a QC entry allowing to quickly review the straightening process. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice qc.add_entry( src=fname_data, process="sct_register_to_template", args=args, path_qc=path_qc, plane="Axial", qcslice=qcslice.Axial( [Image(fname_data), Image(fname_template2anat), Image(fname_seg)]), qcslice_operations=[qc.QcImage.no_seg_seg], qcslice_layout=lambda x: x.mosaic()[:2], )
def generate_qc(fname_in, fname_gm, fname_wm, param_seg, args, path_qc): """ Generate a QC entry allowing to quickly review the segmentation process. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice im_org = Image(fname_in) im_gm = Image(fname_gm) im_wm = Image(fname_wm) # create simple compound segmentation image for QC purposes if param_seg.type_seg == 'bin': im_wm.data[im_wm.data == 1] = 1 im_gm.data[im_gm.data == 1] = 2 else: # binarize anyway im_wm.data[im_wm.data >= param_seg.thr_bin] = 1 im_wm.data[im_wm.data < param_seg.thr_bin] = 0 im_gm.data[im_gm.data >= param_seg.thr_bin] = 2 im_gm.data[im_gm.data < param_seg.thr_bin] = 0 im_seg = im_gm im_seg.data += im_wm.data s = qcslice.Axial([im_org, im_seg]) qc.add_entry( src=fname_in, process="sct_segment_graymatter", args=args, path_qc=path_qc, plane='Axial', qcslice=s, qcslice_operations=[qc.QcImage.listed_seg], qcslice_layout=lambda x: x.mosaic(), )
def generate_qc(fname_in, fname_gm, fname_wm, param_seg, args, path_qc): """ Generate a QC entry allowing to quickly review the segmentation process. """ import spinalcordtoolbox.reports.qc as qc import spinalcordtoolbox.reports.slice as qcslice im_org = Image(fname_in) im_gm = Image(fname_gm) im_wm = Image(fname_wm) # create simple compound segmentation image for QC purposes if param_seg.type_seg == 'bin': im_wm.data[im_wm.data == 1] = 1 im_gm.data[im_gm.data == 1] = 2 else: # binarize anyway im_wm.data[im_wm.data >= param_seg.thr_bin] = 1 im_wm.data[im_wm.data < param_seg.thr_bin] = 0 im_gm.data[im_gm.data >= param_seg.thr_bin] = 2 im_gm.data[im_gm.data < param_seg.thr_bin] = 0 im_seg = im_gm im_seg.data += im_wm.data s = qcslice.Axial([im_org, im_seg]) qc.add_entry( src=fname_in, process="sct_segment_graymatter", args=args, path_qc=path_qc, plane='Axial', qcslice=s, qcslice_operations=[qc.QcImage.listed_seg], qcslice_layout=lambda x: x.mosaic(), )