从变换矩阵提取无旋转平移信息:SIFT刚性2D变换参数求解
从SIFT配准的刚性变换矩阵提取旋转角度与平移量的问题
我使用SIFT特征检测器处理两幅经过刚性2D变换的图像,需要直接从变换矩阵中提取旋转角度以及中心平移量。附上最小可运行示例,思路是利用图像配准得到的角度构建旋转矩阵,再通过矩阵乘法反向提取平移矩阵,但结果存在细微误差。该示例的目标是从图像配准结果中还原初始设定的参数(tx、ty、angle)。
import numpy as np import cv2 as cv, cv2 import matplotlib.pyplot as plt import math img=cv2.imread(r"\lena_std.tif",cv2.IMREAD_GRAYSCALE) tx=0 #parameters to play which should be totally compensated by the code ty=0 angle=60 rows,cols= img.shape rot_mat = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1) rot_mat=np.vstack([rot_mat, np.array([0,0,1])]) trans_mat = np.array([ [1, 0, tx], [0, 1, ty], [0, 0, 1] ], dtype=np.float32) M=trans_mat @ rot_mat reference_image = img test_image = cv2.warpAffine(img,M[:2,:3],(cols,rows)) def similarity_sift_flann_affine2D (reference_image, test_image): img1=test_image.astype(np.uint8) img2=reference_image.astype(np.uint8) # Initiate SIFT detector sift = cv.SIFT_create() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks = 50) flann = cv.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(des1,des2,k=2) # store all the good matches as per Lowe's ratio test. good = [] for m,n in matches: if m.distance < 0.7*n.distance: #Lowes ratio test good.append(m) MIN_MATCH_COUNT=10 if len(good)>=MIN_MATCH_COUNT: src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) M, mask = cv2.estimateAffinePartial2D(src_pts, dst_pts) #M,mask = cv.estimateAffine2D(src_pts, dst_pts) else: print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) ) matchesMask = None return M M1=similarity_sift_flann_affine2D (reference_image, test_image) sizeImg1=img.shape u, _, vh = np.linalg.svd(M[0:2, 0:2]) R = u @ vh angle2 = math.atan2(R[1,0], R[0,0]) angle2 =np.rad2deg(angle2) cor_rot_mat = cv2.getRotationMatrix2D((cols/2,rows/2),-angle2,1) cor_rot_mat=np.vstack([cor_rot_mat, np.array([0,0,1])]) M1=np.vstack([M1, np.array([0,0,1])]) #cor_trans_mat= np.linalg.inv(cor_rot_mat) @ M1 cor_trans_mat= M1 @ np.linalg.inv(cor_rot_mat) print("angle diff", str(np.abs(angle2)-np.abs(angle))) print("tx diff", str(np.abs(tx)-np.abs(cor_trans_mat[0][2]))) print("ty diff", str(np.abs(ty)-np.abs(cor_trans_mat[1][2])))
恳请各位帮忙解决,非常感谢!
内容的提问来源于stack exchange,提问作者TMul
相关产品推荐
相关产品推荐

