Надежная оценка эпиполярной геометрии с помощью Ransac Scikit-изображения
У меня проблемы с достижением высокой производительности с skimage.measure.ransac
при оценке фундаментальной матрицы для пары изображений. Я вижу очень разные результаты с разными случайными семенами по сравнению с OpenCV findFundamentalMatrix
,
Я запускаю Ransac как скимаджа, так и opencv на одних и тех же наборах точек и с (я предполагаю, что) эквивалентными параметрами. Я использую ту же пару изображений, что и уроки по OpenCV Python.
Вот мой демонстрационный скрипт:
import cv2
import numpy as np
from skimage import io
from skimage.measure import ransac
from skimage.feature import ORB, match_descriptors
from skimage.transform import FundamentalMatrixTransform
orb = ORB(n_keypoints=500)
img1 = io.imread('images/right.jpg', as_grey=True)
orb.detect_and_extract(img1)
kp1 = orb.keypoints
desc1 = orb.descriptors
img2 = io.imread('images/left.jpg', as_grey=True)
orb.detect_and_extract(img2)
kp2 = orb.keypoints
desc2 = orb.descriptors
matches = match_descriptors(desc1, desc2, metric='hamming', cross_check=True)
kp1 = kp1[matches[:, 0]]
kp2 = kp2[matches[:, 1]]
n_iter = 10
skimage_inliers = np.empty((n_iter, len(matches)))
opencv_inliers = skimage_inliers.copy()
for i in range(n_iter):
fmat, inliers = ransac((kp1, kp2), FundamentalMatrixTransform,
min_samples=8, residual_threshold=3,
max_trials=5000, stop_probability=0.99,
random_state=i)
skimage_inliers[i, :] = inliers
cv2.setRNGSeed(i)
fmat, inliers = cv2.findFundamentalMat(kp1, kp2, method=cv2.FM_RANSAC,
param1=3, param2=0.99)
opencv_inliers[i, :] = (inliers.ravel() == 1)
skimage_sum_of_vars = np.sum(np.var(skimage_inliers, axis=0))
opencv_sum_of_vars = np.sum(np.var(opencv_inliers, axis=0))
print(f'Scikit-Image sum of inlier variances: {skimage_sum_of_vars:>8.3f}')
print(f'OpenCV sum of inlier variances: {opencv_sum_of_vars:>8.3f}')
И вывод:
Scikit-Image sum of inlier variances: 13.240
OpenCV sum of inlier variances: 0.000
В качестве метрики устойчивости я использую сумму дисперсий вкладышей, полученных из разных случайных семян.
Я ожидаю, что это число будет очень близко к нулю, потому что действительно надежный Ransac должен сходиться к той же модели, независимо от ее случайной инициализации.
Как я могу сделать лыжного мага ransac
вести себя так же крепко, как OpenCV?
Мой код в значительной степени основан на: