#python #opencv #augmented-reality #object-detection #homography
#python #opencv #дополненная реальность #обнаружение объектов #соответствие
Вопрос:
Предполагается, что я улучшу AR-приложение в Phyton, используя библиотеку OpenCV, производящую сравнение между кадрами. Мы должны спроецировать изображение на обложку книги, которое должно быть обнаружено на существующем видео.
Идея заключалась в том, чтобы использовать омографию между двумя последовательными кадрами, чтобы обновлять омографию между первым и текущим кадром, чтобы спроецировать слой AR. Я обнаружил проблемы в правильной оценке омографии. Кажется, что при каждом обновлении омографии накапливаются ошибки, вероятно, из-за умножения матриц, которое повторяется один раз при каждом сравнении кадров. Результатом на выходном видео является все более плохое позиционирование слоя AR.
Как я могу решить свою проблему, сохраняя подход frame2frame?
Здесь приведена соответствующая часть кода:
[...]
#################################
img_array = []
success = True
success,img_trainCOLOUR = vid.read()
kp_query=kp_ref
des_query=des_ref
#get shapes of images
h,w = img_ref.shape[:2]
h_t, w_t = img_trainCOLOUR.shape[:2]
M_mask = np.identity(3, dtype='float64')
M_prev=M_ar
#performing iterations until last frame
while success :
#obtain grayscale image of the current RGB frame
img_train = cv2.cvtColor(img_trainCOLOUR, cv2.COLOR_BGR2GRAY)
# Implementing the object detection pipeline
# F2F method: correspondences between the previous video frame and the actual frame
kp_train = sift.detect(img_train)
kp_train, des_train = sift.compute(img_train, kp_train)
#find matches
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des_query,des_train,k=2)
#validating matches
good = []
for m ,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
#checking if we found the object
MIN_MATCH_COUNT = 10
if len(good)>MIN_MATCH_COUNT:
#differenciate between source points and destination points
src_pts = np.float32([ kp_query[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp_train[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
#find homography between current and previous video frames
M1, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
#matchesMask = mask.ravel().tolist()
#updated homography between M_mask which contains from first to current-1 frame homography
# and the current frame2frame
M_mask=np.dot(M_mask,M1)
#updated homography between M_prev which contains img_ar layer and first frame homography,
# and from first to current-1 frame homography and the current frame2frame
M = np.dot(M1, M_prev)
#warping the img_ar (transformed as the first frame)
warped = cv2.warpPerspective(img_arCOLOUR, M, (w_t, h_t), flags= cv2.INTER_LINEAR)
warp_mask = cv2.warpPerspective(img_armask, M, (w_t, h_t), flags= cv2.INTER_LINEAR)
#restore previous values of the train images where the mask is black
warp_mask = np.equal(warp_mask, 0)
warped[warp_mask] = img_trainCOLOUR[warp_mask]
#inserting the frames into the frame array in order to reconstruct video sequence
img_array.append(warped)
#save current homography for the successive iteration
M_prev = M
#save the current frame for the successive iteration
img_query=img_train
#warping the mask of the book cover as the current frame
img_maskTrans = cv2.warpPerspective(img_mask, M_mask, (w_t, h_t), flags= cv2.INTER_NEAREST)
#new sift object detection with the current frame and the current mask
# to search only the book cover into the next frame
kp_query=sift.detect(img_query,img_maskTrans)
kp_query, des_query = sift.compute(img_query, kp_query)
#reading next frame for the successive iteration
success,img_trainCOLOUR = vid.read()
[...]
здесь есть входные данные, полный код и выходные данные:
https://drive.google.com/drive/folders/1EAI7wYVFy7SbNZs8Cet7fWEfK2usw-y1?usp=sharing
Спасибо за поддержку
Ответ №1:
Ваше решение отклоняется, потому что вы всегда соответствуете предыдущему изображению, а не фиксированному эталонному. Сохраняйте одно из изображений постоянным. Кроме того, SIFT или любой другой метод сопоставления на основе дескрипторов является излишним для короткого отслеживания базовой линии. Вы могли бы просто обнаружить интересующие точки (Shi-Tomasi goodFeaturesToTrack или Harris corners) и отслеживать их с помощью Lucas-Kanade.
Комментарии:
1. Если вы считаете ответ полезным, пожалуйста, поддержите или примите его.