added OpenCL version of cv::patchNaNs

This commit is contained in:
Ilya Lavrenov 2013-12-30 01:21:04 +04:00
parent 6b64257c81
commit 3e1bec5248
3 changed files with 88 additions and 2 deletions

View File

@ -2364,12 +2364,31 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, double minVal, double ma
return badPt.x < 0;
}
static bool ocl_patchNaNs( InputOutputArray _a, float value )
{
ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D UNARY_OP -D OP_PATCH_NANS -D dstT=int"));
if (k.empty())
return false;
UMat a = _a.getUMat();
int cn = a.channels();
k.args(ocl::KernelArg::ReadOnlyNoSize(a),
ocl::KernelArg::WriteOnly(a), (float)value);
size_t globalsize[2] = { a.cols * cn, a.rows };
return k.run(2, globalsize, NULL, false);
}
void patchNaNs( InputOutputArray _a, double _val )
{
Mat a = _a.getMat();
CV_Assert( a.depth() == CV_32F );
CV_Assert( _a.depth() == CV_32F );
if (ocl::useOpenCL() && _a.isUMat() && _a.dims() <= 2 && ocl_patchNaNs(_a, (float)_val))
return;
Mat a = _a.getMat();
const Mat* arrays[] = {&a, 0};
int* ptrs[1];
NAryMatIterator it(arrays, (uchar**)ptrs);

View File

@ -271,6 +271,13 @@ dstelem = v > (dstT)(0) ? log(v) : log(-v)
dstelem = cos(alpha) * x; \
dstelem2 = sin(alpha) * x
#elif defined OP_PATCH_NANS
#undef EXTRA_PARAMS
#define EXTRA_PARAMS , int val
#define PROCESS_ELEM \
if (( srcelem1 & 0x7fffffff) > 0x7f800000 ) \
dstelem = val
#else
#error "unknown op type"
#endif

View File

@ -42,6 +42,8 @@
#include "test_precomp.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include <cmath>
#ifdef HAVE_OPENCL
namespace cvtest {
@ -1357,6 +1359,63 @@ OCL_TEST_P(ScaleAdd, Mat)
}
}
//////////////////////////////// PatchNans ////////////////////////////////////////////////
PARAM_TEST_CASE(PatchNaNs, Channels, bool)
{
int cn;
bool use_roi;
double value;
TEST_DECLARE_INPUT_PARAMETER(src)
virtual void SetUp()
{
cn = GET_PARAM(0);
use_roi = GET_PARAM(1);
}
virtual void generateTestData()
{
const int type = CV_MAKE_TYPE(CV_32F, cn);
Size roiSize = randomSize(1, 10);
Border srcBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src, src_roi, roiSize, srcBorder, type, -40, 40);
// generating NaNs
roiSize.width *= cn;
for (int y = 0; y < roiSize.height; ++y)
{
float * const ptr = src_roi.ptr<float>(y);
for (int x = 0; x < roiSize.width; ++x)
ptr[x] = randomInt(-1, 1) == 0 ? std::numeric_limits<float>::quiet_NaN() : ptr[x];
}
value = randomDouble(-100, 100);
UMAT_UPLOAD_INPUT_PARAMETER(src)
}
void Near()
{
OCL_EXPECT_MATS_NEAR(src, 0)
}
};
OCL_TEST_P(PatchNaNs, Mat)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
OCL_OFF(cv::patchNaNs(src_roi, value));
OCL_ON(cv::patchNaNs(usrc_roi, value));
Near();
}
}
//////////////////////////////////////// Instantiation /////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(Arithm, Lut, Combine(::testing::Values(CV_8U, CV_8S), OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
@ -1395,6 +1454,7 @@ OCL_INSTANTIATE_TEST_CASE_P(Arithm, Normalize, Combine(OCL_ALL_DEPTHS, Values(Ch
OCL_INSTANTIATE_TEST_CASE_P(Arithm, InRange, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Arithm, ConvertScaleAbs, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Arithm, ScaleAdd, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Arithm, PatchNaNs, Combine(OCL_ALL_CHANNELS, Bool()));
} } // namespace cvtest::ocl