Merge pull request #18607 from zteffi:warp-point-backward

pull/18652/head
Alexander Alekhin 4 years ago
commit 3a99fb9d34
  1. 31
      modules/stitching/include/opencv2/stitching/detail/warpers.hpp
  2. 8
      modules/stitching/include/opencv2/stitching/detail/warpers_inl.hpp
  3. 16
      modules/stitching/include/opencv2/stitching/warpers.hpp
  4. 28
      modules/stitching/src/warpers.cpp
  5. 131
      modules/stitching/test/test_reprojection.cpp

@ -70,6 +70,23 @@ public:
*/
virtual Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) = 0;
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Backward-projected point
*/
#if CV_VERSION_MAJOR == 4
virtual Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
CV_UNUSED(pt); CV_UNUSED(K); CV_UNUSED(R);
CV_Error(Error::StsNotImplemented, "");
}
#else
virtual Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R) = 0;
#endif
/** @brief Builds the projection maps according to the given camera data.
@param src_size Source image size
@ -143,6 +160,8 @@ class CV_EXPORTS_TEMPLATE RotationWarperBase : public RotationWarper
public:
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
@ -189,6 +208,9 @@ public:
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T);
Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R, InputArray T);
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE;
@ -228,6 +250,15 @@ public:
*/
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray H) CV_OVERRIDE;
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param H Camera extrinsic parameters
@return Backward-projected point
*/
Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray H) CV_OVERRIDE;
/** @brief Builds the projection maps according to the given camera data.
@param src_size Source image size

@ -61,6 +61,14 @@ Point2f RotationWarperBase<P>::warpPoint(const Point2f &pt, InputArray K, InputA
return uv;
}
template <class P>
Point2f RotationWarperBase<P>::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
projector_.setCameraParams(K, R);
Point2f xy;
projector_.mapBackward(pt.x, pt.y, xy.x, xy.y);
return xy;
}
template <class P>
Rect RotationWarperBase<P>::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray _xmap, OutputArray _ymap)

@ -65,6 +65,22 @@ namespace cv {
*/
CV_WRAP Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
/** @brief Projects the image point backward.
@param pt Projected point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Backward-projected point
*/
#if CV_VERSION_MAJOR == 4
CV_WRAP Point2f warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
CV_UNUSED(pt); CV_UNUSED(K); CV_UNUSED(R);
CV_Error(Error::StsNotImplemented, "");
}
#else
CV_WRAP Point2f warpPointBackward(const Point2f &pt, InputArray K, InputArray R);
#endif
/** @brief Builds the projection maps according to the given camera data.
@param src_size Source image size

@ -92,6 +92,14 @@ Point2f PyRotationWarper::warpPoint(const Point2f &pt, InputArray K, InputArray
{
return rw.get()->warpPoint(pt, K, R);
}
#if CV_VERSION_MAJOR != 4
Point2f PyRotationWarper::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
return rw.get()->warpPointBackward(pt, K, R);
}
#endif
Rect PyRotationWarper::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
{
return rw.get()->buildMaps(src_size, K, R, xmap, ymap);
@ -164,6 +172,20 @@ Point2f PlaneWarper::warpPoint(const Point2f &pt, InputArray K, InputArray R)
Mat_<float> T(3, 1, tz);
return warpPoint(pt, K, R, T);
}
Point2f PlaneWarper::warpPointBackward(const Point2f& pt, InputArray K, InputArray R, InputArray T)
{
projector_.setCameraParams(K, R, T);
Point2f xy;
projector_.mapBackward(pt.x, pt.y, xy.x, xy.y);
return xy;
}
Point2f PlaneWarper::warpPointBackward(const Point2f& pt, InputArray K, InputArray R)
{
float tz[] = { 0.f, 0.f, 0.f };
Mat_<float> T(3, 1, tz);
return warpPointBackward(pt, K, R, T);
}
Rect PlaneWarper::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
{
@ -299,6 +321,12 @@ Point2f AffineWarper::warpPoint(const Point2f &pt, InputArray K, InputArray H)
return PlaneWarper::warpPoint(pt, K, R, T);
}
Point2f AffineWarper::warpPointBackward(const Point2f& pt, InputArray K, InputArray H)
{
Mat R, T;
getRTfromHomogeneous(H, R, T);
return PlaneWarper::warpPointBackward(pt, K, R, T);
}
Rect AffineWarper::buildMaps(Size src_size, InputArray K, InputArray H, OutputArray xmap, OutputArray ymap)
{

@ -0,0 +1,131 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "opencv2/stitching/warpers.hpp"
namespace opencv_test { namespace {
class ReprojectionTest : public ::testing::Test {
protected:
const size_t TEST_COUNT = 15;
Mat K, R;
RNG rng = RNG(0);
ReprojectionTest()
{
K = Mat::eye(3, 3, CV_32FC1);
float angle = (float)(30.0 * CV_PI / 180.0);
float rotationMatrix[9] = {
(float)cos(angle), (float)sin(angle), 0,
(float)-sin(angle), (float)cos(angle), 0,
0, 0, 1
};
Mat(3, 3, CV_32FC1, rotationMatrix).copyTo(R);
}
void TestReprojection(Ptr<detail::RotationWarper> warper, Point2f pt) {
Point2f projected_pt = warper->warpPoint(pt, K, R);
Point2f reprojected_pt = warper->warpPointBackward(projected_pt, K, R);
EXPECT_NEAR(pt.x, reprojected_pt.x, float( 1e-5));
EXPECT_NEAR(pt.y, reprojected_pt.y, float( 1e-5));
}
};
TEST_F(ReprojectionTest, PlaneWarper)
{
Ptr<WarperCreator> creator = makePtr<PlaneWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, AffineWarper)
{
Ptr<WarperCreator> creator = makePtr<AffineWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, CylindricalWarper)
{
Ptr<WarperCreator> creator = makePtr<CylindricalWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, SphericalWarper)
{
Ptr<WarperCreator> creator = makePtr<SphericalWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, FisheyeWarper)
{
Ptr<WarperCreator> creator = makePtr<FisheyeWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, StereographicWarper)
{
Ptr<WarperCreator> creator = makePtr<StereographicWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, CompressedRectilinearWarper)
{
Ptr<WarperCreator> creator = makePtr<CompressedRectilinearWarper>(1.5f, 1.0f);
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, CompressedRectilinearPortraitWarper)
{
Ptr<WarperCreator> creator = makePtr<CompressedRectilinearPortraitWarper>(1.5f, 1.0f);
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, PaniniWarper)
{
Ptr<WarperCreator> creator = makePtr<PaniniWarper>(1.5f, 1.0f);
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, PaniniPortraitWarper)
{
Ptr<WarperCreator> creator = makePtr<PaniniPortraitWarper>(1.5f, 1.0f);
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, MercatorWarper)
{
Ptr<WarperCreator> creator = makePtr<MercatorWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
TEST_F(ReprojectionTest, TransverseMercatorWarper)
{
Ptr<WarperCreator> creator = makePtr<TransverseMercatorWarper>();
for (size_t i = 0; i < TEST_COUNT; ++i) {
TestReprojection(creator->create(1), Point2f(rng.uniform(-1.f, 1.f), rng.uniform(-1.f, 1.f)));
}
}
}} // namespace
Loading…
Cancel
Save