Я пытаюсь вычислить позу изображения Y для данного изображения X. Изображение Y совпадает с изображением X, повернутым на 90 градусов.
1 -Так для начала я нахожу совпадения между обоими изображениями.
2 - Затем я сохраняю все удачные совпадения.
3 - Гомография между совпадениями на обоих изображениях рассчитывается с использованием cv2.RANSAC
.
4 - Затем дляНа изображении X я преобразую 2d совпадающие точки в 3d, добавив 0 в качестве оси Z.
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)
Однако после всего этого imgpts, возвращаемый cv2.projectPoints
, дает результаты, которые не имеют большого смысла для меня, например:
[[[857.3185 109.317406]]
[[857.2196 108.360954]]
[[857.2846 107.579605]]]
Я хотел бы иметь нормаль к своему изображению, как показано здесь https://docs.opencv.org/trunk/d7/d53/tutorial_py_pose.html, и я успешно заставил его работать, используя изображение шахматной доски.Но попытка приспособиться к общему образу дает мне странные результаты.