//  [python]
def CameraIteration2(self,conv1,conv2,fx,fy,ox,oy,p,D,R,T,level):

        with tf.name_scope("initialization"):

            conv1_shape=conv1.get_shape()
            nbatch    =int(conv1_shape[0])
            npixels   =int(conv1_shape[1])
            
            nchannels1=int(conv1_shape[2])
            nchannels2=int(2*nchannels1)
            nchannels3=nchannels1+nchannels2

        with tf.name_scope("warp_compute"): 
            Rp = tf.matmul(R,p)
            RP = tf.multiply(Rp,tf.tile(tf.transpose(D,[0,2,1]),[1,3,1]))
            RPT= tf.add(RP,tf.tile(T,[1,1,npixels]))

            Z  = RPT[:,2,:]
            X  = RPT[:,0,:]
            Y  = RPT[:,1,:]

            x  = tf.div(X,Z)
            y  = tf.div(Y,Z)

            px=fx*x+ox
            py=fy*y+oy

        with tf.name_scope("warp_conv"): 

            with tf.name_scope("weighting"):
                _conv2,_mask=utils.interpolate2d(conv2,px,py)
                num_valid=npixels/tf.reduce_sum(_mask,axis=1,keepdims=True)
                mask   = tf.expand_dims(_mask,axis=-1)
                _diff  = tf.expand_dims(_conv2[:,:,0:nchannels1]-conv1,-1)
                _gradx = tf.expand_dims(_conv2[:,:,nchannels1:nchannels2],-1)
                _grady = tf.expand_dims(_conv2[:,:,nchannels2:nchannels3],-1)

                diff   = tf.matmul(_diff,mask)
                grad   = tf.concat([tf.matmul(_gradx,mask),tf.matmul(_grady,mask)],-1)

        with tf.name_scope("lambda_prediction"):

            avg_residual     =num_valid*tf.reduce_mean(tf.abs(tf.squeeze(diff,axis=-1)),axis=1,keep_dims=True)
            lambda_conv1     =self.conv1d(avg_residual,2*nchannels1,name="lambda_"+level+"_1",activation=tf.nn.selu)
            lambda_conv2     =self.conv1d(lambda_conv1,4*nchannels1,name="lambda_"+level+"_2",activation=tf.nn.selu)
            lambda_conv3     =self.conv1d(lambda_conv2,2*nchannels1,name="lambda_"+level+"_3",activation=tf.nn.selu)
            lambda_conv4     =self.conv1d(lambda_conv3,nchannels1,name="lambda_"+level+"_4",activation=tf.nn.selu)
            lambda_conv5     =self.conv1d(lambda_conv4,1,name="lambda_"+level+"_5",activation=tf.nn.tanh)
            lambda_prediction=tf.pow(tf.norm(avg_residual,axis=-1,keepdims=True),1.0+lambda_conv5)
            avg_residual     =tf.reduce_mean(avg_residual)

        with tf.name_scope("FirstEstimation"):

            with tf.name_scope("Solve"):

                jacobianMatrixGeometry=self.CameraJacobianMatrix(x,y,Z,fx,fy)
                AtA=tf.reduce_sum(tf.matmul(jacobianMatrixGeometry,tf.matmul(tf.matmul(grad,grad,transpose_a=True),jacobianMatrixGeometry),transpose_a=True),axis=1)
                Atb=tf.reduce_sum(tf.matmul(jacobianMatrixGeometry,tf.matmul(grad,diff,transpose_a=True),transpose_a=True),axis=1)

                diag   = tf.matrix_diag_part(AtA)
                AtA    = AtA+tf.matrix_diag(tf.squeeze(tf.matmul(tf.expand_dims(diag,axis=-1)+1e-5,lambda_prediction),axis=-1))
                #motion = tf.matmul(tf.matrix_inverse(AtA),Atb)

                if not qr:
                    motion = tf.matmul(tf.matrix_inverse(AtA),Atb)
                else:
                    q_full,r_full=tf.qr(AtA,full_matrices=True)
                    motion=tf.linalg.solve(r_full,tf.matmul(q_full,Atb,transpose_a=True))

            with tf.name_scope("Update"):

                wx,wy,wz,tx,ty,tz=tf.unstack(motion,num=6,axis=1)
                dr=self.AngleaAxisRotation(wx,wy,wz)
                dv=self.VMatrix(wx,wy,wz)
                dt=tf.stack([tx,ty,tz],axis=1)
                updatedR=tf.matmul(dr,R)
                updatedT=tf.add(tf.matmul(dv,dt),tf.matmul(dr,T))

            with tf.name_scope("CheckUpdate"):
                
                Rp = tf.matmul(updatedR,p)
                RP = tf.multiply(Rp,tf.tile(tf.transpose(D,[0,2,1]),[1,3,1]))
                RPT= tf.add(RP,tf.tile(updatedT,[1,1,npixels]))

                Z  = RPT[:,2,:]
                X  = RPT[:,0,:]
                Y  = RPT[:,1,:]

                x  = tf.div(X,Z)
                y  = tf.div(Y,Z)

                px=fx*x+ox
                py=fy*y+oy

                _conv2,_mask=utils.interpolate2d(conv2,px,py)
                _num_valid   =npixels/tf.reduce_sum(_mask,axis=1,keepdims=True)
                _diff        =_mask*(_conv2[:,:,0:nchannels1]-conv1)
                _avg_residual= _num_valid*tf.reduce_mean(tf.abs(_diff),axis=1,keep_dims=True)
                _avg_residual=tf.reduce_mean(_avg_residual)

                motion=tf.squeeze(motion)
                # assert_op = tf.Assert(False,[motion[3:]],summarize=10000)
                # with tf.control_dependencies([assert_op]):
                #     motion=tf.identity(motion)



                # def return_origin():
                #     return R,T,tf.to_float(0.0),tf.to_float(0.0),tf.squeeze(num_valid)

                # def return_update():
                #     global motion
                #     assert_op = tf.Assert(False,[tf.norm(motion[:3]),tf.norm(motion[3:])],summarize=10000)
                #     with tf.control_dependencies([assert_op]):
                #         motion=tf.identity(motion)
                #     return updatedR,updatedT,tf.norm(motion[:3]),tf.norm(motion[3:]),tf.squeeze(num_valid)

        return tf.cond(tf.less(_avg_residual,residual_ratio*avg_residual),
                               lambda:(updatedR,updatedT,tf.norm(motion[:3]),tf.norm(motion[3:]),tf.squeeze(num_valid)),
                               lambda:(R,T,tf.to_float(0.0),tf.to_float(0.0),tf.squeeze(num_valid)))