Commit b866890b authored by Vladislav Vinogradov's avatar Vladislav Vinogradov

switched to Input/Output Array in abs, sqr, sqrt, exp, log, pow

parent 5ec8c51b
...@@ -72,41 +72,35 @@ static inline void divide(double src1, InputArray src2, OutputArray dst, int dty ...@@ -72,41 +72,35 @@ static inline void divide(double src1, InputArray src2, OutputArray dst, int dty
//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2)) //! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
CV_EXPORTS void absdiff(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null()); CV_EXPORTS void absdiff(InputArray src1, InputArray src2, OutputArray dst, Stream& stream = Stream::Null());
//! computes the weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
CV_EXPORTS void addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, double beta, double gamma, GpuMat& dst,
int dtype = -1, Stream& stream = Stream::Null());
//! adds scaled array to another one (dst = alpha*src1 + src2)
static inline void scaleAdd(const GpuMat& src1, double alpha, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null())
{
addWeighted(src1, alpha, src2, 1.0, 0.0, dst, -1, stream);
}
//! computes absolute value of each matrix element //! computes absolute value of each matrix element
//! supports CV_16S and CV_32F depth CV_EXPORTS void abs(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void abs(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes square of each pixel in an image //! computes square of each pixel in an image
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth CV_EXPORTS void sqr(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void sqr(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes square root of each pixel in an image //! computes square root of each pixel in an image
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth CV_EXPORTS void sqrt(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void sqrt(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes exponent of each matrix element (b = e**a) //! computes exponent of each matrix element
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth CV_EXPORTS void exp(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void exp(const GpuMat& a, GpuMat& b, Stream& stream = Stream::Null());
//! computes natural logarithm of absolute value of each matrix element: b = log(abs(a)) //! computes natural logarithm of absolute value of each matrix element
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth CV_EXPORTS void log(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void log(const GpuMat& a, GpuMat& b, Stream& stream = Stream::Null());
//! computes power of each matrix element: //! computes power of each matrix element:
// (dst(i,j) = pow( src(i,j) , power), if src.type() is integer //! (dst(i,j) = pow( src(i,j) , power), if src.type() is integer
// (dst(i,j) = pow(fabs(src(i,j)), power), otherwise //! (dst(i,j) = pow(fabs(src(i,j)), power), otherwise
//! supports all, except depth == CV_64F CV_EXPORTS void pow(InputArray src, double power, OutputArray dst, Stream& stream = Stream::Null());
CV_EXPORTS void pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream = Stream::Null());
//! computes the weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
CV_EXPORTS void addWeighted(const GpuMat& src1, double alpha, const GpuMat& src2, double beta, double gamma, GpuMat& dst,
int dtype = -1, Stream& stream = Stream::Null());
//! adds scaled array to another one (dst = alpha*src1 + src2)
static inline void scaleAdd(const GpuMat& src1, double alpha, const GpuMat& src2, GpuMat& dst, Stream& stream = Stream::Null())
{
addWeighted(src1, alpha, src2, 1.0, 0.0, dst, -1, stream);
}
//! compares elements of two arrays (c = a <cmpop> b) //! compares elements of two arrays (c = a <cmpop> b)
CV_EXPORTS void compare(const GpuMat& a, const GpuMat& b, GpuMat& c, int cmpop, Stream& stream = Stream::Null()); CV_EXPORTS void compare(const GpuMat& a, const GpuMat& b, GpuMat& c, int cmpop, Stream& stream = Stream::Null());
......
...@@ -57,17 +57,17 @@ void cv::gpu::divide(InputArray, InputArray, OutputArray, double, int, Stream&) ...@@ -57,17 +57,17 @@ void cv::gpu::divide(InputArray, InputArray, OutputArray, double, int, Stream&)
void cv::gpu::absdiff(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); } void cv::gpu::absdiff(InputArray, InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::abs(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::abs(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::sqr(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::sqr(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::sqrt(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::sqrt(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::exp(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::exp(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::log(const GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::log(InputArray, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::pow(const GpuMat&, double, GpuMat&, Stream&) { throw_no_cuda(); } void cv::gpu::pow(InputArray, double, OutputArray, Stream&) { throw_no_cuda(); }
void cv::gpu::compare(const GpuMat&, const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); } void cv::gpu::compare(const GpuMat&, const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); }
void cv::gpu::compare(const GpuMat&, Scalar, GpuMat&, int, Stream&) { throw_no_cuda(); } void cv::gpu::compare(const GpuMat&, Scalar, GpuMat&, int, Stream&) { throw_no_cuda(); }
...@@ -1484,7 +1484,7 @@ namespace arithm ...@@ -1484,7 +1484,7 @@ namespace arithm
void absMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); void absMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
} }
void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) void cv::gpu::abs(InputArray _src, OutputArray _dst, Stream& stream)
{ {
using namespace arithm; using namespace arithm;
...@@ -1500,6 +1500,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1500,6 +1500,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream)
absMat<double> absMat<double>
}; };
GpuMat src = _src.getGpuMat();
const int depth = src.depth(); const int depth = src.depth();
CV_Assert( depth <= CV_64F ); CV_Assert( depth <= CV_64F );
...@@ -1511,7 +1513,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1511,7 +1513,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream)
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
} }
dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream)); funcs[depth](src, dst, StreamAccessor::getStream(stream));
} }
...@@ -1525,7 +1528,7 @@ namespace arithm ...@@ -1525,7 +1528,7 @@ namespace arithm
void sqrMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); void sqrMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
} }
void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) void cv::gpu::sqr(InputArray _src, OutputArray _dst, Stream& stream)
{ {
using namespace arithm; using namespace arithm;
...@@ -1541,6 +1544,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1541,6 +1544,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream)
sqrMat<double> sqrMat<double>
}; };
GpuMat src = _src.getGpuMat();
const int depth = src.depth(); const int depth = src.depth();
CV_Assert( depth <= CV_64F ); CV_Assert( depth <= CV_64F );
...@@ -1552,7 +1557,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1552,7 +1557,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream)
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
} }
dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream)); funcs[depth](src, dst, StreamAccessor::getStream(stream));
} }
...@@ -1566,7 +1572,7 @@ namespace arithm ...@@ -1566,7 +1572,7 @@ namespace arithm
void sqrtMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); void sqrtMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
} }
void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream) void cv::gpu::sqrt(InputArray _src, OutputArray _dst, Stream& stream)
{ {
using namespace arithm; using namespace arithm;
...@@ -1582,6 +1588,8 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1582,6 +1588,8 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream)
sqrtMat<double> sqrtMat<double>
}; };
GpuMat src = _src.getGpuMat();
const int depth = src.depth(); const int depth = src.depth();
CV_Assert( depth <= CV_64F ); CV_Assert( depth <= CV_64F );
...@@ -1593,7 +1601,52 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1593,7 +1601,52 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream)
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
} }
dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream));
}
////////////////////////////////////////////////////////////////////////
// exp
namespace arithm
{
template <typename T>
void expMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::exp(InputArray _src, OutputArray _dst, Stream& stream)
{
using namespace arithm;
typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
static const func_t funcs[] =
{
expMat<unsigned char>,
expMat<signed char>,
expMat<unsigned short>,
expMat<short>,
expMat<int>,
expMat<float>,
expMat<double>
};
GpuMat src = _src.getGpuMat();
const int depth = src.depth();
CV_Assert( depth <= CV_64F );
CV_Assert( src.channels() == 1 );
if (depth == CV_64F)
{
if (!deviceSupports(NATIVE_DOUBLE))
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
}
_dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream)); funcs[depth](src, dst, StreamAccessor::getStream(stream));
} }
...@@ -1607,7 +1660,7 @@ namespace arithm ...@@ -1607,7 +1660,7 @@ namespace arithm
void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream); void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
} }
void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream) void cv::gpu::log(InputArray _src, OutputArray _dst, Stream& stream)
{ {
using namespace arithm; using namespace arithm;
...@@ -1623,6 +1676,8 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1623,6 +1676,8 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream)
logMat<double> logMat<double>
}; };
GpuMat src = _src.getGpuMat();
const int depth = src.depth(); const int depth = src.depth();
CV_Assert( depth <= CV_64F ); CV_Assert( depth <= CV_64F );
...@@ -1634,40 +1689,40 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1634,40 +1689,40 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream)
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
} }
dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream)); funcs[depth](src, dst, StreamAccessor::getStream(stream));
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// exp // pow
namespace arithm namespace arithm
{ {
template <typename T> template<typename T> void pow(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream);
void expMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
} }
void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream) void cv::gpu::pow(InputArray _src, double power, OutputArray _dst, Stream& stream)
{ {
using namespace arithm; typedef void (*func_t)(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream);
typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
static const func_t funcs[] = static const func_t funcs[] =
{ {
expMat<unsigned char>, arithm::pow<unsigned char>,
expMat<signed char>, arithm::pow<signed char>,
expMat<unsigned short>, arithm::pow<unsigned short>,
expMat<short>, arithm::pow<short>,
expMat<int>, arithm::pow<int>,
expMat<float>, arithm::pow<float>,
expMat<double> arithm::pow<double>
}; };
GpuMat src = _src.getGpuMat();
const int depth = src.depth(); const int depth = src.depth();
const int cn = src.channels();
CV_Assert( depth <= CV_64F ); CV_Assert(depth <= CV_64F);
CV_Assert( src.channels() == 1 );
if (depth == CV_64F) if (depth == CV_64F)
{ {
...@@ -1675,9 +1730,13 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream) ...@@ -1675,9 +1730,13 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream)
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double"); CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
} }
dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream)); PtrStepSzb src_(src.rows, src.cols * cn, src.data, src.step);
PtrStepSzb dst_(src.rows, src.cols * cn, dst.data, dst.step);
funcs[depth](src_, power, dst_, StreamAccessor::getStream(stream));
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
...@@ -2562,47 +2621,6 @@ void cv::gpu::max(const GpuMat& src, double val, GpuMat& dst, Stream& stream) ...@@ -2562,47 +2621,6 @@ void cv::gpu::max(const GpuMat& src, double val, GpuMat& dst, Stream& stream)
funcs[depth](src, cast_func[depth](val), dst, StreamAccessor::getStream(stream)); funcs[depth](src, cast_func[depth](val), dst, StreamAccessor::getStream(stream));
} }
////////////////////////////////////////////////////////////////////////
// pow
namespace arithm
{
template<typename T> void pow(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream)
{
typedef void (*func_t)(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream);
static const func_t funcs[] =
{
arithm::pow<unsigned char>,
arithm::pow<signed char>,
arithm::pow<unsigned short>,
arithm::pow<short>,
arithm::pow<int>,
arithm::pow<float>,
arithm::pow<double>
};
const int depth = src.depth();
const int cn = src.channels();
CV_Assert(depth <= CV_64F);
if (depth == CV_64F)
{
if (!deviceSupports(NATIVE_DOUBLE))
CV_Error(cv::Error::StsUnsupportedFormat, "The device doesn't support double");
}
dst.create(src.size(), src.type());
PtrStepSzb src_(src.rows, src.cols * cn, src.data, src.step);
PtrStepSzb dst_(src.rows, src.cols * cn, dst.data, dst.step);
funcs[depth](src_, power, dst_, StreamAccessor::getStream(stream));
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// addWeighted // addWeighted
......
...@@ -1770,6 +1770,65 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Exp, testing::Combine( ...@@ -1770,6 +1770,65 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Exp, testing::Combine(
MatDepth(CV_32F)), MatDepth(CV_32F)),
WHOLE_SUBMAT)); WHOLE_SUBMAT));
////////////////////////////////////////////////////////////////////////////////
// Pow
PARAM_TEST_CASE(Pow, cv::gpu::DeviceInfo, cv::Size, MatDepth, UseRoi)
{
cv::gpu::DeviceInfo devInfo;
cv::Size size;
int depth;
bool useRoi;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
size = GET_PARAM(1);
depth = GET_PARAM(2);
useRoi = GET_PARAM(3);
cv::gpu::setDevice(devInfo.deviceID());
}
};
GPU_TEST_P(Pow, Accuracy)
{
cv::Mat src = randomMat(size, depth, 0.0, 10.0);
double power = randomDouble(2.0, 4.0);
if (src.depth() < CV_32F)
power = static_cast<int>(power);
if (depth == CV_64F && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE))
{
try
{
cv::gpu::GpuMat dst;
cv::gpu::pow(loadMat(src), power, dst);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code);
}
}
else
{
cv::gpu::GpuMat dst = createMat(size, depth, useRoi);
cv::gpu::pow(loadMat(src, useRoi), power, dst);
cv::Mat dst_gold;
cv::pow(src, power, dst_gold);
EXPECT_MAT_NEAR(dst_gold, dst, depth < CV_32F ? 0.0 : 1e-1);
}
}
INSTANTIATE_TEST_CASE_P(GPU_Arithm, Pow, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
ALL_DEPTH,
WHOLE_SUBMAT));
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Compare_Array // Compare_Array
...@@ -2402,65 +2461,6 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Max, testing::Combine( ...@@ -2402,65 +2461,6 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Max, testing::Combine(
ALL_DEPTH, ALL_DEPTH,
WHOLE_SUBMAT)); WHOLE_SUBMAT));
////////////////////////////////////////////////////////////////////////////////
// Pow
PARAM_TEST_CASE(Pow, cv::gpu::DeviceInfo, cv::Size, MatDepth, UseRoi)
{
cv::gpu::DeviceInfo devInfo;
cv::Size size;
int depth;
bool useRoi;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
size = GET_PARAM(1);
depth = GET_PARAM(2);
useRoi = GET_PARAM(3);
cv::gpu::setDevice(devInfo.deviceID());
}
};
GPU_TEST_P(Pow, Accuracy)
{
cv::Mat src = randomMat(size, depth, 0.0, 10.0);
double power = randomDouble(2.0, 4.0);
if (src.depth() < CV_32F)
power = static_cast<int>(power);
if (depth == CV_64F && !supportFeature(devInfo, cv::gpu::NATIVE_DOUBLE))
{
try
{
cv::gpu::GpuMat dst;
cv::gpu::pow(loadMat(src), power, dst);
}
catch (const cv::Exception& e)
{
ASSERT_EQ(cv::Error::StsUnsupportedFormat, e.code);
}
}
else
{
cv::gpu::GpuMat dst = createMat(size, depth, useRoi);
cv::gpu::pow(loadMat(src, useRoi), power, dst);
cv::Mat dst_gold;
cv::pow(src, power, dst_gold);
EXPECT_MAT_NEAR(dst_gold, dst, depth < CV_32F ? 0.0 : 1e-1);
}
}
INSTANTIATE_TEST_CASE_P(GPU_Arithm, Pow, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
ALL_DEPTH,
WHOLE_SUBMAT));
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// AddWeighted // AddWeighted
......
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