def steer(self): N = self.fixedCL.shape # Obtain 2D view SteeringGeneric.update_slices(self) fixed2D, moving2D = self.get_slices() fixedV, movingV = self.get_slice_axes() F = SteeringGeneric.get_frame_matrix(self, fixedV, movingV) # Perform 2D registration scale, T2 = self.register_scale2d(fixed2D, moving2D) print "S = ", scale S = np.identity(3, np.single) * scale T = F[:,0] * T2[0] + F[:,1] * T2[1] C = np.array([N[0]/2, N[1]/2, N[2]/2], np.single) T += C - np.dot(S,C) T = np.single(T) # Subtract identitiy from matrix to match convention for PolyAffineCL for dim in range(3): S[dim, dim] -= 1.0 # Return 3D transformation that will be folded into an existing polyaffine return S, T
def steer(self): N = self.fixedCL.shape # Obtain 2D view SteeringGeneric.update_slices(self) fixed2D, moving2D = self.get_slices() fixedV, movingV = self.get_slice_axes() F = SteeringGeneric.get_frame_matrix(self, fixedV, movingV) # Perform 2D registration R2, T2 = self.register_rigid2d(fixed2D, moving2D) print "R2 = ", R2 print "T2 = ", T2 R = np.identity(3, np.float32) R[:2,:2] = R2 # Project trafo to 3D, from 2D transform in u,v axes from frame F = [u v w] # [u v w] [R2 0; 0 0 1] [x; y; 0] = R [u v w] [x; y; 0] # R = F [R2 0; 0 0 1] inv(F) R = np.dot(F, np.dot(R, np.linalg.inv(F))) T = F[:,0] * T2[0] + F[:,1] * T2[1] C = np.array([N[0]/2, N[1]/2, N[2]/2], np.float32) T += C - np.dot(R,C) # Subtract identity from R to follow convention in PolyAffineCL for dim in range(3): R[dim, dim] -= 1.0 # Return 3D transformation that will be folded into an existing polyaffine return R, T
def __init__(self, fixedCL, movingCL, center, radius): SteeringGeneric.__init__(self, fixedCL, movingCL, center, radius)
def register_scale2d(self, fixed, moving): sizex, sizey = moving.shape x0, y0 = np.mgrid[0:sizex,0:sizey] xc = float(sizex) / 2.0 yc = float(sizey) / 2.0 F = fixed M = moving G = SteeringGeneric.gaussian2(self, fixed.shape) D = G * (F - M) Dnorm = np.linalg.norm(D.ravel()) Dnorm_ref = Dnorm I = np.identity(2, np.single) T = np.zeros((2,), np.single) scale = 1.0 for iter in xrange(20): #print "2D diff", Dnorm S = I * scale dS = I Dnorm_prev = Dnorm D = G * (F - M) Mx, My = np.gradient(M) dScale = np.sum(D * (x0*Mx + y0*My)) dT = np.zeros((2,), np.single) dT[0] = np.sum(D * Mx) dT[1] = np.sum(D * My) if iter == 0: stepScale = 0.2 / max(abs(dScale), 1e-5) stepT = 1.0 / max(np.max(np.abs(dT)), 1e-5) for sub_iter in xrange(20): scale_test = scale + dScale * stepScale T_test = T + dT * stepT Cx = (1.0 - scale_test) * xc Cy = (1.0 - scale_test) * yc x = x0*scale_test + T_test[0] + Cx y = y0*scale_test + T_test[1] + Cy M_test = SteeringGeneric.interp2(self, x, y, moving) D_test = G * (F - M_test) Dnorm_test = np.linalg.norm(D_test.ravel()) if Dnorm_test < Dnorm_prev: stepScale *= 1.2 stepT *= 1.2 Dnorm = Dnorm_test scale = scale_test T = T_test M = M_test break else: stepScale *= 0.5 stepT *= 0.5 if abs(Dnorm-Dnorm_prev) < 1e-4 * abs(Dnorm-Dnorm_ref): break return scale, T
def register_rigid2d(self, fixed, moving): sizex, sizey = moving.shape x0, y0 = np.mgrid[0:sizex,0:sizey] xc = float(sizex) / 2.0 yc = float(sizey) / 2.0 F = fixed M = moving G = SteeringGeneric.gaussian2(self, fixed.shape) D = G * (F - M) Dnorm = np.linalg.norm(D.ravel()) Dnorm_ref = Dnorm R = np.identity(2, np.float32) T = np.zeros((2,), np.float32) angle = 0 for iter in range(20): Dnorm_prev = Dnorm ca = math.cos(angle) sa = math.sin(angle) R = np.array([[ca, -sa], [sa, ca]], np.float32) dR = np.array([[-sa, -ca], [ca, -sa]], np.float32) D = G * (F - M) Mx, My = np.gradient(M) dRx = dR[0,0]*(x0-xc) + dR[0,1]*(y0-yc) dRy = dR[1,0]*(x0-xc) + dR[1,1]*(y0-yc) dAngle = np.sum(G * D * (dRx*Mx + dRy*My)) dT = np.zeros((2,), np.float32) dT[0] = np.sum(D * Mx) dT[1] = np.sum(D * My) if iter == 0: stepAngle = 0.5 / max(abs(dAngle),1e-5) stepT = 1.0 / max(np.max(np.abs(dT)), 1e-5) for sub_iter in range(20): angle_test = angle + dAngle * stepAngle ca = math.cos(angle_test) sa = math.sin(angle_test) R = np.array([[ca, -sa], [sa, ca]], np.float32) Cx = xc - (R[0,0]*xc + R[0,1]*yc) Cy = yc - (R[1,0]*xc + R[1,1]*yc) T_test = T + dT * stepT x = R[0,0] * x0 + R[0,1] * y0 + T_test[0] + Cx y = R[1,0] * x0 + R[1,1] * y0 + T_test[1] + Cy M_test = SteeringGeneric.interp2(self, x, y, moving) D_test = G * (F - M_test) Dnorm_test = np.linalg.norm(D_test.ravel()) if Dnorm_test < Dnorm_prev: stepAngle *= 1.2 stepT *= 1.2 M = M_test Dnorm = Dnorm_test angle = angle_test T = T_test break else: stepAngle *= 0.5 stepT *= 0.5 if abs(Dnorm-Dnorm_prev) < 1e-4 * abs(Dnorm-Dnorm_ref): break return R, T