Ejemplo n.º 1
0
def read_all_channels(im_paths, vox_size=None):
    im, im_meta, im_names = [], [], []
    for path in im_paths:
        filename_pieces = basename(path).split('.')
        if 'nii' not in filename_pieces and vox_size is None:
            print('ERROR: For non-Nifti images you must specify vox size')
            sys.exit()
        data, meta = fileio.read_image(abspath(path))
        def_meta = fileio.get_default_nifti_header(shape=data.shape,
                                                   dtype=data.dtype)
        meta = {**def_meta, **meta}
        meta['dim'][1:4] = data.shape
        if vox_size is not None:
            meta['pixdim'][1:4] = [float(x) for x in vox_size.split('x')]
        im.append(data)
        im_meta.append(meta)
        im_names.append(filename_pieces[0])
    return im, im_meta, im_names
Ejemplo n.º 2
0
def read_image(source, *args, **pargs):
    return fileio.read_image(source, *args, **pargs)
Ejemplo n.º 3
0
def read_image( source, *args, **pargs ):
    return fileio.read_image( source, *args, **pargs )
Ejemplo n.º 4
0
def preprocess(args):
    """Also initializing some helpful variables for later"""
    im1, im1_vs = args.image1, args.im1_vox_size
    im2, im2_vs = args.image2, args.im2_vox_size
    im1_list, im1_meta_list, im1_names = read_all_channels(im1, im1_vs)
    im2_list, im2_meta_list, im2_names = read_all_channels(im2, im2_vs)
    dim = len(im1_list[0].shape)  # image dimension
    v1 = im1_meta_list[0]['pixdim'][1:dim + 1]  # im1 voxel size
    v2 = im2_meta_list[0]['pixdim'][1:dim + 1]
    im1_brain_mask, im2_brain_mask = None, None
    if args.im1_mask is not None:
        im1_brain_mask, mask_meta = fileio.read_image(args.im1_mask)
    if args.im2_mask is not None:
        im2_brain_mask, mask_meta = fileio.read_image(args.im2_mask)
    """All outputs will be at this voxel size, so we can overwrite inputs here
       Update meta data voxel size, important to keep track of all spatial changes"""
    min_size = np.array([
        0.25,
    ] * dim)
    if args.min_vox_size:
        min_size = np.array([float(x) for x in args.min_vox_size.split('x')])
    for i, (im1, im2) in enumerate(zip(im1_list, im2_list)):
        a, b, newvox = pp.normalize_voxelsize(im1,
                                              v1,
                                              im2,
                                              v2,
                                              min_size=min_size)
        im1_list[i], im2_list[i], = a, b
    if im1_brain_mask is not None:
        im1_brain_mask, b, nv = pp.normalize_voxelsize(im1_brain_mask,
                                                       v1,
                                                       im1_list[0],
                                                       newvox,
                                                       min_size=min_size)
    if im2_brain_mask is not None:
        im2_brain_mask, b, nv = pp.normalize_voxelsize(im2_brain_mask,
                                                       v2,
                                                       im2_list[0],
                                                       newvox,
                                                       min_size=min_size)

    # TODO: normalize_intensity has 'sigmoid' mode, experiment with that
    # TODO: consider better options here (sum projection in foreground, mean
    #       projection in background - using a quick heuristic foreground/
    #       background threshold)
    #       Use the very nice two-channel image I stitched for Yu/Sujatha
    #       to test alternatives. Do a dual channel alignment to the Z-brain.
    if args.im1_mask is None:
        """This norm is only for preprocessing purposes, don't overwrite im lists"""
        im_list_norm = [pp.normalize_intensity(im) for im in im1_list]
        im_sum = np.sum(np.array(im_list_norm), axis=0)
        im1_brain_mask = pp.brain_detection(im_sum,
                                            v1,
                                            foreground_mask=None,
                                            iterations=[60, 25, 5],
                                            lambda2=args.im1_lambda)
    if args.im2_mask is None:
        im_list_norm = [pp.normalize_intensity(im) for im in im2_list]
        im_sum = np.sum(np.array(im_list_norm), axis=0)
        im2_brain_mask = pp.brain_detection(im_sum,
                                            v2,
                                            foreground_mask=None,
                                            iterations=[60, 25, 5],
                                            lambda2=args.im2_lambda)
    """Padding is after brain detection, so zeros can't affect masking
       Masks will be used for registration, and pads are not within mask
       so pads shouldn't affect registration either"""
    im1_box = pp.minimal_bounding_box(im1_brain_mask)
    im2_box = pp.minimal_bounding_box(im2_brain_mask)
    im1_box_dims = np.array([a.stop - a.start for a in im1_box])
    im2_box_dims = np.array([a.stop - a.start for a in im2_box])
    final_dims = np.maximum(im1_box_dims, im2_box_dims) + 2 * args.pad_size
    diff1, diff2 = (final_dims - im1_box_dims) / 2., (final_dims -
                                                      im2_box_dims) / 2.
    pad1 = np.array([(np.ceil(d), np.floor(d)) for d in diff1]).astype(int)
    pad2 = np.array([(np.ceil(d), np.floor(d)) for d in diff2]).astype(int)
    for i, (im1, im2) in enumerate(zip(im1_list, im2_list)):
        im1_list[i] = np.pad(im1[im1_box], pad1, mode='constant')
        im2_list[i] = np.pad(im2[im2_box], pad2, mode='constant')
    im1_brain_mask = np.pad(im1_brain_mask[im1_box], pad1, mode='constant')
    im2_brain_mask = np.pad(im2_brain_mask[im2_box], pad2, mode='constant')
    """Preprocessing changes spatial relationship with raw image,
       which will be recorded in sform; ITK uses qform, and this
       which must be zeros for registration to execute accurately"""
    xyz = ['x', 'y', 'z']
    im1_origin = np.array(
        [a.start - np.ceil(b) for a, b in zip(im1_box, diff1)]) * newvox
    im2_origin = np.array(
        [a.start - np.ceil(b) for a, b in zip(im2_box, diff2)]) * newvox
    for meta1, meta2 in zip(im1_meta_list, im2_meta_list):
        meta1['sform_code'], meta1['qform_code'] = 2, 1
        meta2['sform_code'], meta2['qform_code'] = 2, 1
        meta1['pixdim'][1:dim + 1], meta1['dim'][1:dim +
                                                 1] = newvox, final_dims
        meta2['pixdim'][1:dim + 1], meta2['dim'][1:dim +
                                                 1] = newvox, final_dims
        for i, (a, b, c) in enumerate(zip(xyz, im1_origin, im2_origin)):
            meta1['srow_' + a][i], meta2['srow_' + a][i] = newvox[i], newvox[i]
            meta1['srow_' + a][-1], meta2['srow_' + a][-1] = b, c
            meta1['qoffset_' + a], meta2['qoffset_' + a] = 0, 0
        if all([meta1['quatern_' + a] == 0 for a in ['b', 'c', 'd']]):
            meta1['quatern_d'] = 1
        if all([meta2['quatern_' + a] == 0 for a in ['b', 'c', 'd']]):
            meta2['quatern_d'] = 1

    sfx = '_regiprep_mask.nii.gz'
    fileio.write_image(args.outdir + '/' + im1_names[0] + sfx, im1_brain_mask,
                       im1_meta_list[0])
    fileio.write_image(args.outdir + '/' + im2_names[0] + sfx, im2_brain_mask,
                       im2_meta_list[0])
    sfx = '_regiprep_pp.nii.gz'
    for i in range(len(im1_list)):
        fileio.write_image(args.outdir + '/' + im1_names[i] + sfx, im1_list[i],
                           im1_meta_list[i])
        fileio.write_image(args.outdir + '/' + im2_names[i] + sfx, im2_list[i],
                           im2_meta_list[i])