Пример #1
0
def computeJacard(aname, bname):
    '''
    computeJacard('warpedDiff_IBSR_15_segTRI_fill_ana_IBSR_10_ana_strip.nii.gz', '/opt/registration/data/t1/IBSR18/IBSR_10/IBSR_10_segTRI_fill_ana.nii.gz' )
    computeJacard('warpedDiff_IBSR_13_segTRI_fill_ana_IBSR_10_ana_strip.nii.gz', '/opt/registration/data/t1/IBSR18/IBSR_10/IBSR_10_segTRI_fill_ana.nii.gz' )
    computeJacard('warpedAffine_IBSR_16_segTRI_fill_ana_IBSR_10_ana_strip.nii.gz', '/opt/registration/data/t1/IBSR18/IBSR_10/IBSR_10_segTRI_fill_ana.nii.gz')
    computeJacard('warpedAffine_IBSR_10_segTRI_fill_ana_IBSR_01_ana_strip.nii.gz', '/opt/registration/data/t1/IBSR18/IBSR_10/IBSR_10_seg_ana.nii.gz',None)
    computeJacard('warpedDiff_IBSR_01_segTRI_fill_ana_t1_icbm_normal_1mm_pn0_rf0_peeled.nii.gz', 'data/phantom_1.0mm_normal_crisp.rawb.nii.gz')
    '''
    baseA=rcommon.getBaseFileName(aname)
    baseB=rcommon.getBaseFileName(bname)
    oname="jacard_"+baseA+"_"+baseB+".txt"
    if(os.path.exists(oname)):
        print 'Jacard overlap found. Skipped computation.'
        jacard=np.loadtxt(oname)
        return jacard
    nib_A=nib.load(aname)
    affineA=nib_A.get_affine()
    A=nib_A.get_data().squeeze().astype(np.int32)
    A=np.copy(A, order='C')
    print "A range:",A.min(), A.max()
    nib_B=nib.load(bname)
    newB=nib.Nifti1Image(nib_B.get_data(),affineA)
    newB.to_filename(bname)
    B=nib_B.get_data().squeeze().astype(np.int32)
    B=np.copy(B, order='C')
    print "B range:",B.min(), B.max()
    nlabels=1+np.max([A.max(), B.max()])
    jacard=np.array(tf.compute_jacard(A,B, nlabels))
    print "Jacard range:",jacard.min(), jacard.max()
    np.savetxt(oname,jacard)
    return jacard
Пример #2
0
def fullJacardAllPairs(names, segIndex, warpedPreffix):
    nlines=len(names)
    sumJacard=None
    sumJacard2=None
    minScore=None
    worstPair=None
    nsamples=0.0
    for i in range(nlines):
        if not names[i]:
            continue
        registrationReference=names[i][0]
        reference=names[i][segIndex]
        for j in range(nlines):
            if i==j:
                continue
            if not names[j]:
                continue
            target=names[j][segIndex]
            ###############
            baseReference=rcommon.getBaseFileName(registrationReference)
            baseTarget=rcommon.getBaseFileName(target)
            warpedName=warpedPreffix+baseTarget+'_'+baseReference+'.nii.gz'
            jacard=computeJacard(reference, warpedName)
            nsamples+=1
            if sumJacard==None:
                sumJacard=jacard
                sumJacard2=jacard**2
                worstPair=(i,j)
                minScore=np.sum(jacard)
            else:
                lenOld=len(sumJacard)
                lenNew=len(jacard)
                extendedShape=(np.max([lenOld, lenNew]),)
                newSum=np.zeros(shape=extendedShape, dtype=np.float64)
                newSum2=np.zeros(shape=extendedShape, dtype=np.float64)
                newSum[:lenOld]=sumJacard[...]
                newSum[:lenNew]+=jacard[...]
                newSum2[:lenOld]=sumJacard2[...]
                newSum2[:lenNew]+=jacard[...]**2
                sumJacard=newSum
                sumJacard2=newSum2
                optSum=np.sum(jacard)
                if optSum<minScore:
                    minScore=optSum
                    worstPair=(i,j)
    meanJacard=sumJacard/nsamples
    variance=sumJacard2/nsamples-meanJacard**2#E[X^2] - E[X]^2
    std=np.sqrt(variance)
    return meanJacard, std, worstPair, minScore
Пример #3
0
def warpANTSAffine(targetName, referenceName, affineName, oname, interpolationType='trilinear'):
    baseName=rcommon.getBaseFileName(targetName)
    nib_target=nib.load(targetName)
    nib_reference=nib.load(referenceName)
    M=nib_target.get_affine()
    F=nib_reference.get_affine()
    referenceShape=np.array(nib_reference.shape, dtype=np.int32)
    ######Load and compose affine#####
    if not affineName:
        T=np.eye(4)
    else:
        T=rcommon.readAntsAffine(affineName)
    affineComposition=np.linalg.inv(M).dot(T.dot(F))
    ######################
    if interpolationType=='NN':
        target=nib_target.get_data().squeeze().astype(np.int32)
        target=np.copy(target, order='C')
        warped=np.array(tf.warp_discrete_volumeNNAffine(target, referenceShape, affineComposition)).astype(np.int16)
    else:
        target=nib_target.get_data().squeeze().astype(np.float64)
        target=np.copy(target, order='C')
        warped=np.array(tf.warp_volume_affine(target, referenceShape, affineComposition)).astype(np.int16)
    warped=nib.Nifti1Image(warped, F)
    if not oname:
        oname="warped"+baseName+"nii.gz"
    warped.to_filename(oname)
Пример #4
0
def save_registration_results(init_affine, displacement, inverse, params):
    r'''
    Warp the target image using the obtained deformation field
    '''
    fixed = nib.load(params.reference)
    fixed_affine = fixed.get_affine()
    reference_shape = np.array(fixed.shape, dtype=np.int32)
    warp_dir = params.warp_dir
    base_moving = rcommon.getBaseFileName(params.target)
    base_fixed = rcommon.getBaseFileName(params.reference)
    moving = nib.load(params.target).get_data().squeeze().astype(np.float64)
    moving = moving.copy(order='C')
    warped = np.array(tf.warp_volume(moving, displacement)).astype(np.int16)
    img_warped = nib.Nifti1Image(warped, fixed_affine)
    img_warped.to_filename('warpedDiff_'+base_moving+'_'+base_fixed+'.nii.gz')
    #---warp the target image using the affine transformation only---
    moving = nib.load(params.target).get_data().squeeze().astype(np.float64)
    moving = moving.copy(order='C')
    warped = np.array(
        tf.warp_volume_affine(moving, reference_shape, init_affine)
        ).astype(np.int16)
    img_warped = nib.Nifti1Image(warped, fixed_affine)
    img_warped.to_filename('warpedAffine_'+base_moving+'_'+base_fixed+'.nii.gz')
    #---warp all volumes in the warp directory using NN interpolation
    names = [os.path.join(warp_dir, name) for name in os.listdir(warp_dir)]
    for name in names:
        to_warp = nib.load(name).get_data().squeeze().astype(np.int32)
        to_warp = to_warp.copy(order='C')
        base_warp = rcommon.getBaseFileName(name)
        warped = np.array(
            tf.warp_discrete_volumeNN(to_warp, displacement)).astype(np.int16)
        img_warped = nib.Nifti1Image(warped, fixed_affine)
        img_warped.to_filename('warpedDiff_'+base_warp+'_'+base_fixed+'.nii.gz')
    #---finally, the optional output
    if params.output_list == None:
        return
    if 'lattice' in params.output_list:
        save_deformed_lattice_3d(
            displacement,
            'latticeDispDiff_'+base_moving+'_'+base_fixed+'.nii.gz')
    if 'inv_lattice' in params.output_list:
        save_deformed_lattice_3d(
            inverse, 'invLatticeDispDiff_'+base_moving+'_'+base_fixed+'.nii.gz')
    if 'displacement' in params.output_list:
        np.save('dispDiff_'+base_moving+'_'+base_fixed+'.npy', displacement)
    if 'inverse' in params.output_list:
        np.save('invDispDiff_'+base_moving+'_'+base_fixed+'.npy', inverse)
Пример #5
0
def changeExtension(fname, newExt):
    '''
    changeExtension('/opt/registration/data/myfile.nii.gz', '.ext')
    changeExtension('/opt/registration/data/myfile.nii.gz', '_suffix.ext')
    '''
    directory=os.path.dirname(fname)
    if directory:
        directory+='/'
    basename=rcommon.getBaseFileName(fname)
    return directory+basename+newExt
Пример #6
0
def warpNonlinear(targetName, referenceName, dispName, oname, interpolationType='trilinear'):
    baseName=rcommon.getBaseFileName(targetName)
    displacement=np.load(dispName)
    nib_target = nib.load(targetName)
    if interpolationType=='NN':
        target=nib_target.get_data().squeeze().astype(np.int32)
        target=np.copy(target, order='C')
        warped=np.array(tf.warp_discrete_volumeNN(target, displacement))
    else:
        target=nib_target.get_data().squeeze().astype(np.float64)
        target=np.copy(target, order='C')
        warped=np.array(tf.warp_volume(target, displacement))        
    referenceAffine=nib.load(referenceName).get_affine()
    warped=nib.Nifti1Image(warped, referenceAffine)
    if not oname:
        oname="warped"+baseName+"nii.gz"
    warped.to_filename(oname)
Пример #7
0
def testEstimateMultimodalSyN3DMultiScale(fnameMoving, fnameFixed, fnameAffine,
                                          warpDir, lambdaParam):
    '''
        testEstimateMultimodalDiffeomorphicField3DMultiScale('IBSR_01_ana_strip.nii.gz', 't1_icbm_normal_1mm_pn0_rf0_peeled.nii.gz', 'IBSR_01_ana_strip_t1_icbm_normal_1mm_pn0_rf0_peeledAffine.txt', 100)
    '''
    print 'Registering', fnameMoving, 'to', fnameFixed, 'with lambda=', lambdaParam
    sys.stdout.flush()
    moving = nib.load(fnameMoving)
    fixed = nib.load(fnameFixed)
    referenceShape = np.array(fixed.shape, dtype=np.int32)
    M = moving.get_affine()
    F = fixed.get_affine()
    if not fnameAffine:
        T = np.eye(4)
    else:
        T = rcommon.readAntsAffine(fnameAffine)
    initAffine = np.linalg.inv(M).dot(T.dot(F))
    print initAffine
    moving = moving.get_data().squeeze().astype(np.float64)
    fixed = fixed.get_data().squeeze().astype(np.float64)
    moving = np.copy(moving, order='C')
    fixed = np.copy(fixed, order='C')
    moving = (moving - moving.min()) / (moving.max() - moving.min())
    fixed = (fixed - fixed.min()) / (fixed.max() - fixed.min())
    level = 2
    maskMoving = moving > 0
    maskFixed = fixed > 0
    movingPyramid = [
        img for img in rcommon.pyramid_gaussian_3D(moving, level, maskMoving)
    ]
    fixedPyramid = [
        img for img in rcommon.pyramid_gaussian_3D(fixed, level, maskFixed)
    ]
    #maxOuterIter=[25,50,100,100, 100, 100]
    maxOuterIter = [2, 2, 2, 2, 2, 2]
    baseMoving = rcommon.getBaseFileName(fnameMoving)
    baseFixed = rcommon.getBaseFileName(fnameFixed)
    #    if(os.path.exists('disp_'+baseMoving+'_'+baseFixed+'.npy')):
    #        displacement=np.load('disp_'+baseMoving+'_'+baseFixed+'.npy')
    #    else:
    displacement, directInverse = estimateMultimodalSyN3DMultiScale(
        movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, 0)
    tf.prepend_affine_to_displacement_field(displacement, initAffine)
    #    np.save('disp_'+baseMoving+'_'+baseFixed+'.npy', displacement)
    #####Warp all requested volumes
    #---first the target using tri-linear interpolation---
    moving = nib.load(fnameMoving).get_data().squeeze().astype(np.float64)
    moving = np.copy(moving, order='C')
    warped = np.array(tf.warp_volume(moving, displacement)).astype(np.int16)
    imgWarped = nib.Nifti1Image(warped, F)
    imgWarped.to_filename('warpedDiff_' + baseMoving + '_' + baseFixed +
                          '.nii.gz')
    #---warp using affine only
    moving = nib.load(fnameMoving).get_data().squeeze().astype(np.int32)
    moving = np.copy(moving, order='C')
    warped = np.array(
        tf.warp_discrete_volumeNNAffine(moving, referenceShape,
                                        initAffine)).astype(np.int16)
    imgWarped = nib.Nifti1Image(
        warped, F)  #The affine transformation is the reference's one
    imgWarped.to_filename('warpedAffine_' + baseMoving + '_' + baseFixed +
                          '.nii.gz')
    #---now the rest of the targets using nearest neighbor
    names = [os.path.join(warpDir, name) for name in os.listdir(warpDir)]
    for name in names:
        #---warp using the non-linear deformation
        toWarp = nib.load(name).get_data().squeeze().astype(np.int32)
        toWarp = np.copy(toWarp, order='C')
        baseWarp = rcommon.getBaseFileName(name)
        warped = np.array(tf.warp_discrete_volumeNN(
            toWarp, displacement)).astype(np.int16)
        imgWarped = nib.Nifti1Image(
            warped, F)  #The affine transformation is the reference's one
        imgWarped.to_filename('warpedDiff_' + baseWarp + '_' + baseFixed +
                              '.nii.gz')
        #---warp using affine inly
        warped = np.array(
            tf.warp_discrete_volumeNNAffine(toWarp, referenceShape,
                                            initAffine)).astype(np.int16)
        imgWarped = nib.Nifti1Image(
            warped, F)  #The affine transformation is the reference's one
        imgWarped.to_filename('warpedAffine_' + baseWarp + '_' + baseFixed +
                              '.nii.gz')
    #---finally, the deformed lattices (forward, inverse and resdidual)---
    lambdaParam = 0.9
    maxIter = 100
    tolerance = 1e-4
    print 'Computing inverse...'
    inverse = np.array(
        tf.invert_vector_field3D(displacement, lambdaParam, maxIter,
                                 tolerance))
    residual = np.array(tf.compose_vector_fields3D(displacement, inverse))
    saveDeformedLattice3D(
        displacement,
        'latticeDispDiff_' + baseMoving + '_' + baseFixed + '.nii.gz')
    saveDeformedLattice3D(
        inverse, 'latticeInvDiff_' + baseMoving + '_' + baseFixed + '.nii.gz')
    saveDeformedLattice3D(
        residual, 'latticeResdiff_' + baseMoving + '_' + baseFixed + '.nii.gz')
    residual = np.sqrt(np.sum(residual**2, 3))
    print "Mean residual norm:", residual.mean(), " (", residual.std(
    ), "). Max residual norm:", residual.max()
Пример #8
0
def testEstimateMultimodalSyN3DMultiScale(fnameMoving, fnameFixed, fnameAffine, warpDir, lambdaParam):
    '''
        testEstimateMultimodalDiffeomorphicField3DMultiScale('IBSR_01_ana_strip.nii.gz', 't1_icbm_normal_1mm_pn0_rf0_peeled.nii.gz', 'IBSR_01_ana_strip_t1_icbm_normal_1mm_pn0_rf0_peeledAffine.txt', 100)
    '''
    print 'Registering', fnameMoving, 'to', fnameFixed,'with lambda=',lambdaParam  
    sys.stdout.flush()
    moving = nib.load(fnameMoving)
    fixed= nib.load(fnameFixed)
    referenceShape=np.array(fixed.shape, dtype=np.int32)
    M=moving.get_affine()
    F=fixed.get_affine()
    if not fnameAffine:
        T=np.eye(4)
    else:
        T=rcommon.readAntsAffine(fnameAffine)
    initAffine=np.linalg.inv(M).dot(T.dot(F))
    print initAffine
    moving=moving.get_data().squeeze().astype(np.float64)
    fixed=fixed.get_data().squeeze().astype(np.float64)
    moving=np.copy(moving, order='C')
    fixed=np.copy(fixed, order='C')
    moving=(moving-moving.min())/(moving.max()-moving.min())
    fixed=(fixed-fixed.min())/(fixed.max()-fixed.min())
    level=2
    maskMoving=moving>0
    maskFixed=fixed>0
    movingPyramid=[img for img in rcommon.pyramid_gaussian_3D(moving, level, maskMoving)]
    fixedPyramid=[img for img in rcommon.pyramid_gaussian_3D(fixed, level, maskFixed)]
    #maxOuterIter=[25,50,100,100, 100, 100]
    maxOuterIter=[2,2,2,2,2,2]
    baseMoving=rcommon.getBaseFileName(fnameMoving)
    baseFixed=rcommon.getBaseFileName(fnameFixed)    
#    if(os.path.exists('disp_'+baseMoving+'_'+baseFixed+'.npy')):
#        displacement=np.load('disp_'+baseMoving+'_'+baseFixed+'.npy')
#    else:
    displacement, directInverse=estimateMultimodalSyN3DMultiScale(movingPyramid, fixedPyramid, initAffine, lambdaParam, maxOuterIter, 0)
    tf.prepend_affine_to_displacement_field(displacement, initAffine)
#    np.save('disp_'+baseMoving+'_'+baseFixed+'.npy', displacement)
    #####Warp all requested volumes
    #---first the target using tri-linear interpolation---
    moving=nib.load(fnameMoving).get_data().squeeze().astype(np.float64)
    moving=np.copy(moving, order='C')
    warped=np.array(tf.warp_volume(moving, displacement)).astype(np.int16)
    imgWarped=nib.Nifti1Image(warped, F)
    imgWarped.to_filename('warpedDiff_'+baseMoving+'_'+baseFixed+'.nii.gz')
    #---warp using affine only
    moving=nib.load(fnameMoving).get_data().squeeze().astype(np.int32)
    moving=np.copy(moving, order='C')
    warped=np.array(tf.warp_discrete_volumeNNAffine(moving, referenceShape, initAffine)).astype(np.int16)
    imgWarped=nib.Nifti1Image(warped, F)#The affine transformation is the reference's one
    imgWarped.to_filename('warpedAffine_'+baseMoving+'_'+baseFixed+'.nii.gz')
    #---now the rest of the targets using nearest neighbor
    names=[os.path.join(warpDir,name) for name in os.listdir(warpDir)]
    for name in names:
        #---warp using the non-linear deformation
        toWarp=nib.load(name).get_data().squeeze().astype(np.int32)
        toWarp=np.copy(toWarp, order='C')
        baseWarp=rcommon.getBaseFileName(name)
        warped=np.array(tf.warp_discrete_volumeNN(toWarp, displacement)).astype(np.int16)
        imgWarped=nib.Nifti1Image(warped, F)#The affine transformation is the reference's one
        imgWarped.to_filename('warpedDiff_'+baseWarp+'_'+baseFixed+'.nii.gz')
        #---warp using affine inly
        warped=np.array(tf.warp_discrete_volumeNNAffine(toWarp, referenceShape, initAffine)).astype(np.int16)
        imgWarped=nib.Nifti1Image(warped, F)#The affine transformation is the reference's one
        imgWarped.to_filename('warpedAffine_'+baseWarp+'_'+baseFixed+'.nii.gz')
    #---finally, the deformed lattices (forward, inverse and resdidual)---    
    lambdaParam=0.9
    maxIter=100
    tolerance=1e-4
    print 'Computing inverse...'
    inverse=np.array(tf.invert_vector_field3D(displacement, lambdaParam, maxIter, tolerance))
    residual=np.array(tf.compose_vector_fields3D(displacement, inverse))
    saveDeformedLattice3D(displacement, 'latticeDispDiff_'+baseMoving+'_'+baseFixed+'.nii.gz')
    saveDeformedLattice3D(inverse, 'latticeInvDiff_'+baseMoving+'_'+baseFixed+'.nii.gz')
    saveDeformedLattice3D(residual, 'latticeResdiff_'+baseMoving+'_'+baseFixed+'.nii.gz')
    residual=np.sqrt(np.sum(residual**2,3))
    print "Mean residual norm:", residual.mean()," (",residual.std(), "). Max residual norm:", residual.max()
parser.add_argument('--similarity', action='store', metavar='String',
                    help="Cost-function for assessing image similarity. If a string, one of 'cc': correlation coefficient, 'cr': correlation ratio, 'crl1': L1-norm based correlation ratio, 'mi': mutual information, 'nmi': normalized mutual information, 'slr': supervised log-likelihood ratio. If a callable, it should take a two-dimensional array representing the image joint histogram as an input and return a float.",
                    default='crl1')

parser.add_argument('--interp', action='store', metavar='String',
                   help="'Interpolation method.One of 'pv': Partial volume, 'tri':Trilinear, 'rand': Random interpolation'",
                   default='pv')

params = parser.parse_args()


if __name__ == '__main__':
    fmoving = params.in_file
    fstatic = params.reference
    baseFixed=baseFixed=rcommon.getBaseFileName(fstatic)

    print(fmoving + ' --> ' + fstatic)
    static=nib.load(fstatic)
    static=nib.Nifti1Image(static.get_data().squeeze(), static.get_affine())
    static = nifti2nipy(static)
    moving=nib.load(fmoving)
    moving=nib.Nifti1Image(moving.get_data().squeeze(), moving.get_affine())
    moving= nifti2nipy(moving)

    similarity = params.similarity #'crl1' 'cc', 'mi', 'nmi', 'cr', 'slr'
    interp = params.interp #'pv', 'tri',
    renormalize = True
    optimizer = 'powell'

    print('Setting up registration...')
Пример #10
0
    default='crl1')

parser.add_argument(
    '--interp',
    action='store',
    metavar='String',
    help=
    "'Interpolation method.One of 'pv': Partial volume, 'tri':Trilinear, 'rand': Random interpolation'",
    default='pv')

params = parser.parse_args()

if __name__ == '__main__':
    fmoving = params.in_file
    fstatic = params.reference
    baseFixed = baseFixed = rcommon.getBaseFileName(fstatic)

    print(fmoving + ' --> ' + fstatic)
    static = nib.load(fstatic)
    static = nib.Nifti1Image(static.get_data().squeeze(), static.get_affine())
    static = nifti2nipy(static)
    moving = nib.load(fmoving)
    moving = nib.Nifti1Image(moving.get_data().squeeze(), moving.get_affine())
    moving = nifti2nipy(moving)

    similarity = params.similarity  #'crl1' 'cc', 'mi', 'nmi', 'cr', 'slr'
    interp = params.interp  #'pv', 'tri',
    renormalize = True
    optimizer = 'powell'

    print('Setting up registration...')