Commit 404e9cb9 authored by Alexey Spizhevoy's avatar Alexey Spizhevoy

Refactored warpers in the stitching module, added buildMaps function into the…

Refactored warpers in the stitching module, added buildMaps function into the RotationWarper interface
parent b7a3d367
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment