I have a cameraman image from skimage.data, and rotated it with 10 degree by cv2.warpAffine. I'm trying to using gradient based image registration method to find the rotation angle. My cost function is the mean squared error. However, the error never continuously descent.
ref_image = np.double(data.camera())
ref_image = np.pad(ref_image, 100, mode='constant')
theta = 10 # degree
translation = (0, 0)
tform = cv2.getRotationMatrix2D((ref_image.shape[1] / 2, ref_image.shape[0] / 2), theta, 1)
tform[:, 2] += np.array(translation)
moving_image = cv2.warpAffine(ref_image, tform, (ref_image.shape[1],ref_image.shape[0]))
tx = 0.0
ty = 0.0
theta = 5
step_size = 0.001
iterations = 50
error = np.zeros(iterations)
for k in range(iterations):
M = cv2.getRotationMatrix2D((ref_image.shape[1] / 2, ref_image.shape[0] / 2), theta, 1)
M[:, 2] += np.array([tx, ty])
warped_target = cv2.warpAffine(ref_image, M, (ref_image.shape[1], ref_image.shape[0]))
error[k] = np.mean((warped_target-moving_image)**2)
dSME1 = np.mean((warped_target-moving_image)*2)
target_gradient_x = cv2.Sobel(warped_target, cv2.CV_64F, 1, 0, ksize=3)
target_gradient_y = cv2.Sobel(warped_target, cv2.CV_64F, 0, 1, ksize=3)
yaxis = np.arange(target_gradient_x.shape[0])-target_gradient_x.shape[0]//2
xaxis = np.arange(target_gradient_y.shape[1])-target_gradient_y.shape[1]//2
xgrid, ygrid = np.meshgrid(xaxis,yaxis)
dtheta = np.sum(dSME1*(-target_gradient_x*(xgrid*np.sin(theta) + ygrid*np.cos(theta)) + target_gradient_y*(xgrid*np.cos(theta) - ygrid*np.sin(theta))))
theta -= step_size*dtheta