def SubRegion(src_grid, sub_grid, def_grid):
    # The sapcing of the src image was changed, so we have to find the new spacing of the sub region
    reg_grid = ConvertGrid(src_grid, def_grid)
    spacing = (np.array(reg_grid.spacing().tolist()) / np.array(
        src_grid.spacing().tolist())) * np.array(sub_grid.spacing().tolist())

    # Because we updated the spacing, the origin of the sub region will change and we have to find the new origin
    # The new origin is the upper left real coordinate of the subregion to extract
    pixel_origin = np.array(sub_grid.origin().tolist()) / np.array(
        src_grid.spacing().tolist())
    upL_real = pixel_origin * np.array(reg_grid.spacing().tolist()) + np.array(
        reg_grid.origin().tolist())

    # Now need to find the bottom right in real coordinates
    btR_real = (spacing * np.array(sub_grid.size().tolist())) + upL_real

    # Now that we have the top left and bottom right, we need to convert them to index corrdiantes of the deformation grid
    upL = np.floor((upL_real - np.array(def_grid.origin().tolist())) /
                   np.array(def_grid.spacing().tolist()))
    btR = np.floor((btR_real - np.array(def_grid.origin().tolist())) /
                   np.array(def_grid.spacing().tolist()))

    xrng = [int(upL[0]), int(btR[0])]
    yrng = [int(upL[1]), int(btR[1])]

    new_sub_grid = cc.MakeGrid(
        ca.Vec3Di(sub_grid.size()[0],
                  sub_grid.size()[1], 1), ca.Vec3Df(spacing[0], spacing[1], 1),
        ca.Vec3Df(upL_real[0], upL_real[1], 0))

    return xrng, yrng, new_sub_grid
def bb_grid_solver(source_image, affine):
    in_sz = source_image.size().tolist()
    in_sp = source_image.spacing().tolist()
    in_or = source_image.origin().tolist()

    C1temp = in_or[0:2]
    C1temp.append(1)
    C1 = C1temp
    C2 = np.array([in_sz[0] * in_sp[0] + in_or[0], in_or[1], 1])
    C3 = np.array([in_or[0], in_sz[1] * in_sp[1] + in_or[1], 1])
    C4 = np.array(
        [in_sz[0] * in_sp[0] + in_or[0], in_sz[1] * in_sp[1] + in_or[1], 1])

    corners = np.matrix([C1, C2, C3, C4])
    tCorners = affine * corners.transpose()

    bbMax = np.max(tCorners[:, 0:4], 1)
    bbMin = np.min(tCorners[:, 0:4], 1)

    dim = np.ceil(bbMax - bbMin)

    out_sp = (np.squeeze(np.array(dim)) / source_image.size()[0:3]
              )  # * (1/np.sqrt(2))
    if out_sp[2] == 0.0:
        out_sp[2] = 1.0
    out_sz = np.squeeze(np.array(dim)) / out_sp.transpose()
    out_or = np.squeeze(
        np.array(bbMin))  # Maybe needs to be the center of the image??

    grid = cc.MakeGrid(
        [np.int(np.ceil(out_sz[0])),
         np.int(np.ceil(out_sz[1])), 1], [out_sp[0], out_sp[1], 1],
        [out_or[0], out_or[1], 0])

    return grid
def ConvertGrid(I_src_grid, I_tar_grid):
    '''Given a source grid and target grid, returns a grid for the source that is in the world coordinates of the target grid'''
    nS = np.multiply(
        np.divide(I_tar_grid.size().tolist(),
                  [float(i) for i in I_src_grid.size().tolist()]),
        I_tar_grid.spacing().tolist())
    return cc.MakeGrid(I_src_grid.size(), ca.Vec3Df(nS[0], nS[1], nS[2]),
                       'center')
예제 #4
0
#     tmp = cc.LoadMHA(BFIdir + fname)
#     cc.WriteGrid(tmp.grid(), BFIdir + 'block{0}_grid.txt'.format(block))
# tmp = cc.LoadMHA(MRI_fname)
# cc.WriteGrid(tmp.grid(), MRIdir + 'T2_grid.txt'.format(block))
# sys.exit()

#BFIgrid = cc.LoadGrid(BFIdir + 'block{0}_grid.txt'.format(block))
#MRIgrid = cc.LoadGrid(MRIdir + 'T2_grid.txt'.format(block))
MRI = cc.LoadMHA(MRI_fname,ca.MEM_HOST)
MRIgrid = MRI.grid()
#MRIgrid = cc.MakeGrid(MRI.size(),MRI.spacing(),'center')
#MRI.setGrid(MRIgrid)
#BFI = cc.LoadMHA(BFIdir + 'M15_01_seg_crop_hd8.mha',ca.MEM_HOST)
BFI_full = cc.LoadMHA(BFIdir + 'M15_01_hd8_VE.mha',ca.MEM_HOST)
BFI = cc.SubVol(BFI_full, yrng=[146,626])
BFIgrid = cc.MakeGrid(ca.Vec3Di(480,480,2239),ca.Vec3Df(0.1185,0.1185,0.030),'center')
BFI.setGrid(BFIgrid)
#BFIgrid = BFI.grid()
print MRIgrid
print BFIgrid
# print 'b4 memory', 480*480*874*4/1024./1024 *7  # 7 blocks, mem size
# print 'mri memory', 256*256*256*4/1024./1024 *7  # 7 blocks, mem size
# print 'mri big memory', 512*512*512*4/1024./1024 *7  # 7 blocks, mem size
# print 'single mri ', 256*256*256*4/1024./1024

#landmarks = get_new_landmarks(block)
# Use these landmarks for an affine
### landmarks = [[[1893.0,123.0,401.0], [187.0,135.0,202.0]],
###              [[1798.0,416.0,333.0], [183.0,131.0,48.0]],
###              [[892.0,222.0,251.0], [84.0,109.0,132.0]],
###              [[2142.0,260.0,332.0], [217.0,114.0,125.0]],
def main():
    secNum = sys.argv[1]
    mkyNum = sys.argv[2]
    region = str(sys.argv[3])
    # channel = sys.argv[3]
    ext = 'M{0}/section_{1}/{2}/'.format(mkyNum, secNum, region)
    ss_dir = '/home/sci/blakez/korenbergNAS/3D_database/Working/Microscopic/side_light_microscope/'
    conf_dir = '/home/sci/blakez/korenbergNAS/3D_database/Working/Microscopic/confocal/'
    memT = ca.MEM_DEVICE

    try:
        with open(
                ss_dir +
                'src_registration/M{0}/section_{1}/M{0}_01_section_{1}_regions.txt'
                .format(mkyNum, secNum), 'r') as f:
            region_dict = json.load(f)
            f.close()
    except IOError:
        region_dict = {}
        region_dict[region] = {}
        region_dict['size'] = map(
            int,
            raw_input("What is the size of the full resolution image x,y? ").
            split(','))
        region_dict[region]['bbx'] = map(
            int,
            raw_input(
                "What are the x indicies of the bounding box (Matlab Format x_start,x_stop? "
            ).split(','))
        region_dict[region]['bby'] = map(
            int,
            raw_input(
                "What are the y indicies of the bounding box (Matlab Format y_start,y_stop? "
            ).split(','))

    if region not in region_dict:
        region_dict[region] = {}
        region_dict[region]['bbx'] = map(
            int,
            raw_input(
                "What are the x indicies of the bounding box (Matlab Format x_start,x_stop? "
            ).split(','))
        region_dict[region]['bby'] = map(
            int,
            raw_input(
                "What are the y indicies of the bounding box (Matlab Format y_start,y_stop? "
            ).split(','))

    img_region = common.LoadITKImage(
        ss_dir +
        'src_registration/M{0}/section_{1}/M{0}_01_section_{1}_{2}.tiff'.
        format(mkyNum, secNum, region), ca.MEM_HOST)
    ssiSrc = common.LoadITKImage(
        ss_dir +
        'src_registration/M{0}/section_{1}/frag0/M{0}_01_ssi_section_{1}_frag0.nrrd'
        .format(mkyNum, secNum), ca.MEM_HOST)
    bfi_df = common.LoadITKField(
        ss_dir +
        'Blockface_registered/M{0}/section_{1}/frag0/M{0}_01_ssi_section_{1}_frag0_to_bfi_real.mha'
        .format(mkyNum, secNum), ca.MEM_DEVICE)

    # Figure out the same region in the low resolution image: There is a transpose from here to matlab so dimensions are flipped
    low_sz = ssiSrc.size().tolist()
    yrng_raw = [(low_sz[1] * region_dict[region]['bbx'][0]) /
                np.float(region_dict['size'][0]),
                (low_sz[1] * region_dict[region]['bbx'][1]) /
                np.float(region_dict['size'][0])]
    xrng_raw = [(low_sz[0] * region_dict[region]['bby'][0]) /
                np.float(region_dict['size'][1]),
                (low_sz[0] * region_dict[region]['bby'][1]) /
                np.float(region_dict['size'][1])]
    yrng = [np.int(np.floor(yrng_raw[0])), np.int(np.ceil(yrng_raw[1]))]
    xrng = [np.int(np.floor(xrng_raw[0])), np.int(np.ceil(xrng_raw[1]))]
    low_sub = cc.SubVol(ssiSrc, xrng, yrng)

    # Figure out the grid for the sub region in relation to the sidescape
    originout = [
        ssiSrc.origin().x + ssiSrc.spacing().x * xrng[0],
        ssiSrc.origin().y + ssiSrc.spacing().y * yrng[0], 0
    ]
    spacingout = [
        (low_sub.size().x * ssiSrc.spacing().x) / (img_region.size().x),
        (low_sub.size().y * ssiSrc.spacing().y) / (img_region.size().y), 1
    ]

    gridout = cc.MakeGrid(img_region.size().tolist(), spacingout, originout)
    img_region.setGrid(gridout)

    only_sub = np.zeros(ssiSrc.size().tolist()[0:2])
    only_sub[xrng[0]:xrng[1], yrng[0]:yrng[1]] = np.squeeze(low_sub.asnp())
    only_sub = common.ImFromNPArr(only_sub)
    only_sub.setGrid(ssiSrc.grid())

    # Deform the only sub region to
    only_sub.toType(ca.MEM_DEVICE)
    def_sub = ca.Image3D(bfi_df.grid(), bfi_df.memType())
    cc.ApplyHReal(def_sub, only_sub, bfi_df)
    def_sub.toType(ca.MEM_HOST)

    # Now have to find the bounding box in the deformation space (bfi space)
    if 'deformation_bbx' not in region_dict[region]:
        bb_def = np.squeeze(pp.LandmarkPicker([np.squeeze(def_sub.asnp())]))
        bb_def_y = [bb_def[0][0], bb_def[1][0]]
        bb_def_x = [bb_def[0][1], bb_def[1][1]]
        region_dict[region]['deformation_bbx'] = bb_def_x
        region_dict[region]['deformation_bby'] = bb_def_y

    with open(
            ss_dir +
            'src_registration/M{0}/section_{1}/M{0}_01_section_{1}_regions.txt'
            .format(mkyNum, secNum), 'w') as f:
        json.dump(region_dict, f)
        f.close()

    # Now need to extract the region and create a deformation and image that have the same resolution as the img_region
    deform_sub = cc.SubVol(bfi_df, region_dict[region]['deformation_bbx'],
                           region_dict[region]['deformation_bby'])

    common.DebugHere()
    sizeout = [
        int(
            np.ceil((deform_sub.size().x * deform_sub.spacing().x) /
                    img_region.spacing().x)),
        int(
            np.ceil((deform_sub.size().y * deform_sub.spacing().y) /
                    img_region.spacing().y)), 1
    ]

    region_grid = cc.MakeGrid(sizeout,
                              img_region.spacing().tolist(),
                              deform_sub.origin().tolist())

    def_im_region = ca.Image3D(region_grid, deform_sub.memType())
    up_deformation = ca.Field3D(region_grid, deform_sub.memType())

    img_region.toType(ca.MEM_DEVICE)
    cc.ResampleWorld(up_deformation, deform_sub,
                     ca.BACKGROUND_STRATEGY_PARTIAL_ZERO)
    cc.ApplyHReal(def_im_region, img_region, up_deformation)

    ss_out = ss_dir + 'Blockface_registered/M{0}/section_{1}/{2}/'.format(
        mkyNum, secNum, region)

    if not pth.exists(pth.expanduser(ss_out)):
        os.mkdir(pth.expanduser(ss_out))

    common.SaveITKImage(
        def_im_region,
        pth.expanduser(ss_out) +
        'M{0}_01_section_{1}_{2}_def_to_bfi.nrrd'.format(
            mkyNum, secNum, region))
    common.SaveITKImage(
        def_im_region,
        pth.expanduser(ss_out) +
        'M{0}_01_section_{1}_{2}_def_to_bfi.tiff'.format(
            mkyNum, secNum, region))
    del img_region, def_im_region, ssiSrc, deform_sub

    # Now apply the same deformation to the confocal images
    conf_grid = cc.LoadGrid(
        conf_dir +
        'sidelight_registered/M{0}/section_{1}/{2}/affine_registration_grid.txt'
        .format(mkyNum, secNum, region))
    cf_out = conf_dir + 'blockface_registered/M{0}/section_{1}/{2}/'.format(
        mkyNum, secNum, region)
    # confocal.toType(ca.MEM_DEVICE)
    # def_conf = ca.Image3D(region_grid, deform_sub.memType())
    # cc.ApplyHReal(def_conf, confocal, up_deformation)

    for channel in range(0, 4):
        z_stack = []
        num_slices = len(
            glob.glob(conf_dir +
                      'sidelight_registered/M{0}/section_{1}/{3}/Ch{2}/*.tiff'.
                      format(mkyNum, secNum, channel, region)))
        for z in range(0, num_slices):
            src_im = common.LoadITKImage(
                conf_dir +
                'sidelight_registered/M{0}/section_{1}/{3}/Ch{2}/M{0}_01_section_{1}_LGN_RHS_Ch{2}_conf_aff_sidelight_z{4}.tiff'
                .format(mkyNum, secNum, channel, region,
                        str(z).zfill(2)))
            src_im.setGrid(
                cc.MakeGrid(
                    ca.Vec3Di(conf_grid.size().x,
                              conf_grid.size().y, 1), conf_grid.spacing(),
                    conf_grid.origin()))
            src_im.toType(ca.MEM_DEVICE)
            def_im = ca.Image3D(region_grid, ca.MEM_DEVICE)
            cc.ApplyHReal(def_im, src_im, up_deformation)
            def_im.toType(ca.MEM_HOST)
            common.SaveITKImage(
                def_im, cf_out +
                'Ch{2}/M{0}_01_section_{1}_{3}_Ch{2}_conf_def_blockface_z{4}.tiff'
                .format(mkyNum, secNum, channel, region,
                        str(z).zfill(2)))
            if z == 0:
                common.SaveITKImage(
                    def_im, cf_out +
                    'Ch{2}/M{0}_01_section_{1}_{3}_Ch{2}_conf_def_blockface_z{4}.nrrd'
                    .format(mkyNum, secNum, channel, region,
                            str(z).zfill(2)))
            z_stack.append(def_im)
            print('==> Done with Ch {0}: {1}/{2}'.format(
                channel, z, num_slices - 1))
        stacked = cc.Imlist_to_Im(z_stack)
        stacked.setSpacing(
            ca.Vec3Df(region_grid.spacing().x,
                      region_grid.spacing().y,
                      conf_grid.spacing().z))
        common.SaveITKImage(
            stacked, cf_out +
            'Ch{2}/M{0}_01_section_{1}_{3}_Ch{2}_conf_def_blockface_stack.nrrd'
            .format(mkyNum, secNum, channel, region))
        if channel == 0:
            cc.WriteGrid(
                stacked.grid(),
                cf_out + 'deformed_registration_grid.txt'.format(
                    mkyNum, secNum, region))
예제 #6
0
# for a in folderList:
#     print a

#Load in the T2 image and downsample it to the resolution of the DW images
####
T2_list = sorted(glob.glob(indir + 'T2DICOM_scan26/*'))
refIm = dicom.read_file(T2_list[0])
PixelDims = (int(refIm.Rows), int(refIm.Columns), len(T2_list))
# PixelSpacing = (0.5,0.5,0.5)
T2Array = np.zeros(PixelDims, dtype=refIm.pixel_array.dtype)
for filename in T2_list:
    ds = dicom.read_file(filename)
    T2Array[:, :, T2_list.index(filename)] = ds.pixel_array
T2MRI = common.ImFromNPArr(T2Array)
T2MRI.setGrid(cc.MakeGrid(T2MRI.grid().size(), 0.5))
T2MRI.toType(ca.MEM_DEVICE)

#Swap the axis of the images so they align with the gradient directions
T2MRI = cc.SwapAxes(T2MRI, 0, 1)
T2MRI = cc.SwapAxes(T2MRI, 0, 2)
T2MRI = cc.FlipDim(T2MRI, 2)
# T2MRI = cc.FlipDim(T2MRI,2)

DWIgrid = cc.MakeGrid([120, 144, 120], 0.5, [0, 0, 0])
down_T2 = ca.Image3D(DWIgrid, ca.MEM_DEVICE)
ca.Resample(down_T2, T2MRI)
####
#Display the list

# cc.WriteMHA(down_T2,outdir + 'Images/T2_downSample_to_DWImha')
예제 #7
0
    MRI_VE = ca.Image3D(grid2D, MRI.memType())
    ca.Copy(MRI_VE, MRI)
    ca.Copy(BFI_VE, BFI)

    cc.SetRegionLTE(MRI_VE, MRI, 0.13, 1)
    MRI_VE *= -1

    square = ca.Image3D(grid2D, BFI.memType())
    cc.CreateRect(square, [0, 0], [440, 440])
    BFI_VE *= square

    cc.VarianceEqualize_I(BFI_VE, sigma=5.0)
    cc.VarianceEqualize_I(MRI_VE, sigma=5.0)

    grid_orig = BFI_VE.grid().copy()
    grid_new = cc.MakeGrid(grid_orig.size(), [1, 1, 1], 'center')
    BFI_VE.setGrid(grid_new)
    MRI_VE.setGrid(grid_new)
    BFI_VE_def = ca.Image3D(grid_new, BFI_VE.memType())

    # do rigid reg first
    # A = AffineReg(BFI_VE, MRI_VE, constraint='rigid', plot=debug)
    A = AffineReg(BFI_VE, MRI_VE, plot=debug, maxIter=400, verbose=0)[1]
    cc.ApplyAffineReal(BFI_VE_def, BFI_VE, A)
    # cd.DispImage(BFI_VE_def)
    # cd.DispImage(MRI_VE)
    # hA = ca.Field3D(BFI_VE.grid(), BFI_VE.memType())
    # cc.AtoH(hA, A)
    # cd.DispHGrid(hA, splat=False)
    # sys.exit()
예제 #8
0
#############################

imagedir = '/home/sci/crottman/korenberg/results/' + reg_type + '/'
if reg_type in ['landmark', 've_reg']:
    fname_end = '_as_MRI_' + col + '.mha'
else:
    fname_end = '_as_MRI_' + col + '_' + str(sz) + '.mha'

if sz >= 512:
    mType = ca.MEM_HOST
else:
    mType = ca.MEM_DEVICE

if reg_type is not 'best':
    grid = cc.MakeGrid([sz, sz, sz], [256.0 / sz, 256.0 / sz, 256.0 / sz],
                       'center')
    blocks = ca.Field3D(grid, mType)
    ca.SetMem(blocks, 0.0)
    weights = blocks.copy()
    ca.SetMem(weights, 0.0)

    for i in xrange(1, 5):
        fname = imagedir + 'block' + str(i) + fname_end
        try:
            blk = cc.LoadMHA(fname, mType)
        except IOError:
            print 'Warning... block ' + str(i) + ' does not exist'
            continue
        blocks += blk
        weight3 = blk.copy()
        try:
def main():
    # Extract the Monkey number and section number from the command line
    global frgNum
    global secOb

    mkyNum = sys.argv[1]
    secNum = sys.argv[2]
    frgNum = int(sys.argv[3])
    write = True

    # if not os.path.exists(os.path.expanduser('~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml'.format(mkyNum,secNum))):
    #     cf = initial(secNum, mkyNum)

    try:
        secOb = Config.Load(
            secSpec,
            pth.expanduser(
                '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml'
                .format(mkyNum, secNum)))
    except IOError as e:
        try:
            temp = Config.LoadYAMLDict(pth.expanduser(
                '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml'
                .format(mkyNum, secNum)),
                                       include=False)
            secOb = Config.MkConfig(temp, secSpec)
        except IOError:
            print 'It appears there is no configuration file for this section. Please initialize one and restart.'
            sys.exit()
        if frgNum == int(secOb.yamlList[frgNum][-6]):
            Fragmenter()
            try:
                secOb = Config.Load(
                    secSpec,
                    pth.expanduser(
                        '~/korenbergNAS/3D_database/Working/configuration_files/SidescapeRelateBlockface/M{0}/section_{1}/include_configFile.yaml'
                        .format(mkyNum, secNum)))
            except IOError:
                print 'It appeas that the include yaml file list does not match your fragmentation number. Please check them and restart.'
                sys.exit()

    if not pth.exists(
            pth.expanduser(secOb.ssiOutPath + 'frag{0}'.format(frgNum))):
        common.Mkdir_p(
            pth.expanduser(secOb.ssiOutPath + 'frag{0}'.format(frgNum)))
    if not pth.exists(
            pth.expanduser(secOb.bfiOutPath + 'frag{0}'.format(frgNum))):
        common.Mkdir_p(
            pth.expanduser(secOb.bfiOutPath + 'frag{0}'.format(frgNum)))
    if not pth.exists(
            pth.expanduser(secOb.ssiSrcPath + 'frag{0}'.format(frgNum))):
        os.mkdir(pth.expanduser(secOb.ssiSrcPath + 'frag{0}'.format(frgNum)))
    if not pth.exists(
            pth.expanduser(secOb.bfiSrcPath + 'frag{0}'.format(frgNum))):
        os.mkdir(pth.expanduser(secOb.bfiSrcPath + 'frag{0}'.format(frgNum)))

    frgOb = Config.MkConfig(secOb.yamlList[frgNum], frgSpec)
    ssiSrc, bfiSrc, ssiMsk, bfiMsk = Loader(frgOb, ca.MEM_HOST)

    #Extract the saturation Image from the color iamge
    bfiHsv = common.FieldFromNPArr(
        matplotlib.colors.rgb_to_hsv(
            np.rollaxis(np.array(np.squeeze(bfiSrc.asnp())), 0, 3)),
        ca.MEM_HOST)
    bfiHsv.setGrid(bfiSrc.grid())
    bfiSat = ca.Image3D(bfiSrc.grid(), bfiHsv.memType())
    ca.Copy(bfiSat, bfiHsv, 1)
    #Histogram equalize, normalize and mask the blockface saturation image
    bfiSat = cb.HistogramEqualize(bfiSat, 256)
    bfiSat.setGrid(bfiSrc.grid())
    bfiSat *= -1
    bfiSat -= ca.Min(bfiSat)
    bfiSat /= ca.Max(bfiSat)
    bfiSat *= bfiMsk
    bfiSat.setGrid(bfiSrc.grid())

    #Write out the blockface region after adjusting the colors with a format that supports header information
    if write:
        common.SaveITKImage(
            bfiSat,
            pth.expanduser(secOb.bfiSrcPath +
                           'frag{0}/M{1}_01_bfi_section_{2}_frag{0}_sat.nrrd'.
                           format(frgNum, secOb.mkyNum, secOb.secNum)))

    #Set the sidescape grid relative to that of the blockface
    ssiSrc.setGrid(ConvertGrid(ssiSrc.grid(), bfiSat.grid()))
    ssiMsk.setGrid(ConvertGrid(ssiMsk.grid(), bfiSat.grid()))
    ssiSrc *= ssiMsk

    #Write out the sidescape masked image in a format that stores the header information
    if write:
        common.SaveITKImage(
            ssiSrc,
            pth.expanduser(secOb.ssiSrcPath +
                           'frag{0}/M{1}_01_ssi_section_{2}_frag{0}.nrrd'.
                           format(frgNum, secOb.mkyNum, secOb.secNum)))

    #Update the image parameters of the sidescape image for future use
    frgOb.imSize = ssiSrc.size().tolist()
    frgOb.imOrig = ssiSrc.origin().tolist()
    frgOb.imSpac = ssiSrc.spacing().tolist()
    updateFragOb(frgOb)

    #Find the affine transform between the two fragments
    bfiAff, ssiAff, aff = Affine(bfiSat, ssiSrc, frgOb)
    updateFragOb(frgOb)

    #Write out the affine transformed images in a format that stores header information
    if write:
        common.SaveITKImage(
            bfiAff,
            pth.expanduser(
                secOb.bfiOutPath +
                'frag{0}/M{1}_01_bfi_section_{2}_frag{0}_aff_ssi.nrrd'.format(
                    frgNum, secOb.mkyNum, secOb.secNum)))
        common.SaveITKImage(
            ssiAff,
            pth.expanduser(
                secOb.ssiOutPath +
                'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_aff_bfi.nrrd'.format(
                    frgNum, secOb.mkyNum, secOb.secNum)))

    bfiVe = bfiAff.copy()
    ssiVe = ssiSrc.copy()
    cc.VarianceEqualize_I(bfiVe, sigma=frgOb.sigVarBfi, eps=frgOb.epsVar)
    cc.VarianceEqualize_I(ssiVe, sigma=frgOb.sigVarSsi, eps=frgOb.epsVar)

    #As of right now, the largest pre-computed FFT table is 2048, so resample onto that grid for registration
    regGrd = ConvertGrid(
        cc.MakeGrid(ca.Vec3Di(2048, 2048, 1), ca.Vec3Df(1, 1, 1),
                    ca.Vec3Df(0, 0, 0)), ssiSrc.grid())
    ssiReg = ca.Image3D(regGrd, ca.MEM_HOST)
    bfiReg = ca.Image3D(regGrd, ca.MEM_HOST)
    cc.ResampleWorld(ssiReg, ssiVe)
    cc.ResampleWorld(bfiReg, bfiVe)

    #Create the default configuration object for IDiff Matching and then set some parameters
    idCf = Config.SpecToConfig(IDiff.Matching.MatchingConfigSpec)
    idCf.compute.useCUDA = True
    idCf.io.outputPrefix = '/home/sci/blakez/IDtest/'

    #Run the registration
    ssiDef, phi = DefReg(ssiReg, bfiReg, frgOb, ca.MEM_DEVICE, idCf)

    #Turn the deformation into a displacement field so it can be applied to the large tif with C++ code
    affV = phi.copy()
    cc.ApplyAffineReal(affV, phi, np.linalg.inv(frgOb.affine))
    ca.HtoV_I(affV)

    #Apply the found deformation to the input ssi
    ssiSrc.toType(ca.MEM_DEVICE)
    cc.HtoReal(phi)
    affPhi = phi.copy()
    ssiBfi = ssiSrc.copy()
    upPhi = ca.Field3D(ssiSrc.grid(), phi.memType())

    cc.ApplyAffineReal(affPhi, phi, np.linalg.inv(frgOb.affine))
    cc.ResampleWorld(upPhi, affPhi, bg=2)
    cc.ApplyHReal(ssiBfi, ssiSrc, upPhi)

    # ssiPhi = ca.Image3D(ssiSrc.grid(), phi.memType())
    # upPhi = ca.Field3D(ssiSrc.grid(), phi.memType())
    # cc.ResampleWorld(upPhi, phi, bg=2)
    # cc.ApplyHReal(ssiPhi, ssiSrc, upPhi)
    # ssiBfi = ssiSrc.copy()
    # cc.ApplyAffineReal(ssiBfi, ssiPhi, np.linalg.inv(frgOb.affine))

    # #Apply affine to the deformation
    # affPhi = phi.copy()
    # cc.ApplyAffineReal(affPhi, phi, np.linalg.inv(frgOb.affine))

    if write:
        common.SaveITKImage(
            ssiBfi,
            pth.expanduser(
                secOb.ssiOutPath +
                'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_def_bfi.nrrd'.format(
                    frgNum, secOb.mkyNum, secOb.secNum)))
        cc.WriteMHA(
            affPhi,
            pth.expanduser(
                secOb.ssiOutPath +
                'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_to_bfi_real.mha'.
                format(frgNum, secOb.mkyNum, secOb.secNum)))
        cc.WriteMHA(
            affV,
            pth.expanduser(
                secOb.ssiOutPath +
                'frag{0}/M{1}_01_ssi_section_{2}_frag{0}_to_bfi_disp.mha'.
                format(frgNum, secOb.mkyNum, secOb.secNum)))

    #Create the list of names that the deformation should be applied to
    # nameList = ['M15_01_0956_SideLight_DimLED_10x_ORG.tif',
    #             'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c1_ORG.tif',
    #             'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c2_ORG.tif',
    #             'M15_01_0956_TyrosineHydroxylase_Ben_10x_Stitching_c3_ORG.tif']

    # appLarge(nameList, affPhi)

    common.DebugHere()