c++ - Given camera matrices, how to find point correspondances using OpenCV? -
i'm following this tutorial, uses features2d + homography. if have known camera matrix each image, how can optimize result? tried images, didn't work well.
//edit
after reading materials, think should rectify 2 image first. rectification not perfect, vertical line on image 1 correspond vertical band on image 2 generally. there algorithms?
i'm not sure if understand problem. want find corresponding points between images or want improve correctness of matches use of camera intrinsics?
in principle, in order use camera geometry finding matches, need fundamental or essential matrix, depending on wether know camera intrinsics (i.e. calibrated camera). means, need estimate relative rotation , translation of camera. then, computing epipolar lines corresponding features found in 1 image, need search along lines in second image find best match. however, think better rely on automatic feature matching. given fundamental/essential matrix, try luck correctmatches
, move correspondences such reprojection error minimised.
tips better matches
to increase stability , saliency of automatic matches, pays to
- adjust parameters of feature detector
- try different detection algorithms
perform ratio test filter out keypoints have similar second-best match , therefore unstable. done this:
mat descriptors_1, descriptors_2; // obtained feature detector bfmatcher matcher; vector<dmatch> matches; matcher = bfmatcher(norm_l2, false); // norm depends on feature detector vector<vector<dmatch>> match_candidates; const float ratio = 0.8; // or matcher.knnmatch(descriptors_1, descriptors_2, match_candidates, 2); (int = 0; < match_candidates.size(); i++) { if (match_candidates[i][0].distance < ratio * match_candidates[i][1].distance) matches.push_back(match_candidates[i][0]); }
a more involved way of filtering compute reprojection error each keypoint in first frame. means compute corresponding epipolar line in second image , checking how far supposed matching point away line. throwing away points distance exceeds threshold remove matches incompatible epiploar geometry (which assume known). computing error can done (i not remember took code , may have modified bit, editor buggy when code inside lists, sorry bad formatting):
point is, grab fundamental matrix, use compute epilines points , compute distance (the lines given in parametric form need algebra distance).double computereprojectionerror(vector& imgpts1, vector& imgpts2, mat& inlier_mask, const mat& f) { double err = 0; vector lines[2]; int npt = sum(inlier_mask)[0];
// strip outliers validation constrained correspondences // used estimate f vector imgpts1_copy(npt), imgpts2_copy(npt); int c = 0; (int k = 0; k < inlier_mask.size().height; k++) { if (inlier_mask.at(0,k) == 1) { imgpts1_copy[c] = imgpts1[k]; imgpts2_copy[c] = imgpts2[k]; c++; } }
mat imgpt[2] = { mat(imgpts1_copy), mat(imgpts2_copy) }; computecorrespondepilines(imgpt[0], 1, f, lines[0]); computecorrespondepilines(imgpt1, 2, f, lines1); for(int j = 0; j < npt; j++ ) { // error computed distance between point u_l = (x,y) , epipolar line of corresponding point u_r in second image plus reverse, errij = d(u_l, f^t * u_r) + d(u_r, f*u_l) point2f u_l = imgpts1_copy[j], // purpose of function, imagine imgpts1 "left" image , imgpts2 "right" one. doesn't make difference u_r = imgpts2_copy[j]; float a2 = lines1[j][0], // epipolar line b2 = lines1[j]1, c2 = lines1[j][2]; float norm_factor2 = sqrt(pow(a2, 2) + pow(b2, 2)); float a1 = lines[0][j][0], b1 = lines[0][j]1, c1 = lines[0][j][2]; float norm_factor1 = sqrt(pow(a1, 2) + pow(b1, 2));
double errij = fabs(u_l.x * a2 + u_l.y * b2 + c2) / norm_factor2 + fabs(u_r.x * a1 + u_r.y * b1 + c1) / norm_factor1; // distance of (x,y) line (a,b,c) = ax + + c / (a^2 + b^2) err += errij; // @ point, apply threshold , mark bad matches }
return err / npt; }
this similar in outcomefindfundamentalmat
ransac method does. returns mask wherein each match there either1
, meaning used estimate matrix, or0
if thrown out. estimating fundamental matrix less accurate using chessboards.
Comments
Post a Comment