Refactored warpers in the stitching module, added buildMaps function into the RotationWarper interface

pull/13383/head
Alexey Spizhevoy 13 years ago
parent b7a3d36729
commit 404e9cb9d5
  1. 94
      modules/stitching/include/opencv2/stitching/detail/warpers.hpp
  2. 81
      modules/stitching/include/opencv2/stitching/detail/warpers_inl.hpp
  3. 14
      modules/stitching/include/opencv2/stitching/warpers.hpp
  4. 10
      modules/stitching/src/stitcher.cpp
  5. 72
      modules/stitching/src/warpers.cpp
  6. 10
      samples/cpp/stitching_detailed.cpp

@ -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());
return Rect(dst_tl, dst_br);
}
template <class P>
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_tl;
return dst_roi.tl();
}
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)
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

@ -261,7 +261,7 @@ Stitcher::Status Stitcher::composePanorama(Mat &pano)
}
// Warp images and their masks
Ptr<detail::Warper> warper = warper_->create(float(warped_image_scale_ * seam_work_aspect_));
Ptr<detail::RotationWarper> warper = warper_->create(float(warped_image_scale_ * seam_work_aspect_));
for (size_t i = 0; i < imgs_.size(); ++i)
{
Mat_<float> K;
@ -271,10 +271,10 @@ Stitcher::Status Stitcher::composePanorama(Mat &pano)
K(1,1) *= (float)seam_work_aspect_;
K(1,2) *= (float)seam_work_aspect_;
corners[i] = warper->warp(seam_est_imgs_[i], K, cameras_[i].R, images_warped[i], INTER_LINEAR, BORDER_REFLECT);
corners[i] = warper->warp(seam_est_imgs_[i], K, cameras_[i].R, INTER_LINEAR, BORDER_REFLECT, images_warped[i]);
sizes[i] = images_warped[i].size();
warper->warp(masks[i], K, cameras_[i].R, masks_warped[i], INTER_NEAREST, BORDER_CONSTANT);
warper->warp(masks[i], K, cameras_[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
}
vector<Mat> images_warped_f(imgs_.size());
@ -361,12 +361,12 @@ Stitcher::Status Stitcher::composePanorama(Mat &pano)
cameras_[img_idx].K().convertTo(K, CV_32F);
// Warp the current image
warper->warp(img, K, cameras_[img_idx].R, img_warped, INTER_LINEAR, BORDER_REFLECT);
warper->warp(img, K, cameras_[img_idx].R, INTER_LINEAR, BORDER_REFLECT, img_warped);
// Warp the current image mask
mask.create(img_size, CV_8U);
mask.setTo(Scalar::all(255));
warper->warp(mask, K, cameras_[img_idx].R, mask_warped, INTER_NEAREST, BORDER_CONSTANT);
warper->warp(mask, K, cameras_[img_idx].R, INTER_NEAREST, BORDER_CONSTANT, mask_warped);
// Compensate exposure
exposure_comp_->apply(img_idx, corners[img_idx], img_warped, mask_warped);

@ -78,17 +78,15 @@ void ProjectorBase::setCameraParams(const Mat &K, const Mat &R, const Mat &T)
}
Point PlaneWarper::warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
int interp_mode, int border_mode)
Rect PlaneWarper::buildMaps(Size src_size, const Mat &K, const Mat &R, const Mat &T, Mat &xmap, Mat &ymap)
{
src_size_ = src.size();
projector_.setCameraParams(K, R, T);
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)
@ -101,26 +99,35 @@ Point PlaneWarper::warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T
}
}
dst.create(dst_br.y - dst_tl.y + 1, dst_br.x - dst_tl.x + 1, src.type());
return Rect(dst_tl, dst_br);
}
Point PlaneWarper::warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
Mat &dst)
{
Mat xmap, ymap;
Rect dst_roi = buildMaps(src.size(), K, R, T, 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_tl;
return dst_roi.tl();
}
Rect PlaneWarper::warpRoi(const Size &sz, const Mat &K, const Mat &R, const Mat &T)
Rect PlaneWarper::warpRoi(Size src_size, const Mat &K, const Mat &R, const Mat &T)
{
src_size_ = sz;
projector_.setCameraParams(K, R, T);
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));
}
void PlaneWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
void PlaneWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
float tl_uf = numeric_limits<float>::max();
float tl_vf = numeric_limits<float>::max();
@ -133,15 +140,15 @@ void PlaneWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
tl_uf = min(tl_uf, u); tl_vf = min(tl_vf, v);
br_uf = max(br_uf, u); br_vf = max(br_vf, v);
projector_.mapForward(0, static_cast<float>(src_size_.height - 1), u, v);
projector_.mapForward(0, static_cast<float>(src_size.height - 1), u, v);
tl_uf = min(tl_uf, u); tl_vf = min(tl_vf, v);
br_uf = max(br_uf, u); br_vf = max(br_vf, v);
projector_.mapForward(static_cast<float>(src_size_.width - 1), 0, u, v);
projector_.mapForward(static_cast<float>(src_size.width - 1), 0, u, v);
tl_uf = min(tl_uf, u); tl_vf = min(tl_vf, v);
br_uf = max(br_uf, u); br_vf = max(br_vf, v);
projector_.mapForward(static_cast<float>(src_size_.width - 1), static_cast<float>(src_size_.height - 1), u, v);
projector_.mapForward(static_cast<float>(src_size.width - 1), static_cast<float>(src_size.height - 1), u, v);
tl_uf = min(tl_uf, u); tl_vf = min(tl_vf, v);
br_uf = max(br_uf, u); br_vf = max(br_vf, v);
@ -153,21 +160,20 @@ void PlaneWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
#ifndef ANDROID
Point PlaneWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
int interp_mode, int border_mode)
Point PlaneWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
{
return warp(src, K, R, Mat::zeros(3, 1, CV_32F), dst, interp_mode, border_mode);
return warp(src, K, R, Mat::zeros(3, 1, CV_32F), interp_mode, border_mode, dst);
}
Point PlaneWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, Mat &dst,
int interp_mode, int border_mode)
Point PlaneWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, const Mat &T, int interp_mode, int border_mode,
Mat &dst)
{
src_size_ = src.size();
projector_.setCameraParams(K, R, T);
Point dst_tl, dst_br;
detectResultRoi(dst_tl, dst_br);
detectResultRoi(src.size(), dst_tl, dst_br);
gpu::buildWarpPlaneMaps(src.size(), Rect(dst_tl, Point(dst_br.x+1, dst_br.y+1)),
K, R, projector_.scale, d_xmap_, d_ymap_);
@ -186,9 +192,9 @@ Point PlaneWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, const Mat
#endif
void SphericalWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
void SphericalWarper::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
detectResultRoiByBorder(dst_tl, dst_br);
detectResultRoiByBorder(src_size, dst_tl, dst_br);
float tl_uf = static_cast<float>(dst_tl.x);
float tl_vf = static_cast<float>(dst_tl.y);
@ -202,7 +208,7 @@ void SphericalWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
{
float x_ = (projector_.k[0] * x + projector_.k[1] * y) / z + projector_.k[2];
float y_ = projector_.k[4] * y / z + projector_.k[5];
if (x_ > 0.f && x_ < src_size_.width && y_ > 0.f && y_ < src_size_.height)
if (x_ > 0.f && x_ < src_size.width && y_ > 0.f && y_ < src_size.height)
{
tl_uf = min(tl_uf, 0.f); tl_vf = min(tl_vf, static_cast<float>(CV_PI * projector_.scale));
br_uf = max(br_uf, 0.f); br_vf = max(br_vf, static_cast<float>(CV_PI * projector_.scale));
@ -216,7 +222,7 @@ void SphericalWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
{
float x_ = (projector_.k[0] * x + projector_.k[1] * y) / z + projector_.k[2];
float y_ = projector_.k[4] * y / z + projector_.k[5];
if (x_ > 0.f && x_ < src_size_.width && y_ > 0.f && y_ < src_size_.height)
if (x_ > 0.f && x_ < src_size.width && y_ > 0.f && y_ < src_size.height)
{
tl_uf = min(tl_uf, 0.f); tl_vf = min(tl_vf, static_cast<float>(0));
br_uf = max(br_uf, 0.f); br_vf = max(br_vf, static_cast<float>(0));
@ -231,14 +237,13 @@ void SphericalWarper::detectResultRoi(Point &dst_tl, Point &dst_br)
#ifndef ANDROID
Point SphericalWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
int interp_mode, int border_mode)
Point SphericalWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
{
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);
gpu::buildWarpSphericalMaps(src.size(), Rect(dst_tl, Point(dst_br.x+1, dst_br.y+1)),
K, R, projector_.scale, d_xmap_, d_ymap_);
@ -256,14 +261,13 @@ Point SphericalWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, Mat &
}
Point CylindricalWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, Mat &dst,
int interp_mode, int border_mode)
Point CylindricalWarperGpu::warp(const Mat &src, const Mat &K, const Mat &R, int interp_mode, int border_mode,
Mat &dst)
{
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);
gpu::buildWarpCylindricalMaps(src.size(), Rect(dst_tl, Point(dst_br.x+1, dst_br.y+1)),
K, R, projector_.scale, d_xmap_, d_ymap_);

@ -523,7 +523,7 @@ int main(int argc, char* argv[])
return 1;
}
Ptr<Warper> warper = warper_creator->create(static_cast<float>(warped_image_scale * seam_work_aspect));
Ptr<RotationWarper> warper = warper_creator->create(static_cast<float>(warped_image_scale * seam_work_aspect));
for (int i = 0; i < num_images; ++i)
{
@ -532,10 +532,10 @@ int main(int argc, char* argv[])
K(0,0) *= seam_work_aspect; K(0,2) *= seam_work_aspect;
K(1,1) *= seam_work_aspect; K(1,2) *= seam_work_aspect;
corners[i] = warper->warp(images[i], K, cameras[i].R, images_warped[i], INTER_LINEAR, BORDER_REFLECT);
corners[i] = warper->warp(images[i], K, cameras[i].R, INTER_LINEAR, BORDER_REFLECT, images_warped[i]);
sizes[i] = images_warped[i].size();
warper->warp(masks[i], K, cameras[i].R, masks_warped[i], INTER_NEAREST, BORDER_CONSTANT);
warper->warp(masks[i], K, cameras[i].R, INTER_NEAREST, BORDER_CONSTANT, masks_warped[i]);
}
vector<Mat> images_warped_f(num_images);
@ -647,12 +647,12 @@ int main(int argc, char* argv[])
cameras[img_idx].K().convertTo(K, CV_32F);
// Warp the current image
warper->warp(img, K, cameras[img_idx].R, img_warped, INTER_LINEAR, BORDER_REFLECT);
warper->warp(img, K, cameras[img_idx].R, INTER_LINEAR, BORDER_REFLECT, img_warped);
// Warp the current image mask
mask.create(img_size, CV_8U);
mask.setTo(Scalar::all(255));
warper->warp(mask, K, cameras[img_idx].R, mask_warped, INTER_NEAREST, BORDER_CONSTANT);
warper->warp(mask, K, cameras[img_idx].R, INTER_NEAREST, BORDER_CONSTANT, mask_warped);
// Compensate exposure
compensator->apply(img_idx, corners[img_idx], img_warped, mask_warped);

Loading…
Cancel
Save