在给定图像X的情况下,我正在尝试计算图像Y的姿态。图像Y与旋转90º的图像X相同。
1-所以,对于初学者来说,我找到了两个图像之间的匹配项。
2-然后我存储所有符合条件的匹配项。
3-使用cv2.RANSAC
计算两个图像的匹配之间的单应性。
4-然后对于X图像,我将2d匹配点转换为3d,并在Z轴上添加0。
5-对象点包含原始图像匹配的所有点,而图像点包含训练图像匹配的点。这两个点数组都使用单应性返回的蒙版进行过滤。
6-之后,我将cv2.calibrateCamera
与这些对象点和图像点一起使用。
7-最后我用cv2.projectPoints
来获取轴的投影
我知道直到第5步,结果都是正确的,因为我使用cv2.drawMatches
来查看匹配项。但是,这可能不是获得我想要实现的目标的方法。
matches = flann.knnMatch(query_image.descriptors, descriptors, k=2)
good = []
for m, n in matches:
if m.distance < 0.70 * n.distance:
good.append(m)
current_good = good
src_pts = np.float32([selected_image.keypoints[m.queryIdx].pt for m in current_good]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints[m.trainIdx].pt for m in current_good]).reshape(-1, 1, 2)
homography, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
test = np.zeros(((mask.ravel() > 0).sum(), 3),np.float32) #obj points
test1 = np.zeros(((mask.ravel() > 0).sum(), 2), np.float32) #img points
i=0
counter=0
for m in current_good:
if mask.ravel()[i] == 1:
test[counter][0] = selected_image.keypoints[m.queryIdx].pt[0]
test[counter][1] = selected_image.keypoints[m.queryIdx].pt[1]
test1[counter][0] = selected_image.keypoints[m.trainIdx].pt[0]
test1[counter][1] = selected_image.keypoints[m.trainIdx].pt[1]
counter+=1
i+=1
gray = cv2.cvtColor(self.train_image, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#here start my doubts about what i want to do and if it is possible to do it this way
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera([test], [test1], gray.shape[::-1], None, None)
axis = np.float32([[3, 0, 0], [0, 3, 0], [0, 0, -3]]).reshape(-1, 3)
rvecs = np.array(rvecs, np.float32)
tvecs = np.array(tvecs, np.float32)
imgpts, jac = cv2.projectPoints(axis, rvecs, tvecs, mtx, dist)
尽管如此,cv2.projectPoints
返回的imgpt给出的结果对我来说并没有太大意义,例如:
[[[857.3185 109.317406]]
[[857.2196 108.360954]]
[[857.2846 107.579605]]]
我希望图像具有法线,如此处see this post所示,并且我已成功使用棋盘图像使它正常工作。但是尝试适应一般的形象会给我带来奇怪的结果。