Added some new warpers.

This commit is contained in:
Ivan Korolev 2012-03-14 12:59:23 +00:00
parent 8ec1c2b03a
commit 6e2507c197
4 changed files with 550 additions and 1 deletions

View File

@ -185,6 +185,147 @@ protected:
}; };
struct CV_EXPORTS FisheyeProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS FisheyeWarper : public RotationWarperBase<FisheyeProjector>
{
public:
FisheyeWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS StereographicProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS StereographicWarper : public RotationWarperBase<StereographicProjector>
{
public:
StereographicWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS CompressedRectilinearProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS CompressedRectilinearWarper : public RotationWarperBase<CompressedRectilinearProjector>
{
public:
CompressedRectilinearWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS CompressedRectilinearPortraitProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS CompressedRectilinearPortraitWarper : public RotationWarperBase<CompressedRectilinearPortraitProjector>
{
public:
CompressedRectilinearPortraitWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS PaniniProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS PaniniWarper : public RotationWarperBase<PaniniProjector>
{
public:
PaniniWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS PaniniPortraitProjector : ProjectorBase
{
float a, b;
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS PaniniPortraitWarper : public RotationWarperBase<PaniniPortraitProjector>
{
public:
PaniniPortraitWarper(float scale, float A = 1, float B = 1)
{
projector_.a = A;
projector_.b = B;
projector_.scale = scale;
}
};
struct CV_EXPORTS MercatorProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS MercatorWarper : public RotationWarperBase<MercatorProjector>
{
public:
MercatorWarper(float scale) { projector_.scale = scale; }
};
struct CV_EXPORTS TransverseMercatorProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
};
class CV_EXPORTS TransverseMercatorWarper : public RotationWarperBase<TransverseMercatorProjector>
{
public:
TransverseMercatorWarper(float scale) { projector_.scale = scale; }
};
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
class CV_EXPORTS PlaneWarperGpu : public PlaneWarper class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
{ {

View File

@ -298,6 +298,333 @@ void CylindricalProjector::mapBackward(float u, float v, float &x, float &y)
else x = y = -1; else x = y = -1;
} }
inline
void FisheyeProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * v_ * cosf(u_);
v = scale * v_ * sinf(u_);
}
inline
void FisheyeProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float u_ = atan2f(v, u);
float v_ = sqrtf(u*u + v*v);
float sinv = sinf(CV_PI - v_);
float x_ = sinv * sinf(u_);
float y_ = cosf(CV_PI - v_);
float z_ = sinv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void StereographicProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = CV_PI - acosf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float r = sinf(v_) / (1 - cosf(v_));
u = scale * r * cos(u_);
v = scale * r * sin(u_);
}
inline
void StereographicProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float u_ = atan2f(v, u);
float r = sqrtf(u*u + v*v);
float v_ = 2 * atanf(1.0 / r);
float sinv = sinf(CV_PI - v_);
float x_ = sinv * sinf(u_);
float y_ = cosf(CV_PI - v_);
float z_ = sinv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CompressedRectilinearProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * a * tanf(u_ / a);
v = scale * b * tanf(v_) / cosf(u_);
}
inline
void CompressedRectilinearProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float aatg = a * atanf(u / a);
float u_ = aatg;
float v_ = atanf(v * cosf(aatg) / b);
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void CompressedRectilinearPortraitProjector::mapForward(float x, float y, float &u, float &v)
{
float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = - scale * a * tanf(u_ / a);
v = scale * b * tanf(v_) / cosf(u_);
}
inline
void CompressedRectilinearPortraitProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= - scale;
v /= scale;
float aatg = a * atanf(u / a);
float u_ = aatg;
float v_ = atanf(v * cosf( aatg ) / b);
float cosv = cosf(v_);
float y_ = cosv * sinf(u_);
float x_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void PaniniProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float tg = a * tanf(u_ / a);
u = scale * tg;
float sinu = sinf(u_);
if ( fabs(sinu) < 1E-7 )
v = scale * b * tanf(v_);
else
v = scale * b * tg * tanf(v_) / sinu;
}
inline
void PaniniProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float lamda = a * atanf(u / a);
float u_ = lamda;
float v_;
if ( fabs(lamda) > 1E-7)
v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda / a)));
else
v_ = atanf(v / b);
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void PaniniPortraitProjector::mapForward(float x, float y, float &u, float &v)
{
float y_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float x_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float tg = a * tanf(u_ / a);
u = - scale * tg;
float sinu = sinf( u_ );
if ( fabs(sinu) < 1E-7 )
v = scale * b * tanf(v_);
else
v = scale * b * tg * tanf(v_) / sinu;
}
inline
void PaniniPortraitProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= - scale;
v /= scale;
float lamda = a * atanf(u / a);
float u_ = lamda;
float v_;
if ( fabs(lamda) > 1E-7)
v_ = atanf(v * sinf(lamda) / (b * a * tanf(lamda/a)));
else
v_ = atanf(v / b);
float cosv = cosf(v_);
float y_ = cosv * sinf(u_);
float x_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void MercatorProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
u = scale * u_;
v = scale * logf( tanf( CV_PI/4 + v_/2 ) );
}
inline
void MercatorProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float v_ = atanf( sinhf(v) );
float u_ = u;
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline
void TransverseMercatorProjector::mapForward(float x, float y, float &u, float &v)
{
float x_ = r_kinv[0] * x + r_kinv[1] * y + r_kinv[2];
float y_ = r_kinv[3] * x + r_kinv[4] * y + r_kinv[5];
float z_ = r_kinv[6] * x + r_kinv[7] * y + r_kinv[8];
float u_ = atan2f(x_, z_);
float v_ = asinf(y_ / sqrtf(x_ * x_ + y_ * y_ + z_ * z_));
float B = cosf(v_) * sinf(u_);
u = scale / 2 * logf( (1+B) / (1-B) );
v = scale * atan2f(tanf(v_), cosf(u_));
}
inline
void TransverseMercatorProjector::mapBackward(float u, float v, float &x, float &y)
{
u /= scale;
v /= scale;
float v_ = asinf( sinf(v) / coshf(u) );
float u_ = atan2f( sinhf(u), cos(v) );
float cosv = cosf(v_);
float x_ = cosv * sinf(u_);
float y_ = sinf(v_);
float z_ = cosv * cosf(u_);
float z;
x = k_rinv[0] * x_ + k_rinv[1] * y_ + k_rinv[2] * z_;
y = k_rinv[3] * x_ + k_rinv[4] * y_ + k_rinv[5] * z_;
z = k_rinv[6] * x_ + k_rinv[7] * y_ + k_rinv[8] * z_;
if (z > 0) { x /= z; y /= z; }
else x = y = -1;
}
inline inline
void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0) void SphericalPortraitProjector::mapForward(float x, float y, float &u0, float &v0)
{ {

View File

@ -75,6 +75,75 @@ public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarper(scale); } Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarper(scale); }
}; };
class FisheyeWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::FisheyeWarper(scale); }
};
class StereographicWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::StereographicWarper(scale); }
};
class CompressedRectilinearWarper: public WarperCreator
{
float a, b;
public:
CompressedRectilinearWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CompressedRectilinearWarper(scale, a, b); }
};
class CompressedRectilinearPortraitWarper: public WarperCreator
{
float a, b;
public:
CompressedRectilinearPortraitWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CompressedRectilinearPortraitWarper(scale, a, b); }
};
class PaniniWarper: public WarperCreator
{
float a, b;
public:
PaniniWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PaniniWarper(scale, a, b); }
};
class PaniniPortraitWarper: public WarperCreator
{
float a, b;
public:
PaniniPortraitWarper(float A = 1, float B = 1)
{
a = A; b = B;
}
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PaniniPortraitWarper(scale, a, b); }
};
class MercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::MercatorWarper(scale); }
};
class TransverseMercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const { return new detail::TransverseMercatorWarper(scale); }
};
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
class PlaneWarperGpu: public WarperCreator class PlaneWarperGpu: public WarperCreator

View File

@ -98,7 +98,7 @@ void printUsage()
" Labels description: Nm is number of matches, Ni is number of inliers,\n" " Labels description: Nm is number of matches, Ni is number of inliers,\n"
" C is confidence.\n" " C is confidence.\n"
"\nCompositing Flags:\n" "\nCompositing Flags:\n"
" --warp (plane|cylindrical|spherical)\n" " --warp (plane|cylindrical|spherical|fisheye|stereographic|compressedPlaneA2B1|compressedPlaneA1.5B1|compressedPlanePortraitA2B1|compressedPlanePortraitA1.5B1|paniniA2B1|paniniA1.5B1|paniniPortraitA2B1|paniniPortraitA1.5B1|mercator|transverseMercator)\n"
" Warp surface type. The default is 'spherical'.\n" " Warp surface type. The default is 'spherical'.\n"
" --seam_megapix <float>\n" " --seam_megapix <float>\n"
" Resolution for seam estimation step. The default is 0.1 Mpx.\n" " Resolution for seam estimation step. The default is 0.1 Mpx.\n"
@ -544,6 +544,18 @@ int main(int argc, char* argv[])
if (warp_type == "plane") warper_creator = new cv::PlaneWarper(); if (warp_type == "plane") warper_creator = new cv::PlaneWarper();
else if (warp_type == "cylindrical") warper_creator = new cv::CylindricalWarper(); else if (warp_type == "cylindrical") warper_creator = new cv::CylindricalWarper();
else if (warp_type == "spherical") warper_creator = new cv::SphericalWarper(); else if (warp_type == "spherical") warper_creator = new cv::SphericalWarper();
else if (warp_type == "fisheye") warper_creator = new cv::FisheyeWarper();
else if (warp_type == "stereographic") warper_creator = new cv::StereographicWarper();
else if (warp_type == "compressedPlaneA2B1") warper_creator = new cv::CompressedRectilinearWarper(2, 1);
else if (warp_type == "compressedPlaneA1.5B1") warper_creator = new cv::CompressedRectilinearWarper(1.5, 1);
else if (warp_type == "compressedPlanePortraitA2B1") warper_creator = new cv::CompressedRectilinearPortraitWarper(2, 1);
else if (warp_type == "compressedPlanePortraitA1.5B1") warper_creator = new cv::CompressedRectilinearPortraitWarper(1.5, 1);
else if (warp_type == "paniniA2B1") warper_creator = new cv::PaniniWarper(2, 1);
else if (warp_type == "paniniA1.5B1") warper_creator = new cv::PaniniWarper(1.5, 1);
else if (warp_type == "paniniPortraitA2B1") warper_creator = new cv::PaniniPortraitWarper(2, 1);
else if (warp_type == "paniniPortraitA1.5B1") warper_creator = new cv::PaniniPortraitWarper(1.5, 1);
else if (warp_type == "mercator") warper_creator = new cv::MercatorWarper();
else if (warp_type == "transverseMercator") warper_creator = new cv::TransverseMercatorWarper();
} }
if (warper_creator.empty()) if (warper_creator.empty())