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