make GPU version of solvePnPRansac more consistent with CPU one
This commit is contained in:
parent
1d62fddd31
commit
23416e3db5
@ -868,22 +868,10 @@ namespace cv
|
|||||||
const Mat& camera_mat, const Mat& dist_coef, GpuMat& dst,
|
const Mat& camera_mat, const Mat& dist_coef, GpuMat& dst,
|
||||||
const Stream& stream);
|
const Stream& stream);
|
||||||
|
|
||||||
struct CV_EXPORTS SolvePnpRansacParams
|
CV_EXPORTS void solvePnPRansac(const Mat& object, const Mat& image, const Mat& camera_mat,
|
||||||
{
|
const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess=false,
|
||||||
SolvePnpRansacParams(): subset_size(4),
|
int num_iters=100, float max_dist=8.0, int min_inlier_count=100,
|
||||||
use_extrinsic_guess(false),
|
vector<int>* inliers=NULL);
|
||||||
num_iters(100),
|
|
||||||
max_dist(2.f),
|
|
||||||
inliers(NULL) {}
|
|
||||||
int subset_size;
|
|
||||||
bool use_extrinsic_guess;
|
|
||||||
int num_iters;
|
|
||||||
float max_dist;
|
|
||||||
vector<int>* inliers;
|
|
||||||
};
|
|
||||||
|
|
||||||
CV_EXPORTS void solvePnpRansac(const Mat& object, const Mat& image, const Mat& camera_mat,
|
|
||||||
const Mat& dist_coef, Mat& rvec, Mat& tvec, SolvePnpRansacParams params);
|
|
||||||
|
|
||||||
//////////////////////////////// Filter Engine ////////////////////////////////
|
//////////////////////////////// Filter Engine ////////////////////////////////
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ void cv::gpu::projectPoints(const GpuMat&, const Mat&, const Mat&,
|
|||||||
void cv::gpu::projectPoints(const GpuMat&, const Mat&, const Mat&,
|
void cv::gpu::projectPoints(const GpuMat&, const Mat&, const Mat&,
|
||||||
const Mat&, const Mat&, GpuMat&, const Stream&) { throw_nogpu(); }
|
const Mat&, const Mat&, GpuMat&, const Stream&) { throw_nogpu(); }
|
||||||
|
|
||||||
void cv::gpu::solvePnpRansac(const Mat&, const Mat&, const Mat&, const Mat&,
|
void cv::gpu::solvePnPRansac(const Mat&, const Mat&, const Mat&, const Mat&,
|
||||||
Mat&, Mat&, SolvePnpRansacParams) { throw_nogpu(); }
|
Mat&, Mat&, bool, int, float, int, vector<int>*) { throw_nogpu(); }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -235,18 +235,21 @@ namespace
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& camera_mat,
|
void cv::gpu::solvePnPRansac(const Mat& object, const Mat& image, const Mat& camera_mat,
|
||||||
const Mat& dist_coef, Mat& rvec, Mat& tvec, SolvePnpRansacParams params)
|
const Mat& dist_coef, Mat& rvec, Mat& tvec, bool use_extrinsic_guess,
|
||||||
|
int num_iters, float max_dist, int min_inlier_count,
|
||||||
|
vector<int>* inliers)
|
||||||
{
|
{
|
||||||
CV_Assert(object.rows == 1 && object.cols > 0 && object.type() == CV_32FC3);
|
CV_Assert(object.rows == 1 && object.cols > 0 && object.type() == CV_32FC3);
|
||||||
CV_Assert(image.rows == 1 && image.cols > 0 && image.type() == CV_32FC2);
|
CV_Assert(image.rows == 1 && image.cols > 0 && image.type() == CV_32FC2);
|
||||||
CV_Assert(object.cols == image.cols);
|
CV_Assert(object.cols == image.cols);
|
||||||
CV_Assert(camera_mat.size() == Size(3, 3) && camera_mat.type() == CV_32F);
|
CV_Assert(camera_mat.size() == Size(3, 3) && camera_mat.type() == CV_32F);
|
||||||
CV_Assert(!params.use_extrinsic_guess); // We don't support initial guess for now
|
CV_Assert(!use_extrinsic_guess); // We don't support initial guess for now
|
||||||
CV_Assert(params.num_iters <= solve_pnp_ransac::maxNumIters());
|
CV_Assert(num_iters <= solve_pnp_ransac::maxNumIters());
|
||||||
|
|
||||||
|
const int subset_size = 4;
|
||||||
const int num_points = object.cols;
|
const int num_points = object.cols;
|
||||||
CV_Assert(num_points >= params.subset_size);
|
CV_Assert(num_points >= subset_size);
|
||||||
|
|
||||||
// Unapply distortion and intrinsic camera transformations
|
// Unapply distortion and intrinsic camera transformations
|
||||||
Mat eye_camera_mat = Mat::eye(3, 3, CV_32F);
|
Mat eye_camera_mat = Mat::eye(3, 3, CV_32F);
|
||||||
@ -255,21 +258,21 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
|
|||||||
undistortPoints(image, image_normalized, camera_mat, dist_coef, Mat(), eye_camera_mat);
|
undistortPoints(image, image_normalized, camera_mat, dist_coef, Mat(), eye_camera_mat);
|
||||||
|
|
||||||
// Hypotheses storage (global)
|
// Hypotheses storage (global)
|
||||||
Mat rot_matrices(1, params.num_iters * 9, CV_32F);
|
Mat rot_matrices(1, num_iters * 9, CV_32F);
|
||||||
Mat transl_vectors(1, params.num_iters * 3, CV_32F);
|
Mat transl_vectors(1, num_iters * 3, CV_32F);
|
||||||
|
|
||||||
// Generate set of hypotheses using small subsets of the input data
|
// Generate set of hypotheses using small subsets of the input data
|
||||||
TransformHypothesesGenerator body(object, image_normalized, empty_dist_coef, eye_camera_mat,
|
TransformHypothesesGenerator body(object, image_normalized, empty_dist_coef, eye_camera_mat,
|
||||||
num_points, params.subset_size, rot_matrices, transl_vectors);
|
num_points, subset_size, rot_matrices, transl_vectors);
|
||||||
parallel_for(BlockedRange(0, params.num_iters), body);
|
parallel_for(BlockedRange(0, num_iters), body);
|
||||||
|
|
||||||
// Compute scores (i.e. number of inliers) for each hypothesis
|
// Compute scores (i.e. number of inliers) for each hypothesis
|
||||||
GpuMat d_object(object);
|
GpuMat d_object(object);
|
||||||
GpuMat d_image_normalized(image_normalized);
|
GpuMat d_image_normalized(image_normalized);
|
||||||
GpuMat d_hypothesis_scores(1, params.num_iters, CV_32S);
|
GpuMat d_hypothesis_scores(1, num_iters, CV_32S);
|
||||||
solve_pnp_ransac::computeHypothesisScores(
|
solve_pnp_ransac::computeHypothesisScores(
|
||||||
params.num_iters, num_points, rot_matrices.ptr<float>(), transl_vectors.ptr<float3>(),
|
num_iters, num_points, rot_matrices.ptr<float>(), transl_vectors.ptr<float3>(),
|
||||||
d_object.ptr<float3>(), d_image_normalized.ptr<float2>(), params.max_dist * params.max_dist,
|
d_object.ptr<float3>(), d_image_normalized.ptr<float2>(), max_dist * max_dist,
|
||||||
d_hypothesis_scores.ptr<int>());
|
d_hypothesis_scores.ptr<int>());
|
||||||
|
|
||||||
// Find the best hypothesis index
|
// Find the best hypothesis index
|
||||||
@ -288,10 +291,10 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
|
|||||||
tvec = tvec.reshape(0, 1);
|
tvec = tvec.reshape(0, 1);
|
||||||
|
|
||||||
// Build vector of inlier indices
|
// Build vector of inlier indices
|
||||||
if (params.inliers != NULL)
|
if (inliers != NULL)
|
||||||
{
|
{
|
||||||
params.inliers->clear();
|
inliers->clear();
|
||||||
params.inliers->reserve(num_inliers);
|
inliers->reserve(num_inliers);
|
||||||
|
|
||||||
Point3f p, p_transf;
|
Point3f p, p_transf;
|
||||||
Point2f p_proj;
|
Point2f p_proj;
|
||||||
@ -306,8 +309,8 @@ void cv::gpu::solvePnpRansac(const Mat& object, const Mat& image, const Mat& cam
|
|||||||
p_transf.z = rot[6] * p.x + rot[7] * p.y + rot[8] * p.z + transl[2];
|
p_transf.z = rot[6] * p.x + rot[7] * p.y + rot[8] * p.z + transl[2];
|
||||||
p_proj.x = p_transf.x / p_transf.z;
|
p_proj.x = p_transf.x / p_transf.z;
|
||||||
p_proj.y = p_transf.y / p_transf.z;
|
p_proj.y = p_transf.y / p_transf.z;
|
||||||
if (norm(p_proj - image_normalized.at<Point2f>(0, i)) < params.max_dist)
|
if (norm(p_proj - image_normalized.at<Point2f>(0, i)) < max_dist)
|
||||||
params.inliers->push_back(i);
|
inliers->push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ TEST(transformPoints, accuracy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(solvePnpRansac, accuracy)
|
TEST(solvePnPRansac, accuracy)
|
||||||
{
|
{
|
||||||
RNG& rng = TS::ptr()->get_rng();
|
RNG& rng = TS::ptr()->get_rng();
|
||||||
|
|
||||||
@ -126,12 +126,9 @@ TEST(solvePnpRansac, accuracy)
|
|||||||
projectPoints(object, rvec_gold, tvec_gold, camera_mat, Mat(), image_vec);
|
projectPoints(object, rvec_gold, tvec_gold, camera_mat, Mat(), image_vec);
|
||||||
Mat image(1, image_vec.size(), CV_32FC2, &image_vec[0]);
|
Mat image(1, image_vec.size(), CV_32FC2, &image_vec[0]);
|
||||||
|
|
||||||
Mat rvec;
|
Mat rvec, tvec;
|
||||||
Mat tvec;
|
|
||||||
SolvePnpRansacParams params;
|
|
||||||
vector<int> inliers;
|
vector<int> inliers;
|
||||||
params.inliers = &inliers;
|
gpu::solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, 200, 2.f, 100, &inliers);
|
||||||
solvePnpRansac(object, image, camera_mat, Mat(), rvec, tvec, params);
|
|
||||||
|
|
||||||
ASSERT_LE(norm(rvec - rvec_gold), 1e-3f);
|
ASSERT_LE(norm(rvec - rvec_gold), 1e-3f);
|
||||||
ASSERT_LE(norm(tvec - tvec_gold), 1e-3f);
|
ASSERT_LE(norm(tvec - tvec_gold), 1e-3f);
|
||||||
|
@ -787,8 +787,7 @@ void InitSolvePnpRansac()
|
|||||||
Mat object; gen(object, 1, 4, CV_32FC3, Scalar::all(0), Scalar::all(100));
|
Mat object; gen(object, 1, 4, CV_32FC3, Scalar::all(0), Scalar::all(100));
|
||||||
Mat image; gen(image, 1, 4, CV_32FC2, Scalar::all(0), Scalar::all(100));
|
Mat image; gen(image, 1, 4, CV_32FC2, Scalar::all(0), Scalar::all(100));
|
||||||
Mat rvec, tvec;
|
Mat rvec, tvec;
|
||||||
gpu::solvePnpRansac(object, image, Mat::eye(3, 3, CV_32F), Mat(), rvec, tvec,
|
gpu::solvePnPRansac(object, image, Mat::eye(3, 3, CV_32F), Mat(), rvec, tvec);
|
||||||
gpu::SolvePnpRansacParams());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -811,21 +810,16 @@ TEST(solvePnpRansac)
|
|||||||
Mat rvec, tvec;
|
Mat rvec, tvec;
|
||||||
const int num_iters = 200;
|
const int num_iters = 200;
|
||||||
const float max_dist = 2.0f;
|
const float max_dist = 2.0f;
|
||||||
vector<int> inliers_cpu;
|
vector<int> inliers_cpu, inliers_gpu;
|
||||||
|
|
||||||
CPU_ON;
|
CPU_ON;
|
||||||
solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, num_iters,
|
solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, num_iters,
|
||||||
max_dist, int(num_points * 0.05), &inliers_cpu);
|
max_dist, int(num_points * 0.05), &inliers_cpu);
|
||||||
CPU_OFF;
|
CPU_OFF;
|
||||||
|
|
||||||
gpu::SolvePnpRansacParams params;
|
|
||||||
params.num_iters = num_iters;
|
|
||||||
params.max_dist = max_dist;
|
|
||||||
vector<int> inliers_gpu;
|
|
||||||
params.inliers = &inliers_gpu;
|
|
||||||
|
|
||||||
GPU_ON;
|
GPU_ON;
|
||||||
gpu::solvePnpRansac(object, image, camera_mat, Mat(), rvec, tvec, params);
|
gpu::solvePnPRansac(object, image, camera_mat, Mat(), rvec, tvec, false, num_iters,
|
||||||
|
max_dist, int(num_points * 0.05), &inliers_gpu);
|
||||||
GPU_OFF;
|
GPU_OFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user