TAPI: stitching: improve warpers
This commit is contained in:

committed by
Andrey Pavlenko

parent
89e3e448f5
commit
c1ea6f3c42
@@ -71,6 +71,7 @@
|
||||
#define LOG_(_level, _msg) \
|
||||
for(;;) \
|
||||
{ \
|
||||
using namespace std; \
|
||||
if ((_level) >= ::cv::detail::stitchingLogLevel()) \
|
||||
{ \
|
||||
LOG_STITCHING_MSG(_msg); \
|
||||
|
@@ -160,6 +160,8 @@ class CV_EXPORTS SphericalWarper : public RotationWarperBase<SphericalProjector>
|
||||
public:
|
||||
SphericalWarper(float scale) { projector_.scale = scale; }
|
||||
|
||||
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
|
||||
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
|
||||
protected:
|
||||
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br);
|
||||
};
|
||||
@@ -178,6 +180,8 @@ class CV_EXPORTS CylindricalWarper : public RotationWarperBase<CylindricalProjec
|
||||
public:
|
||||
CylindricalWarper(float scale) { projector_.scale = scale; }
|
||||
|
||||
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
|
||||
Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
|
||||
protected:
|
||||
void detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
|
||||
{
|
||||
@@ -503,45 +507,6 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////// OpenCL Accelerated Warpers /////////////////////////////////////
|
||||
|
||||
class CV_EXPORTS PlaneWarperOcl : public PlaneWarper
|
||||
{
|
||||
public:
|
||||
PlaneWarperOcl(float scale = 1.f) : PlaneWarper(scale) { }
|
||||
|
||||
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
return buildMaps(src_size, K, R, Mat::zeros(3, 1, CV_32FC1), xmap, ymap);
|
||||
}
|
||||
|
||||
virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
return warp(src, K, R, Mat::zeros(3, 1, CV_32FC1), interp_mode, border_mode, dst);
|
||||
}
|
||||
|
||||
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap);
|
||||
virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, OutputArray dst);
|
||||
};
|
||||
|
||||
class CV_EXPORTS SphericalWarperOcl : public SphericalWarper
|
||||
{
|
||||
public:
|
||||
SphericalWarperOcl(float scale) : SphericalWarper(scale) { }
|
||||
|
||||
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
|
||||
virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
|
||||
};
|
||||
|
||||
class CV_EXPORTS CylindricalWarperOcl : public CylindricalWarper
|
||||
{
|
||||
public:
|
||||
CylindricalWarperOcl(float scale) : CylindricalWarper(scale) { }
|
||||
|
||||
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
|
||||
virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
||||
|
@@ -92,7 +92,7 @@ template <class P>
|
||||
Point RotationWarperBase<P>::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
|
||||
OutputArray dst)
|
||||
{
|
||||
Mat xmap, ymap;
|
||||
UMat xmap, ymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, xmap, ymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
|
@@ -167,24 +167,6 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
class PlaneWarperOcl: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::PlaneWarperOcl>(scale); }
|
||||
};
|
||||
|
||||
class SphericalWarperOcl: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::SphericalWarperOcl>(scale); }
|
||||
};
|
||||
|
||||
class CylindricalWarperOcl: public WarperCreator
|
||||
{
|
||||
public:
|
||||
Ptr<detail::RotationWarper> create(float scale) const { return makePtr<detail::CylindricalWarperOcl>(scale); }
|
||||
};
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // __OPENCV_STITCHING_WARPER_CREATORS_HPP__
|
||||
|
@@ -63,24 +63,12 @@ public:
|
||||
explicit WarperBase(int type, Size srcSize)
|
||||
{
|
||||
Ptr<WarperCreator> creator;
|
||||
if (cv::ocl::useOpenCL())
|
||||
{
|
||||
if (type == SphericalWarperType)
|
||||
creator = makePtr<SphericalWarperOcl>();
|
||||
else if (type == CylindricalWarperType)
|
||||
creator = makePtr<CylindricalWarperOcl>();
|
||||
else if (type == PlaneWarperType)
|
||||
creator = makePtr<PlaneWarperOcl>();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == SphericalWarperType)
|
||||
creator = makePtr<SphericalWarper>();
|
||||
else if (type == CylindricalWarperType)
|
||||
creator = makePtr<CylindricalWarper>();
|
||||
else if (type == PlaneWarperType)
|
||||
creator = makePtr<PlaneWarper>();
|
||||
}
|
||||
CV_Assert(!creator.empty());
|
||||
|
||||
K = Mat::eye(3, 3, CV_32FC1);
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include <set>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
@@ -309,9 +309,7 @@ Stitcher::Status Stitcher::composePanorama(InputArrayOfArrays images, OutputArra
|
||||
|
||||
// Preliminary result is in CV_16SC3 format, but all values are in [0,255] range,
|
||||
// so convert it to avoid user confusing
|
||||
result.convertTo(pano_, CV_8U);
|
||||
|
||||
pano.assign(pano_);
|
||||
result.convertTo(pano, CV_8U);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -456,7 +454,7 @@ Stitcher::Status Stitcher::estimateCameraParams()
|
||||
Mat R;
|
||||
cameras_[i].R.convertTo(R, CV_32F);
|
||||
cameras_[i].R = R;
|
||||
LOGLN("Initial intrinsic parameters #" << indices_[i] + 1 << ":\n " << cameras_[i].K());
|
||||
//LOGLN("Initial intrinsic parameters #" << indices_[i] + 1 << ":\n " << cameras_[i].K());
|
||||
}
|
||||
|
||||
bundle_adjuster_->setConfThresh(conf_thresh_);
|
||||
@@ -467,7 +465,7 @@ Stitcher::Status Stitcher::estimateCameraParams()
|
||||
std::vector<double> focals;
|
||||
for (size_t i = 0; i < cameras_.size(); ++i)
|
||||
{
|
||||
LOGLN("Camera #" << indices_[i] + 1 << ":\n" << cameras_[i].K());
|
||||
//LOGLN("Camera #" << indices_[i] + 1 << ":\n" << cameras_[i].K());
|
||||
focals.push_back(cameras_[i].focal);
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
@@ -86,7 +87,6 @@ Point2f PlaneWarper::warpPoint(const Point2f &pt, InputArray K, InputArray R, In
|
||||
return uv;
|
||||
}
|
||||
|
||||
|
||||
Rect PlaneWarper::buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray _xmap, OutputArray _ymap)
|
||||
{
|
||||
projector_.setCameraParams(K, R, T);
|
||||
@@ -94,8 +94,29 @@ Rect PlaneWarper::buildMaps(Size src_size, InputArray K, InputArray R, InputArra
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
_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);
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
_xmap.create(dsize, CV_32FC1);
|
||||
_ymap.create(dsize, CV_32FC1);
|
||||
|
||||
if (ocl::useOpenCL()) // TODO !!!!! check T
|
||||
{
|
||||
ocl::Kernel k("buildWarpPlaneMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv), t(1, 3, CV_32FC1, projector_.t);
|
||||
UMat uxmap = _xmap.getUMat(), uymap = _ymap.getUMat(),
|
||||
uk_rinv = k_rinv.getUMat(ACCESS_READ), ut = t.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), ocl::KernelArg::PtrReadOnly(ut),
|
||||
dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
Mat xmap = _xmap.getMat(), ymap = _ymap.getMat();
|
||||
|
||||
@@ -117,11 +138,11 @@ Rect PlaneWarper::buildMaps(Size src_size, InputArray K, InputArray R, InputArra
|
||||
Point PlaneWarper::warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
|
||||
OutputArray dst)
|
||||
{
|
||||
Mat xmap, ymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, T, xmap, ymap);
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, T, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
remap(src, dst, xmap, ymap, interp_mode, border_mode);
|
||||
remap(src, dst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
@@ -341,5 +362,93 @@ void SphericalPortraitWarper::detectResultRoi(Size src_size, Point &dst_tl, Poin
|
||||
dst_br.y = static_cast<int>(br_vf);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////// SphericalWarper ////////////////////////////////////////
|
||||
|
||||
Rect SphericalWarper::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
if (ocl::useOpenCL())
|
||||
{
|
||||
ocl::Kernel k("buildWarpSphericalMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
xmap.create(dsize, CV_32FC1);
|
||||
ymap.create(dsize, CV_32FC1);
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv);
|
||||
UMat uxmap = xmap.getUMat(), uymap = ymap.getUMat(), uk_rinv = k_rinv.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
return RotationWarperBase<SphericalProjector>::buildMaps(src_size, K, R, xmap, ymap);
|
||||
}
|
||||
|
||||
Point SphericalWarper::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
remap(src, dst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////// CylindricalWarper ////////////////////////////////////////
|
||||
|
||||
Rect CylindricalWarper::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
if (ocl::useOpenCL())
|
||||
{
|
||||
ocl::Kernel k("buildWarpCylindricalMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
xmap.create(dsize, CV_32FC1);
|
||||
ymap.create(dsize, CV_32FC1);
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv);
|
||||
UMat uxmap = xmap.getUMat(), uymap = ymap.getUMat(), uk_rinv = k_rinv.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
return RotationWarperBase<CylindricalProjector>::buildMaps(src_size, K, R, xmap, ymap);
|
||||
}
|
||||
|
||||
Point CylindricalWarper::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
remap(src, dst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
||||
|
@@ -1,187 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace detail {
|
||||
|
||||
/////////////////////////////////////////// PlaneWarperOcl ////////////////////////////////////////////
|
||||
|
||||
Rect PlaneWarperOcl::buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
projector_.setCameraParams(K, R, T);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
if (ocl::useOpenCL())
|
||||
{
|
||||
ocl::Kernel k("buildWarpPlaneMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
xmap.create(dsize, CV_32FC1);
|
||||
ymap.create(dsize, CV_32FC1);
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv), t(1, 3, CV_32FC1, projector_.t);
|
||||
UMat uxmap = xmap.getUMat(), uymap = ymap.getUMat(),
|
||||
uk_rinv = k_rinv.getUMat(ACCESS_READ), ut = t.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), ocl::KernelArg::PtrReadOnly(ut),
|
||||
dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
return PlaneWarper::buildMaps(src_size, K, R, T, xmap, ymap);
|
||||
}
|
||||
|
||||
Point PlaneWarperOcl::warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, T, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
UMat udst = dst.getUMat();
|
||||
remap(src, udst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////// SphericalWarperOcl ////////////////////////////////////////
|
||||
|
||||
Rect SphericalWarperOcl::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
if (ocl::useOpenCL())
|
||||
{
|
||||
ocl::Kernel k("buildWarpSphericalMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
xmap.create(dsize, CV_32FC1);
|
||||
ymap.create(dsize, CV_32FC1);
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv);
|
||||
UMat uxmap = xmap.getUMat(), uymap = ymap.getUMat(), uk_rinv = k_rinv.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
return SphericalWarper::buildMaps(src_size, K, R, xmap, ymap);
|
||||
}
|
||||
|
||||
Point SphericalWarperOcl::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
UMat udst = dst.getUMat();
|
||||
remap(src, udst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////// CylindricalWarperOcl ////////////////////////////////////////
|
||||
|
||||
Rect CylindricalWarperOcl::buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap)
|
||||
{
|
||||
projector_.setCameraParams(K, R);
|
||||
|
||||
Point dst_tl, dst_br;
|
||||
detectResultRoi(src_size, dst_tl, dst_br);
|
||||
|
||||
if (ocl::useOpenCL())
|
||||
{
|
||||
ocl::Kernel k("buildWarpCylindricalMaps", ocl::stitching::warpers_oclsrc);
|
||||
if (!k.empty())
|
||||
{
|
||||
Size dsize(dst_br.x - dst_tl.x + 1, dst_br.y - dst_tl.y + 1);
|
||||
xmap.create(dsize, CV_32FC1);
|
||||
ymap.create(dsize, CV_32FC1);
|
||||
|
||||
Mat k_rinv(1, 9, CV_32FC1, projector_.k_rinv);
|
||||
UMat uxmap = xmap.getUMat(), uymap = ymap.getUMat(), uk_rinv = k_rinv.getUMat(ACCESS_READ);
|
||||
|
||||
k.args(ocl::KernelArg::WriteOnlyNoSize(uxmap), ocl::KernelArg::WriteOnly(uymap),
|
||||
ocl::KernelArg::PtrReadOnly(uk_rinv), dst_tl.x, dst_tl.y, projector_.scale);
|
||||
|
||||
size_t globalsize[2] = { dsize.width, dsize.height };
|
||||
if (k.run(2, globalsize, NULL, true))
|
||||
return Rect(dst_tl, dst_br);
|
||||
}
|
||||
}
|
||||
|
||||
return CylindricalWarper::buildMaps(src_size, K, R, xmap, ymap);
|
||||
}
|
||||
|
||||
Point CylindricalWarperOcl::warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode, OutputArray dst)
|
||||
{
|
||||
UMat uxmap, uymap;
|
||||
Rect dst_roi = buildMaps(src.size(), K, R, uxmap, uymap);
|
||||
|
||||
dst.create(dst_roi.height + 1, dst_roi.width + 1, src.type());
|
||||
UMat udst = dst.getUMat();
|
||||
remap(src, udst, uxmap, uymap, interp_mode, border_mode);
|
||||
|
||||
return dst_roi.tl();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace cv
|
@@ -48,13 +48,11 @@
|
||||
namespace cvtest {
|
||||
namespace ocl {
|
||||
|
||||
///////////////////////// WarperTestBase ///////////////////////////
|
||||
|
||||
struct WarperTestBase :
|
||||
public Test, public TestUtils
|
||||
{
|
||||
Mat src, dst, xmap, ymap;
|
||||
Mat udst, uxmap, uymap;
|
||||
UMat usrc, udst, uxmap, uymap;
|
||||
Mat K, R;
|
||||
|
||||
virtual void generateTestData()
|
||||
@@ -62,6 +60,7 @@ struct WarperTestBase :
|
||||
Size size = randomSize(1, MAX_VALUE);
|
||||
|
||||
src = randomMat(size, CV_32FC1, -500, 500);
|
||||
src.copyTo(usrc);
|
||||
|
||||
K = Mat::eye(3, 3, CV_32FC1);
|
||||
float angle = (float)(30.0 * CV_PI / 180.0);
|
||||
@@ -81,70 +80,64 @@ struct WarperTestBase :
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////// SphericalWarperOcl /////////////////////////////////////////////////
|
||||
typedef WarperTestBase SphericalWarperTest;
|
||||
|
||||
typedef WarperTestBase SphericalWarperOclTest;
|
||||
|
||||
OCL_TEST_F(SphericalWarperOclTest, Mat)
|
||||
OCL_TEST_F(SphericalWarperTest, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Ptr<WarperCreator> creator = makePtr<SphericalWarperOcl>();
|
||||
Ptr<WarperCreator> creator = makePtr<SphericalWarper>();
|
||||
Ptr<detail::RotationWarper> warper = creator->create(2.0);
|
||||
|
||||
OCL_OFF(warper->buildMaps(src.size(), K, R, xmap, ymap));
|
||||
OCL_ON(warper->buildMaps(src.size(), K, R, uxmap, uymap));
|
||||
OCL_ON(warper->buildMaps(usrc.size(), K, R, uxmap, uymap));
|
||||
|
||||
OCL_OFF(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, dst));
|
||||
OCL_ON(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
OCL_ON(warper->warp(usrc, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
|
||||
Near(1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// CylindricalWarperOcl /////////////////////////////////////////////////
|
||||
typedef WarperTestBase CylindricalWarperTest;
|
||||
|
||||
typedef WarperTestBase CylindricalWarperOclTest;
|
||||
|
||||
OCL_TEST_F(CylindricalWarperOclTest, Mat)
|
||||
OCL_TEST_F(CylindricalWarperTest, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Ptr<WarperCreator> creator = makePtr<CylindricalWarperOcl>();
|
||||
Ptr<WarperCreator> creator = makePtr<CylindricalWarper>();
|
||||
Ptr<detail::RotationWarper> warper = creator->create(2.0);
|
||||
|
||||
OCL_OFF(warper->buildMaps(src.size(), K, R, xmap, ymap));
|
||||
OCL_ON(warper->buildMaps(src.size(), K, R, uxmap, uymap));
|
||||
OCL_ON(warper->buildMaps(usrc.size(), K, R, uxmap, uymap));
|
||||
|
||||
OCL_OFF(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, dst));
|
||||
OCL_ON(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
OCL_ON(warper->warp(usrc, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
|
||||
Near(1e-4);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////// PlaneWarperOcl /////////////////////////////////////////////////
|
||||
typedef WarperTestBase PlaneWarperTest;
|
||||
|
||||
typedef WarperTestBase PlaneWarperOclTest;
|
||||
|
||||
OCL_TEST_F(PlaneWarperOclTest, Mat)
|
||||
OCL_TEST_F(PlaneWarperTest, Mat)
|
||||
{
|
||||
for (int j = 0; j < test_loop_times; j++)
|
||||
{
|
||||
generateTestData();
|
||||
|
||||
Ptr<WarperCreator> creator = makePtr<PlaneWarperOcl>();
|
||||
Ptr<WarperCreator> creator = makePtr<PlaneWarper>();
|
||||
Ptr<detail::RotationWarper> warper = creator->create(2.0);
|
||||
|
||||
OCL_OFF(warper->buildMaps(src.size(), K, R, xmap, ymap));
|
||||
OCL_ON(warper->buildMaps(src.size(), K, R, uxmap, uymap));
|
||||
OCL_ON(warper->buildMaps(usrc.size(), K, R, uxmap, uymap));
|
||||
|
||||
OCL_OFF(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, dst));
|
||||
OCL_ON(warper->warp(src, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
OCL_ON(warper->warp(usrc, K, R, INTER_LINEAR, BORDER_REPLICATE, udst));
|
||||
|
||||
Near(1e-4);
|
||||
}
|
||||
|
@@ -74,9 +74,6 @@ static void printUsage()
|
||||
" --try_cuda (yes|no)\n"
|
||||
" Try to use CUDA. The default value is 'no'. All default values\n"
|
||||
" are for CPU mode.\n"
|
||||
" --try_ocl (yes|no)\n"
|
||||
" Try to use OpenCL. The default value is 'no'. All default values\n"
|
||||
" are for CPU mode.\n"
|
||||
"\nMotion Estimation Flags:\n"
|
||||
" --work_megapix <float>\n"
|
||||
" Resolution for image registration step. The default is 0.6 Mpx.\n"
|
||||
@@ -127,7 +124,6 @@ static void printUsage()
|
||||
vector<String> img_names;
|
||||
bool preview = false;
|
||||
bool try_cuda = false;
|
||||
bool try_ocl = false;
|
||||
double work_megapix = 0.6;
|
||||
double seam_megapix = 0.1;
|
||||
double compose_megapix = -1;
|
||||
@@ -178,19 +174,6 @@ static int parseCmdArgs(int argc, char** argv)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--try_ocl")
|
||||
{
|
||||
if (string(argv[i + 1]) == "no")
|
||||
try_ocl = false;
|
||||
else if (string(argv[i + 1]) == "yes")
|
||||
try_ocl = true;
|
||||
else
|
||||
{
|
||||
cout << "Bad --try_ocl flag value\n";
|
||||
return -1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if (string(argv[i]) == "--work_megapix")
|
||||
{
|
||||
work_megapix = atof(argv[i + 1]);
|
||||
@@ -571,17 +554,8 @@ int main(int argc, char* argv[])
|
||||
// Warp images and their masks
|
||||
|
||||
Ptr<WarperCreator> warper_creator;
|
||||
if (try_ocl)
|
||||
{
|
||||
if (warp_type == "plane")
|
||||
warper_creator = makePtr<cv::PlaneWarperOcl>();
|
||||
else if (warp_type == "cylindrical")
|
||||
warper_creator = makePtr<cv::CylindricalWarperOcl>();
|
||||
else if (warp_type == "spherical")
|
||||
warper_creator = makePtr<cv::SphericalWarperOcl>();
|
||||
}
|
||||
#ifdef HAVE_OPENCV_CUDAWARPING
|
||||
else if (try_cuda && cuda::getCudaEnabledDeviceCount() > 0)
|
||||
if (try_cuda && cuda::getCudaEnabledDeviceCount() > 0)
|
||||
{
|
||||
if (warp_type == "plane")
|
||||
warper_creator = makePtr<cv::PlaneWarperGpu>();
|
||||
|
Reference in New Issue
Block a user