Refactored warpers in the stitching module, added buildMaps function into the RotationWarper interface
This commit is contained in:
@@ -52,18 +52,20 @@
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
|
||||
class CV_EXPORTS Warper
|
||||
class CV_EXPORTS RotationWarper
|
||||
{
|
||||
public:
|
||||
virtual ~Warper() {}
|
||||
virtual Point warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode) = 0;
|
||||
virtual void warpBackward(const Mat &src, const Mat &K, const Mat &R, Mat &dst, Size dstSize,
|
||||
int interp_mode, int border_mode) = 0;
|
||||
virtual Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
|
||||
int interp_mode, int border_mode) = 0;
|
||||
virtual Rect warpRoi(const Size &sz, const Mat &K, const Mat &R) = 0;
|
||||
virtual Rect warpRoi(const Size &sz, const Mat &K, const Mat &R, const Mat &T) = 0;
|
||||
virtual ~RotationWarper() {}
|
||||
|
||||
virtual Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap) = 0;
|
||||
|
||||
virtual Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst) = 0;
|
||||
|
||||
virtual void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Size dst_size, Mat &dst) = 0;
|
||||
|
||||
virtual Rect warpRoi(Size src_size, const Mat &K, const Mat &R) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -83,27 +85,28 @@ struct CV_EXPORTS ProjectorBase
|
||||
|
||||
|
||||
template <class P>
|
||||
class CV_EXPORTS WarperBase : public Warper
|
||||
class CV_EXPORTS RotationWarperBase : public RotationWarper
|
||||
{
|
||||
public:
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
void warpBackward(const Mat &src, const Mat &K, const Mat &R, Mat &dst, Size dstSize,
|
||||
int interp_mode, int border_mode);
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
Rect warpRoi(const Size &sz, const Mat &K, const Mat &R);
|
||||
Rect warpRoi(const Size &sz, const Mat &K, const Mat &R, const Mat &T);
|
||||
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
void warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Size dst_size, Mat &dst);
|
||||
|
||||
Rect warpRoi(Size src_size, const Mat &K, const Mat &R);
|
||||
|
||||
protected:
|
||||
|
||||
// Detects ROI of the destination image. It's correct for any projection.
|
||||
virtual void detectResultRoi(Point &dst_tl, Point &dst_br);
|
||||
virtual void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
|
||||
|
||||
// Detects ROI of the destination image by walking over image border.
|
||||
// Correctness for any projection isn't guaranteed.
|
||||
void detectResultRoiByBorder(Point &dst_tl, Point &dst_br);
|
||||
void detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br);
|
||||
|
||||
Size src_size_;
|
||||
P projector_;
|
||||
};
|
||||
|
||||
@@ -116,17 +119,22 @@ struct CV_EXPORTS PlaneProjector : ProjectorBase
|
||||
|
||||
|
||||
// Projects image onto z = plane_dist plane
|
||||
class CV_EXPORTS PlaneWarper : public WarperBase<PlaneProjector>
|
||||
class CV_EXPORTS PlaneWarper : public RotationWarperBase<PlaneProjector>
|
||||
{
|
||||
public:
|
||||
PlaneWarper(float scale = 1.f) { projector_.scale = scale; }
|
||||
|
||||
void setScale(float scale) { projector_.scale = scale; }
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
Rect warpRoi(const Size &sz, const Mat &K, const Mat &R, const Mat &T);
|
||||
|
||||
Rect buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
Rect warpRoi(Size src_size, const Mat &K, const Mat &R, const Mat &T);
|
||||
|
||||
protected:
|
||||
void detectResultRoi(Point &dst_tl, Point &dst_br);
|
||||
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
|
||||
};
|
||||
|
||||
|
||||
@@ -135,10 +143,12 @@ class CV_EXPORTS PlaneWarperGpu : public PlaneWarper
|
||||
{
|
||||
public:
|
||||
PlaneWarperGpu(float scale = 1.f) : PlaneWarper(scale) {}
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
private:
|
||||
gpu::GpuMat d_xmap_, d_ymap_, d_dst_, d_src_;
|
||||
@@ -155,13 +165,13 @@ struct CV_EXPORTS SphericalProjector : ProjectorBase
|
||||
|
||||
// Projects image onto unit sphere with origin at (0, 0, 0).
|
||||
// Poles are located at (0, -1, 0) and (0, 1, 0) points.
|
||||
class CV_EXPORTS SphericalWarper : public WarperBase<SphericalProjector>
|
||||
class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector>
|
||||
{
|
||||
public:
|
||||
SphericalWarper(float scale) { projector_.scale = scale; }
|
||||
|
||||
protected:
|
||||
void detectResultRoi(Point &dst_tl, Point &dst_br);
|
||||
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
|
||||
};
|
||||
|
||||
|
||||
@@ -170,8 +180,9 @@ class CV_EXPORTS SphericalWarperGpu : public SphericalWarper
|
||||
{
|
||||
public:
|
||||
SphericalWarperGpu(float scale) : SphericalWarper(scale) {}
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
private:
|
||||
gpu::GpuMat d_xmap_, d_ymap_, d_dst_, d_src_;
|
||||
@@ -187,14 +198,16 @@ struct CV_EXPORTS CylindricalProjector : ProjectorBase
|
||||
|
||||
|
||||
// Projects image onto x * x + z * z = 1 cylinder
|
||||
class CV_EXPORTS CylindricalWarper : public WarperBase<CylindricalProjector>
|
||||
class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjector>
|
||||
{
|
||||
public:
|
||||
CylindricalWarper(float scale) { projector_.scale = scale; }
|
||||
|
||||
protected:
|
||||
void detectResultRoi(Point &dst_tl, Point &dst_br)
|
||||
{ WarperBase<CylindricalProjector>::detectResultRoiByBorder(dst_tl, dst_br); }
|
||||
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||
{
|
||||
RotationWarperBase<CylindricalProjector>::detectResultRoiByBorder(src_size, dst_tl, dst_br);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -203,8 +216,9 @@ class CV_EXPORTS CylindricalWarperGpu : public CylindricalWarper
|
||||
{
|
||||
public:
|
||||
CylindricalWarperGpu(float scale) : CylindricalWarper(scale) {}
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode);
|
||||
|
||||
Point warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst);
|
||||
|
||||
private:
|
||||
gpu::GpuMat d_xmap_, d_ymap_, d_dst_, d_src_;
|
||||
|
@@ -50,17 +50,15 @@ namespace cv {
|
||||
namespace detail {
|
||||
|
||||
template <class P>
|
||||
Point WarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
int interp_mode, int border_mode)
|
||||
Rect RotationWarperBase<P>::buildMaps(Size src_size, const Mat &K, const Mat &R, Mat &xmap, Mat &ymap)
|
||||
{
|
||||
src_size_ = src.size();
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(dst_tl, dst_br);
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
Mat xmap(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
|
||||
Mat ymap(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
|
||||
xmap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
|
||||
ymap.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, CV_32F);
|
||||
|
||||
float x, y;
|
||||
for (int v = dst_tl.y; v <= dst_br.y; ++v)
|
||||
@@ -73,30 +71,41 @@ Point WarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
|
||||
}
|
||||
}
|
||||
|
||||
dst.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, src.type());
|
||||
remap(src, dst, xmap, ymap, interp_mode, border_mode);
|
||||
|
||||
return dst_tl;
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
void WarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, Mat &dst, Size dstSize,
|
||||
int interp_mode, int border_mode)
|
||||
Point RotationWarperBase<P>::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Mat &dst)
|
||||
{
|
||||
Mat xmap, ymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
remap(src, dst, xmap, ymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
void RotationWarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
|
||||
Size dst_size, Mat &dst)
|
||||
{
|
||||
src_size_ = dstSize;
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point src_tl, src_br;
|
||||
detectResultRoi(src_tl, src_br);
|
||||
detectResultRoi(dst_size, src_tl, src_br);
|
||||
CV_Assert(src_br.x - src_tl.x + 1 == src.cols && src_br.y - src_tl.y + 1 == src.rows);
|
||||
|
||||
Mat xmap(dstSize, CV_32F);
|
||||
Mat ymap(dstSize, CV_32F);
|
||||
Mat xmap(dst_size, CV_32F);
|
||||
Mat ymap(dst_size, CV_32F);
|
||||
|
||||
float u, v;
|
||||
for (int y = 0; y < dstSize.height; ++y)
|
||||
for (int y = 0; y < dst_size.height; ++y)
|
||||
{
|
||||
for (int x = 0; x < dstSize.width; ++x)
|
||||
for (int x = 0; x < dst_size.width; ++x)
|
||||
{
|
||||
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
|
||||
xmap.at<float>(y, x) = u - src_tl.x;
|
||||
@@ -104,43 +113,25 @@ void WarperBase<P>::warpBackward(const Mat &src, const Mat &K, const Mat &R, Mat
|
||||
}
|
||||
}
|
||||
|
||||
dst.create(dstSize, src.type());
|
||||
dst.create(dst_size, src.type());
|
||||
remap(src, dst, xmap, ymap, interp_mode, border_mode);
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
Point WarperBase<P>::warp(const Mat &/*src*/, const Mat &/*K*/, const Mat &/*R*/, const Mat &/*T*/, Mat &/*dst*/,
|
||||
int /*interp_mode*/, int /*border_mode*/)
|
||||
Rect RotationWarperBase<P>::warpRoi(Size src_size, const Mat &K, const Mat &R)
|
||||
{
|
||||
CV_Error(CV_StsNotImplemented, "translation support isn't implemented");
|
||||
return Point();
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
Rect WarperBase<P>::warpRoi(const Size &sz, const Mat &K, const Mat &R)
|
||||
{
|
||||
src_size_ = sz;
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(dst_tl, dst_br);
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
return Rect(dst_tl, Point(dst_br.x + 1, dst_br.y + 1));
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
Rect WarperBase<P>::warpRoi(const Size &/*sz*/, const Mat &/*K*/, const Mat &/*R*/, const Mat &/*T*/)
|
||||
{
|
||||
CV_Error(CV_StsNotImplemented, "translation support isn't implemented");
|
||||
return Rect();
|
||||
}
|
||||
|
||||
|
||||
template <class P>
|
||||
void WarperBase<P>::detectResultRoi(Point &dst_tl, Point &dst_br)
|
||||
void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||
{
|
||||
float tl_uf = std::numeric_limits<float>::max();
|
||||
float tl_vf = std::numeric_limits<float>::max();
|
||||
@@ -148,9 +139,9 @@ void WarperBase<P>::detectResultRoi(Point &dst_tl, Point &dst_br)
|
||||
float br_vf = -std::numeric_limits<float>::max();
|
||||
|
||||
float u, v;
|
||||
for (int y = 0; y < src_size_.height; ++y)
|
||||
for (int y = 0; y < src_size.height; ++y)
|
||||
{
|
||||
for (int x = 0; x < src_size_.width; ++x)
|
||||
for (int x = 0; x < src_size.width; ++x)
|
||||
{
|
||||
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
|
||||
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
|
||||
@@ -166,7 +157,7 @@ void WarperBase<P>::detectResultRoi(Point &dst_tl, Point &dst_br)
|
||||
|
||||
|
||||
template <class P>
|
||||
void WarperBase<P>::detectResultRoiByBorder(Point &dst_tl, Point &dst_br)
|
||||
void RotationWarperBase<P>::detectResultRoiByBorder(Size src_size, Point &dst_tl, Point &dst_br)
|
||||
{
|
||||
float tl_uf = std::numeric_limits<float>::max();
|
||||
float tl_vf = std::numeric_limits<float>::max();
|
||||
@@ -174,23 +165,23 @@ void WarperBase<P>::detectResultRoiByBorder(Point &dst_tl, Point &dst_br)
|
||||
float br_vf = -std::numeric_limits<float>::max();
|
||||
|
||||
float u, v;
|
||||
for (float x = 0; x < src_size_.width; ++x)
|
||||
for (float x = 0; x < src_size.width; ++x)
|
||||
{
|
||||
projector_.mapForward(static_cast<float>(x), 0, u, v);
|
||||
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
|
||||
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
|
||||
|
||||
projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size_.height - 1), u, v);
|
||||
projector_.mapForward(static_cast<float>(x), static_cast<float>(src_size.height - 1), u, v);
|
||||
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
|
||||
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
|
||||
}
|
||||
for (int y = 0; y < src_size_.height; ++y)
|
||||
for (int y = 0; y < src_size.height; ++y)
|
||||
{
|
||||
projector_.mapForward(0, static_cast<float>(y), u, v);
|
||||
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
|
||||
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
|
||||
|
||||
projector_.mapForward(static_cast<float>(src_size_.width - 1), static_cast<float>(y), u, v);
|
||||
projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(y), u, v);
|
||||
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
|
||||
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
|
||||
}
|
||||
|
@@ -51,28 +51,28 @@ class WarperCreator
|
||||
{
|
||||
public:
|
||||
virtual ~WarperCreator() {}
|
||||
virtual Ptr<detail::Warper> create(float scale) const = 0;
|
||||
virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
|
||||
};
|
||||
|
||||
|
||||
class PlaneWarper : public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::PlaneWarper(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PlaneWarper(scale); }
|
||||
};
|
||||
|
||||
|
||||
class CylindricalWarper: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::CylindricalWarper(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CylindricalWarper(scale); }
|
||||
};
|
||||
|
||||
|
||||
class SphericalWarper: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::SphericalWarper(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarper(scale); }
|
||||
};
|
||||
|
||||
|
||||
@@ -80,21 +80,21 @@ public:
|
||||
class PlaneWarperGpu: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::PlaneWarperGpu(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::PlaneWarperGpu(scale); }
|
||||
};
|
||||
|
||||
|
||||
class CylindricalWarperGpu: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::CylindricalWarperGpu(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::CylindricalWarperGpu(scale); }
|
||||
};
|
||||
|
||||
|
||||
class SphericalWarperGpu: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::Warper> create(float scale) const { return new detail::SphericalWarperGpu(scale); }
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return new detail::SphericalWarperGpu(scale); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
Reference in New Issue
Block a user