def estimateNewMonomodalDiffeomorphicField2D(moving, fixed, lambdaParam,
                                             maxOuterIter,
                                             previousDisplacement,
                                             previousDisplacementInverse):
    '''
    Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1,
    as opposed as lambdaParam=150 used in the multimodal case
    '''
    innerTolerance = 1e-4
    displacement = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64)
    gradientField = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64)
    totalDisplacement = np.zeros(shape=(moving.shape) + (2, ),
                                 dtype=np.float64)
    totalDisplacementInverse = np.zeros(shape=(moving.shape) + (2, ),
                                        dtype=np.float64)
    if (previousDisplacement != None):
        totalDisplacement[...] = previousDisplacement
        totalDisplacementInverse[...] = previousDisplacementInverse
    outerIter = 0
    framesToCapture = 5
    maxOuterIter = framesToCapture * (
        (maxOuterIter + framesToCapture - 1) / framesToCapture)
    itersPerCapture = maxOuterIter / framesToCapture
    plt.figure()
    while (outerIter < maxOuterIter):
        outerIter += 1
        print 'Outer iter:', outerIter
        warped = np.array(tf.warp_image(moving, totalDisplacement, None))
        if ((outerIter == 1) or (outerIter % itersPerCapture == 0)):
            plt.subplot(1, framesToCapture + 1,
                        1 + outerIter / itersPerCapture)
            rcommon.overlayImages(warped, fixed, False)
            plt.title('Iter:' + str(outerIter - 1))
        sigmaField = np.ones_like(warped, dtype=np.float64)
        deltaField = fixed - warped
        gradientField[:, :, 0], gradientField[:, :, 1] = sp.gradient(warped)
        maxVariation = 1 + innerTolerance
        innerIter = 0
        displacement[...] = 0
        maxInnerIter = 200
        while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)):
            innerIter += 1
            maxVariation = tf.iterateDisplacementField2DCYTHON(
                deltaField, sigmaField, gradientField, lambdaParam,
                displacement, None)
        #maxDisplacement=np.max(np.abs(displacement))
        expd, invexpd = tf.vector_field_exponential(displacement, True)
        totalDisplacement, stats = tf.compose_vector_fields(
            displacement, totalDisplacement)
        #totalDisplacement=np.array(totalDisplacement)
        totalDisplacementInverse, stats = tf.compose_vector_fields(
            totalDisplacementInverse, invexpd)
        #totalDisplacementInverse=np.array(totalDisplacementInverse)
        #if(maxDisplacement<outerTolerance):
        #break
    print "Iter: ", innerIter, "Max variation:", maxVariation
    return totalDisplacement, totalDisplacementInverse
def estimateNewMonomodalDiffeomorphicField2D(moving, fixed, lambdaParam, maxOuterIter, previousDisplacement, previousDisplacementInverse):
    '''
    Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1,
    as opposed as lambdaParam=150 used in the multimodal case
    '''
    innerTolerance=1e-4
    displacement     =np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    gradientField    =np.empty(shape=(moving.shape)+(2,), dtype=np.float64)
    totalDisplacement=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    totalDisplacementInverse=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    if(previousDisplacement!=None):
        totalDisplacement[...]=previousDisplacement
        totalDisplacementInverse[...]=previousDisplacementInverse
    outerIter=0
    framesToCapture=5
    maxOuterIter=framesToCapture*((maxOuterIter+framesToCapture-1)/framesToCapture)
    itersPerCapture=maxOuterIter/framesToCapture
    plt.figure()
    while(outerIter<maxOuterIter):
        outerIter+=1
        print 'Outer iter:', outerIter
        warped=np.array(tf.warp_image(moving, totalDisplacement, None))
        if((outerIter==1) or (outerIter%itersPerCapture==0)):
            plt.subplot(1,framesToCapture+1, 1+outerIter/itersPerCapture)
            rcommon.overlayImages(warped, fixed, False)
            plt.title('Iter:'+str(outerIter-1))
        sigmaField=np.ones_like(warped, dtype=np.float64)
        deltaField=fixed-warped
        gradientField[:,:,0], gradientField[:,:,1]=sp.gradient(warped)
        maxVariation=1+innerTolerance
        innerIter=0
        displacement[...]=0
        maxInnerIter=200
        while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)):
            innerIter+=1
            maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, gradientField,  lambdaParam, displacement, None)
        #maxDisplacement=np.max(np.abs(displacement))
        expd, invexpd=tf.vector_field_exponential(displacement, True)
        totalDisplacement, stats=tf.compose_vector_fields(displacement, totalDisplacement)
        #totalDisplacement=np.array(totalDisplacement)
        totalDisplacementInverse, stats=tf.compose_vector_fields(totalDisplacementInverse, invexpd)
        #totalDisplacementInverse=np.array(totalDisplacementInverse)
        #if(maxDisplacement<outerTolerance):
            #break
    print "Iter: ",innerIter, "Max variation:",maxVariation
    return totalDisplacement, totalDisplacementInverse
Ejemplo n.º 3
0
def estimateNewMonomodalSyNField2D(moving, fixed, fWarp, fInv, mWarp, mInv,
                                   lambdaParam, maxOuterIter):
    '''
    Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1,
    as opposed as lambdaParam=150 used in the multimodal case
    '''
    innerTolerance = 1e-4
    outerTolerance = 1e-3

    if (mWarp != None):
        totalM = mWarp
        totalMInv = mInv
    else:
        totalM = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64)
        totalMInv = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64)
    if (fWarp != None):
        totalF = fWarp
        totalFInv = fInv
    else:
        totalF = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64)
        totalFInv = np.zeros(shape=(moving.shape) + (2, ), dtype=np.float64)
    outerIter = 0
    framesToCapture = 5
    maxOuterIter = framesToCapture * (
        (maxOuterIter + framesToCapture - 1) / framesToCapture)
    itersPerCapture = maxOuterIter / framesToCapture
    plt.figure()
    while (outerIter < maxOuterIter):
        outerIter += 1
        print 'Outer iter:', outerIter
        wmoving = np.array(tf.warp_image(moving, totalMInv))
        wfixed = np.array(tf.warp_image(fixed, totalFInv))
        if ((outerIter == 1) or (outerIter % itersPerCapture == 0)):
            plt.subplot(1, framesToCapture + 1,
                        1 + outerIter / itersPerCapture)
            rcommon.overlayImages(wmoving, wfixed, False)
            plt.title('Iter:' + str(outerIter - 1))
        #Compute forward update
        sigmaField = np.ones_like(wmoving, dtype=np.float64)
        deltaField = wfixed - wmoving
        movingGradient = np.empty(shape=(wmoving.shape) + (2, ),
                                  dtype=np.float64)
        movingGradient[:, :, 0], movingGradient[:, :, 1] = sp.gradient(wmoving)
        maxVariation = 1 + innerTolerance
        innerIter = 0
        fw = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64)
        maxInnerIter = 1000
        while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)):
            innerIter += 1
            maxVariation = tf.iterateDisplacementField2DCYTHON(
                deltaField, sigmaField, movingGradient, lambdaParam, fw, None)
        #fw*=0.5
        totalF, stats = tf.compose_vector_fields(fw, totalF)
        totalF = np.array(totalF)
        meanDispF = np.mean(np.abs(fw))
        #Compute backward field
        sigmaField = np.ones_like(wfixed, dtype=np.float64)
        deltaField = wmoving - wfixed
        fixedGradient = np.empty(shape=(wfixed.shape) + (2, ),
                                 dtype=np.float64)
        fixedGradient[:, :, 0], fixedGradient[:, :, 1] = sp.gradient(wfixed)
        maxVariation = 1 + innerTolerance
        innerIter = 0
        mw = np.zeros(shape=(fixed.shape) + (2, ), dtype=np.float64)
        maxInnerIter = 1000
        while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)):
            innerIter += 1
            maxVariation = tf.iterateDisplacementField2DCYTHON(
                deltaField, sigmaField, fixedGradient, lambdaParam, mw, None)
        #mw*=0.5
        totalM, stats = tf.compose_vector_fields(mw, totalM)
        totalM = np.array(totalM)
        meanDispM = np.mean(np.abs(mw))
        totalFInv = np.array(
            tf.invert_vector_field_fixed_point(totalF, None, 20, 1e-3, None))
        totalMInv = np.array(
            tf.invert_vector_field_fixed_point(totalM, None, 20, 1e-3, None))
        totalF = np.array(
            tf.invert_vector_field_fixed_point(totalFInv, None, 20, 1e-3,
                                               None))
        totalM = np.array(
            tf.invert_vector_field_fixed_point(totalMInv, None, 20, 1e-3,
                                               None))
        #        totalFInv=np.array(tf.invert_vector_field(totalF, 0.75, 100, 1e-6))
        #        totalMInv=np.array(tf.invert_vector_field(totalM, 0.75, 100, 1e-6))
        #        totalF=np.array(tf.invert_vector_field(totalFInv, 0.75, 100, 1e-6))
        #        totalM=np.array(tf.invert_vector_field(totalMInv, 0.75, 100, 1e-6))
        if (meanDispM + meanDispF < 2 * outerTolerance):
            break
    print "Iter: ", innerIter, "Mean lateral displacement:", 0.5 * (
        meanDispM + meanDispF), "Max variation:", maxVariation
    return totalF, totalFInv, totalM, totalMInv
Ejemplo n.º 4
0
def estimateNewMonomodalSyNField2D(moving, fixed, fWarp, fInv, mWarp, mInv, lambdaParam, maxOuterIter):
    '''
    Warning: in the monomodal case, the parameter lambda must be significantly lower than in the multimodal case. Try lambdaParam=1,
    as opposed as lambdaParam=150 used in the multimodal case
    '''
    innerTolerance=1e-4
    outerTolerance=1e-3
    
    if(mWarp!=None):
        totalM=mWarp
        totalMInv=mInv
    else:
        totalM=np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64)
        totalMInv=np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64)
    if(fWarp!=None):
        totalF=fWarp
        totalFInv=fInv
    else:
        totalF=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
        totalFInv=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    outerIter=0
    framesToCapture=5
    maxOuterIter=framesToCapture*((maxOuterIter+framesToCapture-1)/framesToCapture)
    itersPerCapture=maxOuterIter/framesToCapture
    plt.figure()
    while(outerIter<maxOuterIter):
        outerIter+=1
        print 'Outer iter:', outerIter
        wmoving=np.array(tf.warp_image(moving, totalMInv))
        wfixed=np.array(tf.warp_image(fixed, totalFInv))
        if((outerIter==1) or (outerIter%itersPerCapture==0)):
            plt.subplot(1,framesToCapture+1, 1+outerIter/itersPerCapture)
            rcommon.overlayImages(wmoving, wfixed, False)
            plt.title('Iter:'+str(outerIter-1))
        #Compute forward update
        sigmaField=np.ones_like(wmoving, dtype=np.float64)
        deltaField=wfixed-wmoving
        movingGradient    =np.empty(shape=(wmoving.shape)+(2,), dtype=np.float64)
        movingGradient[:,:,0], movingGradient[:,:,1]=sp.gradient(wmoving)
        maxVariation=1+innerTolerance
        innerIter=0
        fw     =np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64)
        maxInnerIter=1000
        while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)):
            innerIter+=1
            maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, movingGradient,  lambdaParam, fw, None)
        #fw*=0.5
        totalF, stats=tf.compose_vector_fields(fw, totalF)
        totalF=np.array(totalF);
        meanDispF=np.mean(np.abs(fw))
        #Compute backward field
        sigmaField=np.ones_like(wfixed, dtype=np.float64)
        deltaField=wmoving-wfixed
        fixedGradient    =np.empty(shape=(wfixed.shape)+(2,), dtype=np.float64)
        fixedGradient[:,:,0], fixedGradient[:,:,1]=sp.gradient(wfixed)
        maxVariation=1+innerTolerance
        innerIter=0
        mw     =np.zeros(shape=(fixed.shape)+(2,), dtype=np.float64)
        maxInnerIter=1000
        while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)):
            innerIter+=1
            maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, fixedGradient,  lambdaParam, mw, None)
        #mw*=0.5
        totalM, stats=tf.compose_vector_fields(mw, totalM)
        totalM=np.array(totalM);
        meanDispM=np.mean(np.abs(mw))
        totalFInv=np.array(tf.invert_vector_field_fixed_point(totalF, None, 20, 1e-3, None))
        totalMInv=np.array(tf.invert_vector_field_fixed_point(totalM, None, 20, 1e-3, None))
        totalF=np.array(tf.invert_vector_field_fixed_point(totalFInv, None, 20, 1e-3, None))
        totalM=np.array(tf.invert_vector_field_fixed_point(totalMInv, None, 20, 1e-3, None))
#        totalFInv=np.array(tf.invert_vector_field(totalF, 0.75, 100, 1e-6))
#        totalMInv=np.array(tf.invert_vector_field(totalM, 0.75, 100, 1e-6))
#        totalF=np.array(tf.invert_vector_field(totalFInv, 0.75, 100, 1e-6))
#        totalM=np.array(tf.invert_vector_field(totalMInv, 0.75, 100, 1e-6))
        if(meanDispM+meanDispF<2*outerTolerance):
            break
    print "Iter: ",innerIter, "Mean lateral displacement:", 0.5*(meanDispM+meanDispF), "Max variation:",maxVariation
    return totalF, totalFInv, totalM, totalMInv
def estimateNewMultimodalDiffeomorphicField2D(moving, fixed,
                                              lambdaDisplacement,
                                              quantizationLevels, maxOuterIter,
                                              previousDisplacement,
                                              previousDisplacementInverse):
    innerTolerance = 1e-4
    outerTolerance = 1e-3
    sh = moving.shape
    X0, X1 = np.mgrid[0:sh[0], 0:sh[1]]
    displacement = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64)
    residuals = np.zeros(shape=(moving.shape), dtype=np.float64)
    gradientField = np.empty(shape=(moving.shape) + (2, ), dtype=np.float64)
    totalDisplacement = np.zeros(shape=(moving.shape) + (2, ),
                                 dtype=np.float64)
    totalDisplacementInverse = np.zeros(shape=(moving.shape) + (2, ),
                                        dtype=np.float64)
    if (previousDisplacement != None):
        totalDisplacement[...] = previousDisplacement
        totalDisplacementInverse[...] = previousDisplacementInverse
    fixedQ = None
    grayLevels = None
    fixedQ, grayLevels, hist = tf.quantizePositiveImageCYTHON(
        fixed, quantizationLevels)
    fixedQ = np.array(fixedQ, dtype=np.int32)
    finished = False
    outerIter = 0
    maxDisplacement = None
    maxVariation = None
    maxResidual = 0
    while ((not finished) and (outerIter < maxOuterIter)):
        outerIter += 1
        #---E step---
        warped = ndimage.map_coordinates(
            moving,
            [X0 + totalDisplacement[..., 0], X1 + totalDisplacement[..., 1]],
            prefilter=True)
        movingMask = ((moving > 0) * 1.0) * ((fixed > 0) * 1.0)
        warpedMovingMask = ndimage.map_coordinates(
            movingMask,
            [X0 + totalDisplacement[..., 0], X1 + totalDisplacement[..., 1]],
            order=0,
            prefilter=False)
        warpedMovingMask = warpedMovingMask.astype(np.int32)
        means, variances = tf.computeMaskedImageClassStatsCYTHON(
            warpedMovingMask, warped, quantizationLevels, fixedQ)
        means[0] = 0
        means = np.array(means)
        variances = np.array(variances)
        sigmaField = variances[fixedQ]
        deltaField = means[
            fixedQ] - warped  #########Delta-field using Arce's rule
        #--M step--
        g0, g1 = sp.gradient(warped)
        gradientField[:, :, 0] = g0
        gradientField[:, :, 1] = g1
        maxVariation = 1 + innerTolerance
        innerIter = 0
        maxInnerIter = 1000
        displacement[...] = 0
        while ((maxVariation > innerTolerance) and (innerIter < maxInnerIter)):
            innerIter += 1
            maxVariation = tf.iterateDisplacementField2DCYTHON(
                deltaField, sigmaField, gradientField, lambdaDisplacement,
                totalDisplacement, displacement, residuals)
            opt = np.max(residuals)
            if (maxResidual < opt):
                maxResidual = opt
        #--accumulate displacement--
        expd, invexpd = tf.vector_field_exponential(displacement)
        totalDisplacement = tf.compose_vector_fields(expd, totalDisplacement)
        totalDisplacementInverse = tf.compose_vector_fields(
            totalDisplacementInverse, invexpd)
        #--check stop condition--
        nrm = np.sqrt(displacement[..., 0]**2 + displacement[..., 1]**2)
        #maxDisplacement=np.max(nrm)
        maxDisplacement = np.mean(nrm)
        if ((maxDisplacement < outerTolerance) or (outerIter >= maxOuterIter)):
            finished = True


#            plt.figure()
#            plt.subplot(1,3,1)
#            plt.imshow(means[fixedQ],cmap=plt.cm.gray)
#            plt.title("Estimated warped modality")
#            plt.subplot(1,3,2)
#            plt.imshow(fixedQ,cmap=plt.cm.gray)
#            plt.title("Quantized")
#            plt.subplot(1,3,3)
#            plt.plot(means)
#            plt.title("Means")
    print "Iter: ", outerIter, "Mean displacement:", maxDisplacement, "Max variation:", maxVariation, "Max residual:", maxResidual
    if (previousDisplacement != None):
        return totalDisplacement - previousDisplacement, totalDisplacementInverse
    return totalDisplacement, totalDisplacementInverse
def estimateNewMultimodalDiffeomorphicField2D(moving, fixed, lambdaDisplacement, quantizationLevels, maxOuterIter, previousDisplacement, previousDisplacementInverse):
    innerTolerance=1e-4
    outerTolerance=1e-3
    sh=moving.shape
    X0,X1=np.mgrid[0:sh[0], 0:sh[1]]
    displacement     =np.empty(shape=(moving.shape)+(2,), dtype=np.float64)
    residuals=np.zeros(shape=(moving.shape), dtype=np.float64)
    gradientField    =np.empty(shape=(moving.shape)+(2,), dtype=np.float64)
    totalDisplacement=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    totalDisplacementInverse=np.zeros(shape=(moving.shape)+(2,), dtype=np.float64)
    if(previousDisplacement!=None):
        totalDisplacement[...]=previousDisplacement
        totalDisplacementInverse[...]=previousDisplacementInverse
    fixedQ=None
    grayLevels=None
    fixedQ, grayLevels, hist=tf.quantizePositiveImageCYTHON(fixed, quantizationLevels)
    fixedQ=np.array(fixedQ, dtype=np.int32)
    finished=False
    outerIter=0
    maxDisplacement=None
    maxVariation=None
    maxResidual=0
    while((not finished) and (outerIter<maxOuterIter)):
        outerIter+=1
        #---E step---
        warped=ndimage.map_coordinates(moving, [X0+totalDisplacement[...,0], X1+totalDisplacement[...,1]], prefilter=True)
        movingMask=((moving>0)*1.0)*((fixed>0)*1.0)
        warpedMovingMask=ndimage.map_coordinates(movingMask, [X0+totalDisplacement[...,0], X1+totalDisplacement[...,1]], order=0, prefilter=False)
        warpedMovingMask=warpedMovingMask.astype(np.int32)
        means, variances=tf.computeMaskedImageClassStatsCYTHON(warpedMovingMask, warped, quantizationLevels, fixedQ)            
        means[0]=0
        means=np.array(means)
        variances=np.array(variances)
        sigmaField=variances[fixedQ]
        deltaField=means[fixedQ]-warped#########Delta-field using Arce's rule
        #--M step--
        g0, g1=sp.gradient(warped)
        gradientField[:,:,0]=g0
        gradientField[:,:,1]=g1
        maxVariation=1+innerTolerance
        innerIter=0
        maxInnerIter=1000
        displacement[...]=0
        while((maxVariation>innerTolerance)and(innerIter<maxInnerIter)):
            innerIter+=1
            maxVariation=tf.iterateDisplacementField2DCYTHON(deltaField, sigmaField, gradientField,  lambdaDisplacement, totalDisplacement, displacement, residuals)
            opt=np.max(residuals)
            if(maxResidual<opt):
                maxResidual=opt
        #--accumulate displacement--
        expd, invexpd=tf.vector_field_exponential(displacement)
        totalDisplacement=tf.compose_vector_fields(expd, totalDisplacement)
        totalDisplacementInverse=tf.compose_vector_fields(totalDisplacementInverse, invexpd)
        #--check stop condition--
        nrm=np.sqrt(displacement[...,0]**2+displacement[...,1]**2)
        #maxDisplacement=np.max(nrm)
        maxDisplacement=np.mean(nrm)
        if((maxDisplacement<outerTolerance)or(outerIter>=maxOuterIter)):
            finished=True
#            plt.figure()
#            plt.subplot(1,3,1)
#            plt.imshow(means[fixedQ],cmap=plt.cm.gray)    
#            plt.title("Estimated warped modality")
#            plt.subplot(1,3,2)
#            plt.imshow(fixedQ,cmap=plt.cm.gray)
#            plt.title("Quantized")
#            plt.subplot(1,3,3)
#            plt.plot(means)
#            plt.title("Means")
    print "Iter: ",outerIter, "Mean displacement:", maxDisplacement, "Max variation:",maxVariation, "Max residual:", maxResidual
    if(previousDisplacement!=None):
        return totalDisplacement-previousDisplacement, totalDisplacementInverse
    return totalDisplacement, totalDisplacementInverse