class PnPRansacCallback : public PointSetRegistrator::Callback
{
public:
- bool checkSubset( InputArray _ms1, InputArray _ms2, int count ) const
- {
- // which kind of checking??
- return true;
- }
+ PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=cv::ITERATIVE,
+ bool _useExtrinsicGuess=false, Mat _rvec=Mat(), Mat _tvec=Mat() )
+ : cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), flags(_flags), useExtrinsicGuess(_useExtrinsicGuess),
+ rvec(_rvec), tvec(_tvec) {}
/* Pre: True */
/* Post: compute _model with given points an eturn number of found models */
{
Mat opoints = _m1.getMat(), ipoints = _m2.getMat();
- Mat cameraMatrix = _model.getMat(0);
- Mat distCoeffs = _model.getMat(1);
- Mat rvec = _model.getMat(2);
- Mat tvec = _model.getMat(3);
- int flags = _model.getMat(4).at<int>(0);
+ bool correspondence = cv::solvePnP( _m1, _m2, cameraMatrix, distCoeffs,
+ rvec, tvec, useExtrinsicGuess, flags );
+
- bool useExtrinsicGuess = true;
+ if(correspondence)
+ {
+ Mat _local_model;
+ _local_model.push_back(rvec);
+ _local_model.push_back(tvec);
- bool correspondence = cv::solvePnP( opoints, ipoints,
- cameraMatrix, distCoeffs, rvec, tvec, useExtrinsicGuess, flags );
+ _local_model.copyTo(_model);
+ }
- return 1;
+ return correspondence;
}
/* Pre: True */
void computeError( InputArray _m1, InputArray _m2, InputArray _model, OutputArray _err ) const
{
- Mat opoints = _m1.getMat(), ipoints = _m2.getMat();
-
- Mat cameraMatrix = _model.getMat(0);
- Mat distCoeffs = _model.getMat(1);
- Mat rvec = _model.getMat(2);
- Mat tvec = _model.getMat(3);
+ Mat opoints = _m1.getMat(), ipoints = _m2.getMat(), model = _model.getMat();
int i, count = opoints.cols;
+ Mat _rvec = model.rowRange(0,3);
+ Mat _tvec = model.rowRange(3, 6);
- Mat projpoints(count, 2, CV_64FC1);
- cv::projectPoints(opoints, rvec, tvec, cameraMatrix, distCoeffs, projpoints);
+ Mat projpoints(count, 2, CV_32FC1);
+ cv::projectPoints(opoints, _rvec, _tvec, cameraMatrix, distCoeffs, projpoints);
const Point2f* ipoints_ptr = ipoints.ptr<Point2f>();
const Point2f* projpoints_ptr = projpoints.ptr<Point2f>();
- _err.create(count, 1, CV_64FC1);
+ _err.create(count, 1, CV_32FC1);
float* err = _err.getMat().ptr<float>();
for ( i = 0; i < count; ++i)
err[i] = cv::norm( ipoints_ptr[i] - projpoints_ptr[i] );
}
+
+
+ Mat cameraMatrix;
+ Mat distCoeffs;
+ int flags;
+ bool useExtrinsicGuess;
+ Mat rvec;
+ Mat tvec;
};
void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
int iterationsCount, float reprojectionError, int minInliersCount,
OutputArray _inliers, int flags)
{
- // NO CHANGES
+
Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
CV_Assert(ipoints.depth() == CV_32F);
CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
- _rvec.create(3, 1, CV_64FC1);
- _tvec.create(3, 1, CV_64FC1);
- Mat rvec = _rvec.getMat();
- Mat tvec = _tvec.getMat();
-
Mat objectPoints = opoints.reshape(3, 1), imagePoints = ipoints.reshape(2, 1);
if (minInliersCount <= 0)
params.useExtrinsicGuess = useExtrinsicGuess;
params.camera.init(cameraMatrix, distCoeffs);
params.flags = flags;
- // END NO CHANGES
- cv::Mat flag(1, 1, CV_8UC1);
- flag.at<int>(0) = params.flags;
+ Ptr<PointSetRegistrator::Callback> cb; // pointer to callback
- // Embed input model to a Mat
- std::vector<cv::Mat> _model;
+ _rvec.create(3, 1, CV_64FC1);
+ _tvec.create(3, 1, CV_64FC1);
- _model.push_back(_cameraMatrix.getMat()); // 3x3
- _model.push_back(_distCoeffs.getMat()); // 4x1
- _model.push_back(_rvec.getMat()); // 3x1
- _model.push_back(_tvec.getMat()); // 3x1
- _model.push_back(flag); // 1x1
+ Mat rvec, tvec;
- cv::Mat local_inliers;
+ if (useExtrinsicGuess) // use given rvec & tvec
+ {
+ rvec = _rvec.getMat();
+ tvec = _tvec.getMat();
+
+ cb = makePtr<PnPRansacCallback>( params.camera.intrinsics, params.camera.distortion,
+ params.flags, params.useExtrinsicGuess, rvec, tvec);
+ }
+ else
+ {
+ rvec = Mat(3, 1, CV_64FC1);
+ tvec = Mat(3, 1, CV_64FC1);
- Ptr<PointSetRegistrator::Callback> cb = makePtr<PnPRansacCallback>(); // pointer to callback
+ cb = makePtr<PnPRansacCallback>( params.camera.intrinsics, params.camera.distortion,
+ params.flags, params.useExtrinsicGuess, rvec, tvec);
+ }
- int model_points = 7; // number of model points. From fundamentalMatrix, must change
+ int model_points = 7; // number of model points
double param1 = params.reprojectionError ; // reprojection error
double param2 = 0.99; // confidence
int param3 = params.iterationsCount; // number maximum iterations
+ cv::Mat _local_model(3, 2, CV_64FC1);
+ cv::Mat _mask_local_inliers(1, opoints.rows, CV_8UC1);
+
// call Ransac
+ int result = createRANSACPointSetRegistrator(cb, model_points, param1, param2, param3)->run(_opoints, _ipoints, _local_model, _mask_local_inliers);
- // NO COMPILE, IT DOESN'T LIKE vector<Mat> in run
- int result = createRANSACPointSetRegistrator(cb, model_points, param1, param2, param3)->run(objectPoints, imagePoints, _model, local_inliers);
+ _rvec.assign(_local_model.rowRange(0,3)); // output rotation vector
+ _tvec.assign(_local_model.rowRange(3,6)); // output translation vector
- _rvec.assign(_model.at<cv::Mat>(2)); // output rotation vector
- _tvec.assign(_model.at<cv::Mat>(3)); // output translation vector
+ //std::cout << _mask_local_inliers.type() << std::endl;
- // output inliers vector
+ Mat _local_inliers;
int count = 0;
- for (int i = 0; i < local_inliers.rows; ++i)
+ for (int i = 0; i < _mask_local_inliers.rows; ++i)
{
- if(local_inliers.at<int>(i) == 1)
+ if((int)_mask_local_inliers.at<uchar>(i) == 1) // inliers mask
{
- cv::Mat & inliers = _inliers.getMat().at<int>(count) = i;
+ _local_inliers.push_back(count); // output inliers vector
count++;
}
}
+ _local_inliers.copyTo(_inliers);
+
// OLD IMPLEMENTATION