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

This commit is contained in:
Vladislav Vinogradov 2013-04-25 13:49:45 +04:00
parent 5ec8c51b98
commit b866890b27
3 changed files with 192 additions and 180 deletions

View File

@ -72,6 +72,26 @@ static inline void divide(double src1, InputArray src2, OutputArray dst, int dty
//! 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());
//! computes absolute value of each matrix element
CV_EXPORTS void abs(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
//! computes square of each pixel in an image
CV_EXPORTS void sqr(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
//! computes square root of each pixel in an image
CV_EXPORTS void sqrt(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
//! computes exponent of each matrix element
CV_EXPORTS void exp(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
//! computes natural logarithm of absolute value of each matrix element
CV_EXPORTS void log(InputArray src, OutputArray dst, Stream& stream = Stream::Null());
//! computes power of each matrix element:
//! (dst(i,j) = pow( src(i,j) , power), if src.type() is integer
//! (dst(i,j) = pow(fabs(src(i,j)), power), otherwise
CV_EXPORTS void pow(InputArray src, double power, 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());
@ -82,32 +102,6 @@ static inline void scaleAdd(const GpuMat& src1, double alpha, const GpuMat& src2
addWeighted(src1, alpha, src2, 1.0, 0.0, dst, -1, stream);
}
//! computes absolute value of each matrix element
//! supports CV_16S and CV_32F depth
CV_EXPORTS void abs(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes square of each pixel in an image
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth
CV_EXPORTS void sqr(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes square root of each pixel in an image
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth
CV_EXPORTS void sqrt(const GpuMat& src, GpuMat& dst, Stream& stream = Stream::Null());
//! computes exponent of each matrix element (b = e**a)
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth
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))
//! supports CV_8U, CV_16U, CV_16S and CV_32F depth
CV_EXPORTS void log(const GpuMat& a, GpuMat& b, Stream& stream = Stream::Null());
//! computes power of each matrix element:
// (dst(i,j) = pow( src(i,j) , power), if src.type() is integer
// (dst(i,j) = pow(fabs(src(i,j)), power), otherwise
//! supports all, except depth == CV_64F
CV_EXPORTS void pow(const GpuMat& src, double power, GpuMat& dst, Stream& stream = Stream::Null());
//! 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, Scalar sc, GpuMat& c, int cmpop, Stream& stream = Stream::Null());

View File

@ -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::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&, Scalar, GpuMat&, int, Stream&) { throw_no_cuda(); }
@ -1484,7 +1484,7 @@ namespace arithm
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;
@ -1500,6 +1500,8 @@ void cv::gpu::abs(const GpuMat& src, GpuMat& dst, Stream& stream)
absMat<double>
};
GpuMat src = _src.getGpuMat();
const int depth = src.depth();
CV_Assert( depth <= CV_64F );
@ -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");
}
dst.create(src.size(), src.type());
_dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream));
}
@ -1525,7 +1528,7 @@ namespace arithm
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;
@ -1541,6 +1544,8 @@ void cv::gpu::sqr(const GpuMat& src, GpuMat& dst, Stream& stream)
sqrMat<double>
};
GpuMat src = _src.getGpuMat();
const int depth = src.depth();
CV_Assert( depth <= CV_64F );
@ -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");
}
dst.create(src.size(), src.type());
_dst.create(src.size(), src.type());
GpuMat dst = _dst.getGpuMat();
funcs[depth](src, dst, StreamAccessor::getStream(stream));
}
@ -1566,7 +1572,7 @@ namespace arithm
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;
@ -1582,46 +1588,7 @@ void cv::gpu::sqrt(const GpuMat& src, GpuMat& dst, Stream& stream)
sqrtMat<double>
};
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());
funcs[depth](src, dst, StreamAccessor::getStream(stream));
}
////////////////////////////////////////////////////////////////////////
// log
namespace arithm
{
template <typename T>
void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream)
{
using namespace arithm;
typedef void (*func_t)(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
static const func_t funcs[] =
{
logMat<unsigned char>,
logMat<signed char>,
logMat<unsigned short>,
logMat<short>,
logMat<int>,
logMat<float>,
logMat<double>
};
GpuMat src = _src.getGpuMat();
const int depth = src.depth();
@ -1634,7 +1601,8 @@ void cv::gpu::log(const GpuMat& src, GpuMat& dst, Stream& stream)
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));
}
@ -1648,7 +1616,7 @@ namespace arithm
void expMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream)
void cv::gpu::exp(InputArray _src, OutputArray _dst, Stream& stream)
{
using namespace arithm;
@ -1664,6 +1632,8 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream)
expMat<double>
};
GpuMat src = _src.getGpuMat();
const int depth = src.depth();
CV_Assert( depth <= CV_64F );
@ -1675,11 +1645,100 @@ void cv::gpu::exp(const GpuMat& src, GpuMat& dst, Stream& stream)
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));
}
////////////////////////////////////////////////////////////////////////
// log
namespace arithm
{
template <typename T>
void logMat(PtrStepSzb src, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::log(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[] =
{
logMat<unsigned char>,
logMat<signed char>,
logMat<unsigned short>,
logMat<short>,
logMat<int>,
logMat<float>,
logMat<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));
}
////////////////////////////////////////////////////////////////////////
// pow
namespace arithm
{
template<typename T> void pow(PtrStepSzb src, double power, PtrStepSzb dst, cudaStream_t stream);
}
void cv::gpu::pow(InputArray _src, double power, OutputArray _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>
};
GpuMat src = _src.getGpuMat();
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());
GpuMat dst = _dst.getGpuMat();
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));
}
//////////////////////////////////////////////////////////////////////////////
// compare
@ -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));
}
////////////////////////////////////////////////////////////////////////
// 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

View File

@ -1770,6 +1770,65 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Exp, testing::Combine(
MatDepth(CV_32F)),
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
@ -2402,65 +2461,6 @@ INSTANTIATE_TEST_CASE_P(GPU_Arithm, Max, testing::Combine(
ALL_DEPTH,
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