1

У меня есть калиброванная (встроенная функция) камера. Я беру стереофонические фотографии с объектов и использую их в процессе повторной проекции, чтобы найти некоторую трехмерную информацию об объектах.OpenCV: Фундаментальная матрица и движущаяся камера

Для этого сначала я вычислил основную матрицу. Затем я получаю матрицу Essential и оттуда, у меня есть матрица вращения и вектор перевода, а другая - необходимая информация.

Проблема в том, что с различными параметрами я получаю очень разные результаты. Я знаю, что Фундаментальная матрица может отличаться для одного и того же стереоизображения, но я ожидаю, что у меня будет одна матрица вращения и векторы перевода. Однако каждый другой параметр (например, количество согласованных функций) приводит к разным матрицам. Мне что-то не хватает? Правильно ли, что одно и то же стереоизображение должно обеспечивать (симпатичную) же матрицу Rotation, Translation и re-projection?

вот мой код. любая помощь будет оценена по достоинству. Благодаря!

Mat img_1 = imread("images/box01-edited.jpg", CV_LOAD_IMAGE_GRAYSCALE); 
Mat img_2 = imread("images/box02-edited.jpg", CV_LOAD_IMAGE_GRAYSCALE); 


if(!img_1.data || !img_2.data) 
{ return -1; } 

//-- Step 1: Detect the keypoints using SURF Detector 
int minHessian = 1000; 
SurfFeatureDetector detector(minHessian); 
std::vector<KeyPoint> keypoints_1, keypoints_2; 
detector.detect(img_1, keypoints_1); 
detector.detect(img_2, keypoints_2); 

//-- Step 2: Calculate descriptors (feature vectors) 
SurfDescriptorExtractor extractor; 
Mat descriptors_1, descriptors_2; 
extractor.compute(img_1, keypoints_1, descriptors_1); 
extractor.compute(img_2, keypoints_2, descriptors_2); 

//-- Step 3: Matching descriptor vectors with a brute force matcher 
BFMatcher matcher(NORM_L1, true); 
std::vector<DMatch> matches; 
matcher.match(descriptors_1, descriptors_2, matches); 

//-- Draw matches 
Mat img_matches; 
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches); 
//-- Show detected matches 
namedWindow("Matches", CV_WINDOW_NORMAL); 
imshow("Matches", img_matches); 
waitKey(0); 


//-- Step 4: calculate Fundamental Matrix 
vector<Point2f>imgpts1,imgpts2; 
for(unsigned int i = 0; i<matches.size(); i++) 
{ 
// queryIdx is the "left" image 
imgpts1.push_back(keypoints_1[matches[i].queryIdx].pt); 
// trainIdx is the "right" image 
imgpts2.push_back(keypoints_2[matches[i].trainIdx].pt); 
} 
Mat F = findFundamentalMat (imgpts1, imgpts2, FM_RANSAC, 0.1, 0.99); 


//-- Step 5: calculate Essential Matrix 

double data[] = {1189.46 , 0.0, 805.49, 
       0.0, 1191.78, 597.44, 
       0.0, 0.0, 1.0};//Camera Matrix 
Mat K(3, 3, CV_64F, data); 
Mat_<double> E = K.t() * F * K; //according to HZ (9.12) 

//-- Step 6: calculate Rotation Matrix and Translation Vector 
Matx34d P; 
Matx34d P1; 
//decompose E to P' , HZ (9.19) 
SVD svd(E,SVD::MODIFY_A); 
Mat svd_u = svd.u; 
Mat svd_vt = svd.vt; 
Mat svd_w = svd.w; 
Matx33d W(0,-1,0,1,0,0,0,0,1);//HZ 9.13 
Mat_<double> R = svd_u * Mat(W) * svd_vt; //HZ 9.19 
Mat_<double> t = svd_u.col(2); //u3 

if (!CheckCoherentRotation (R)) { 
std::cout<<"resulting rotation is not coherent\n"; 
P1 = 0; 
return 0; 
} 

P1 = Matx34d(R(0,0),R(0,1),R(0,2),t(0), 
      R(1,0),R(1,1),R(1,2),t(1), 
      R(2,0),R(2,1),R(2,2),t(2)); 

//-- Step 7: Reprojection Matrix and rectification data 
Mat R1, R2, P1_, P2_, Q; 
Rect validRoi[2]; 
double dist[] = { -0.03432, 0.05332, -0.00347, 0.00106, 0.00000}; 
Mat D(1, 5, CV_64F, dist); 

stereoRectify(K, D, K, D, img_1.size(), R, t, R1, R2, P1_, P2_, Q, CV_CALIB_ZERO_DISPARITY, 1, img_1.size(), &validRoi[0], &validRoi[1]); 

ответ

1

я настоятельно рекомендую вам, чтобы уточнить расчет фундаментальной матрицы со стандартным алгоритмом 8-бального после устранения дальней функции совпадает с RANSAC algortihm.

Следующий текст взят из документа calib3d для функции findFundamentalMat. status - необязательный выходной параметр для определения выбросов в вашем наборе данных.

статус - Выходной массив N элементов, каждый элемент из которых имеет значение 0 для выбросов и 1 для остальных точек. Массив вычисляется только в методах RANSAC и LMedS. Для других методов он устанавливается для всех 1.

Затем вы можете использовать только совпадающие совпадения с помощью опции CV_FM_8POINT для получения более надежной фундаментальной матрицы.

Смежные вопросы