Улучшите оценку гомографии между двумя кадрами видео для приложения AR с помощью Python

Я должен улучшить приложение 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

Спасибо за поддержку


person Aer13    schedule 16.09.2020    source источник


Ответы (1)


Ваше решение дрейфует, потому что вы всегда сопоставляете с предыдущим изображением, а не с фиксированным эталоном. Оставьте одно из изображений постоянным. Кроме того, SIFT или любой другой метод сопоставления на основе дескрипторов является излишним для отслеживания коротких базовых показателей. Вы можете просто обнаружить точки интереса (Shi-Tomasi goodFeaturesToTrack или углы Харриса) и отслеживать их с помощью Lucas-Kanade.

person Francesco Callari    schedule 16.09.2020
comment
Огромное спасибо за помощь! - person Aer13; 17.09.2020
comment
Если вы найдете ответ полезным, пожалуйста, проголосуйте за него или примите его. - person Francesco Callari; 17.09.2020