mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge remote-tracking branch 'origin/master' into merge-2.4
This commit is contained in:
@@ -348,6 +348,10 @@ void cv::Canny( InputArray _src, OutputArray _dst,
|
||||
#define CANNY_PUSH(d) *(d) = uchar(2), *stack_top++ = (d)
|
||||
#define CANNY_POP(d) (d) = *--stack_top
|
||||
|
||||
#if CV_SSE2
|
||||
bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
|
||||
#endif
|
||||
|
||||
// calculate magnitude and angle of gradient, perform non-maxima suppression.
|
||||
// fill the map with one of the following values:
|
||||
// 0 - the pixel might belong to an edge
|
||||
@@ -363,12 +367,52 @@ void cv::Canny( InputArray _src, OutputArray _dst,
|
||||
|
||||
if (!L2gradient)
|
||||
{
|
||||
for (int j = 0; j < src.cols*cn; j++)
|
||||
int j = 0, width = src.cols * cn;
|
||||
#if CV_SSE2
|
||||
if (haveSSE2)
|
||||
{
|
||||
__m128i v_zero = _mm_setzero_si128();
|
||||
for ( ; j <= width - 8; j += 8)
|
||||
{
|
||||
__m128i v_dx = _mm_loadu_si128((const __m128i *)(_dx + j));
|
||||
__m128i v_dy = _mm_loadu_si128((const __m128i *)(_dy + j));
|
||||
v_dx = _mm_max_epi16(v_dx, _mm_sub_epi16(v_zero, v_dx));
|
||||
v_dy = _mm_max_epi16(v_dy, _mm_sub_epi16(v_zero, v_dy));
|
||||
|
||||
__m128i v_norm = _mm_add_epi32(_mm_unpacklo_epi16(v_dx, v_zero), _mm_unpacklo_epi16(v_dy, v_zero));
|
||||
_mm_storeu_si128((__m128i *)(_norm + j), v_norm);
|
||||
|
||||
v_norm = _mm_add_epi32(_mm_unpackhi_epi16(v_dx, v_zero), _mm_unpackhi_epi16(v_dy, v_zero));
|
||||
_mm_storeu_si128((__m128i *)(_norm + j + 4), v_norm);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for ( ; j < width; ++j)
|
||||
_norm[j] = std::abs(int(_dx[j])) + std::abs(int(_dy[j]));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < src.cols*cn; j++)
|
||||
int j = 0, width = src.cols * cn;
|
||||
#if CV_SSE2
|
||||
if (haveSSE2)
|
||||
{
|
||||
for ( ; j <= width - 8; j += 8)
|
||||
{
|
||||
__m128i v_dx = _mm_loadu_si128((const __m128i *)(_dx + j));
|
||||
__m128i v_dy = _mm_loadu_si128((const __m128i *)(_dy + j));
|
||||
|
||||
__m128i v_dx_ml = _mm_mullo_epi16(v_dx, v_dx), v_dx_mh = _mm_mulhi_epi16(v_dx, v_dx);
|
||||
__m128i v_dy_ml = _mm_mullo_epi16(v_dy, v_dy), v_dy_mh = _mm_mulhi_epi16(v_dy, v_dy);
|
||||
|
||||
__m128i v_norm = _mm_add_epi32(_mm_unpacklo_epi16(v_dx_ml, v_dx_mh), _mm_unpacklo_epi16(v_dy_ml, v_dy_mh));
|
||||
_mm_storeu_si128((__m128i *)(_norm + j), v_norm);
|
||||
|
||||
v_norm = _mm_add_epi32(_mm_unpackhi_epi16(v_dx_ml, v_dx_mh), _mm_unpackhi_epi16(v_dy_ml, v_dy_mh));
|
||||
_mm_storeu_si128((__m128i *)(_norm + j + 4), v_norm);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for ( ; j < width; ++j)
|
||||
_norm[j] = int(_dx[j])*_dx[j] + int(_dy[j])*_dy[j];
|
||||
}
|
||||
|
||||
|
||||
@@ -1704,8 +1704,10 @@ void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
|
||||
OutputArray _hierarchy, int mode, int method, Point offset )
|
||||
{
|
||||
// Sanity check: output must be of type vector<vector<Point>>
|
||||
CV_Assert( _contours.kind() == _InputArray::STD_VECTOR_VECTOR &&
|
||||
_contours.channels() == 2 && _contours.depth() == CV_32S );
|
||||
CV_Assert((_contours.kind() == _InputArray::STD_VECTOR_VECTOR || _contours.kind() == _InputArray::STD_VECTOR_MAT ||
|
||||
_contours.kind() == _InputArray::STD_VECTOR_UMAT));
|
||||
|
||||
CV_Assert(_contours.empty() || (_contours.channels() == 2 && _contours.depth() == CV_32S));
|
||||
|
||||
Mat image = _image.getMat();
|
||||
MemStorage storage(cvCreateMemStorage());
|
||||
|
||||
@@ -66,6 +66,11 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bayer2RGBA(const T*, int, T*, int, int) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bayer2RGB_EA(const T*, int, T*, int, int) const
|
||||
{
|
||||
return 0;
|
||||
@@ -218,6 +223,11 @@ public:
|
||||
return (int)(bayer - (bayer_end - width));
|
||||
}
|
||||
|
||||
int bayer2RGBA(const uchar*, int, uchar*, int, int) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bayer2RGB_EA(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
|
||||
{
|
||||
if (!use_simd)
|
||||
@@ -323,6 +333,165 @@ public:
|
||||
|
||||
bool use_simd;
|
||||
};
|
||||
#elif CV_NEON
|
||||
class SIMDBayerInterpolator_8u
|
||||
{
|
||||
public:
|
||||
SIMDBayerInterpolator_8u()
|
||||
{
|
||||
}
|
||||
|
||||
int bayer2Gray(const uchar* bayer, int bayer_step, uchar* dst,
|
||||
int width, int bcoeff, int gcoeff, int rcoeff) const
|
||||
{
|
||||
/*
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
G R G R | G R G R | G R G R | G R G R
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
*/
|
||||
|
||||
uint16x8_t masklo = vdupq_n_u16(255);
|
||||
const uchar* bayer_end = bayer + width;
|
||||
|
||||
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 )
|
||||
{
|
||||
uint16x8_t r0 = vld1q_u16((const ushort*)bayer);
|
||||
uint16x8_t r1 = vld1q_u16((const ushort*)(bayer + bayer_step));
|
||||
uint16x8_t r2 = vld1q_u16((const ushort*)(bayer + bayer_step*2));
|
||||
|
||||
uint16x8_t b1_ = vaddq_u16(vandq_u16(r0, masklo), vandq_u16(r2, masklo));
|
||||
uint16x8_t b1 = vextq_u16(b1_, b1_, 1);
|
||||
uint16x8_t b0 = vaddq_u16(b1_, b1);
|
||||
// b0 = b0 b2 b4 ...
|
||||
// b1 = b1 b3 b5 ...
|
||||
|
||||
uint16x8_t g0 = vaddq_u16(vshrq_n_u16(r0, 8), vshrq_n_u16(r2, 8));
|
||||
uint16x8_t g1 = vandq_u16(r1, masklo);
|
||||
g0 = vaddq_u16(g0, vaddq_u16(g1, vextq_u16(g1, g1, 1)));
|
||||
g1 = vshlq_n_u16(vextq_u16(g1, g1, 1), 2);
|
||||
// g0 = b0 b2 b4 ...
|
||||
// g1 = b1 b3 b5 ...
|
||||
|
||||
r0 = vshrq_n_u16(r1, 8);
|
||||
r1 = vaddq_u16(r0, vextq_u16(r0, r0, 1));
|
||||
r0 = vshlq_n_u16(r0, 2);
|
||||
// r0 = r0 r2 r4 ...
|
||||
// r1 = r1 r3 r5 ...
|
||||
|
||||
b0 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(b0), (short)(rcoeff*2)));
|
||||
b1 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(b1), (short)(rcoeff*4)));
|
||||
|
||||
g0 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(g0), (short)(gcoeff*2)));
|
||||
g1 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(g1), (short)(gcoeff*2)));
|
||||
|
||||
r0 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(r0), (short)(bcoeff*2)));
|
||||
r1 = vreinterpretq_u16_s16(vqdmulhq_n_s16(vreinterpretq_s16_u16(r1), (short)(bcoeff*4)));
|
||||
|
||||
g0 = vaddq_u16(vaddq_u16(g0, b0), r0);
|
||||
g1 = vaddq_u16(vaddq_u16(g1, b1), r1);
|
||||
|
||||
uint8x8x2_t p = vzip_u8(vrshrn_n_u16(g0, 2), vrshrn_n_u16(g1, 2));
|
||||
vst1_u8(dst, p.val[0]);
|
||||
vst1_u8(dst + 8, p.val[1]);
|
||||
}
|
||||
|
||||
return (int)(bayer - (bayer_end - width));
|
||||
}
|
||||
|
||||
int bayer2RGB(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
|
||||
{
|
||||
/*
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
G R G R | G R G R | G R G R | G R G R
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
*/
|
||||
uint16x8_t masklo = vdupq_n_u16(255);
|
||||
uint8x16x3_t pix;
|
||||
const uchar* bayer_end = bayer + width;
|
||||
|
||||
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 )
|
||||
{
|
||||
uint16x8_t r0 = vld1q_u16((const ushort*)bayer);
|
||||
uint16x8_t r1 = vld1q_u16((const ushort*)(bayer + bayer_step));
|
||||
uint16x8_t r2 = vld1q_u16((const ushort*)(bayer + bayer_step*2));
|
||||
|
||||
uint16x8_t b1 = vaddq_u16(vandq_u16(r0, masklo), vandq_u16(r2, masklo));
|
||||
uint16x8_t nextb1 = vextq_u16(b1, b1, 1);
|
||||
uint16x8_t b0 = vaddq_u16(b1, nextb1);
|
||||
// b0 b1 b2 ...
|
||||
uint8x8x2_t bb = vzip_u8(vrshrn_n_u16(b0, 2), vrshrn_n_u16(nextb1, 1));
|
||||
pix.val[1-blue] = vcombine_u8(bb.val[0], bb.val[1]);
|
||||
|
||||
uint16x8_t g0 = vaddq_u16(vshrq_n_u16(r0, 8), vshrq_n_u16(r2, 8));
|
||||
uint16x8_t g1 = vandq_u16(r1, masklo);
|
||||
g0 = vaddq_u16(g0, vaddq_u16(g1, vextq_u16(g1, g1, 1)));
|
||||
g1 = vextq_u16(g1, g1, 1);
|
||||
// g0 g1 g2 ...
|
||||
uint8x8x2_t gg = vzip_u8(vrshrn_n_u16(g0, 2), vmovn_u16(g1));
|
||||
pix.val[1] = vcombine_u8(gg.val[0], gg.val[1]);
|
||||
|
||||
r0 = vshrq_n_u16(r1, 8);
|
||||
r1 = vaddq_u16(r0, vextq_u16(r0, r0, 1));
|
||||
// r0 r1 r2 ...
|
||||
uint8x8x2_t rr = vzip_u8(vmovn_u16(r0), vrshrn_n_u16(r1, 1));
|
||||
pix.val[1+blue] = vcombine_u8(rr.val[0], rr.val[1]);
|
||||
|
||||
vst3q_u8(dst-1, pix);
|
||||
}
|
||||
|
||||
return (int)(bayer - (bayer_end - width));
|
||||
}
|
||||
|
||||
int bayer2RGBA(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const
|
||||
{
|
||||
/*
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
G R G R | G R G R | G R G R | G R G R
|
||||
B G B G | B G B G | B G B G | B G B G
|
||||
*/
|
||||
uint16x8_t masklo = vdupq_n_u16(255);
|
||||
uint8x16x4_t pix;
|
||||
const uchar* bayer_end = bayer + width;
|
||||
pix.val[3] = vdupq_n_u8(255);
|
||||
|
||||
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 56 )
|
||||
{
|
||||
uint16x8_t r0 = vld1q_u16((const ushort*)bayer);
|
||||
uint16x8_t r1 = vld1q_u16((const ushort*)(bayer + bayer_step));
|
||||
uint16x8_t r2 = vld1q_u16((const ushort*)(bayer + bayer_step*2));
|
||||
|
||||
uint16x8_t b1 = vaddq_u16(vandq_u16(r0, masklo), vandq_u16(r2, masklo));
|
||||
uint16x8_t nextb1 = vextq_u16(b1, b1, 1);
|
||||
uint16x8_t b0 = vaddq_u16(b1, nextb1);
|
||||
// b0 b1 b2 ...
|
||||
uint8x8x2_t bb = vzip_u8(vrshrn_n_u16(b0, 2), vrshrn_n_u16(nextb1, 1));
|
||||
pix.val[1-blue] = vcombine_u8(bb.val[0], bb.val[1]);
|
||||
|
||||
uint16x8_t g0 = vaddq_u16(vshrq_n_u16(r0, 8), vshrq_n_u16(r2, 8));
|
||||
uint16x8_t g1 = vandq_u16(r1, masklo);
|
||||
g0 = vaddq_u16(g0, vaddq_u16(g1, vextq_u16(g1, g1, 1)));
|
||||
g1 = vextq_u16(g1, g1, 1);
|
||||
// g0 g1 g2 ...
|
||||
uint8x8x2_t gg = vzip_u8(vrshrn_n_u16(g0, 2), vmovn_u16(g1));
|
||||
pix.val[1] = vcombine_u8(gg.val[0], gg.val[1]);
|
||||
|
||||
r0 = vshrq_n_u16(r1, 8);
|
||||
r1 = vaddq_u16(r0, vextq_u16(r0, r0, 1));
|
||||
// r0 r1 r2 ...
|
||||
uint8x8x2_t rr = vzip_u8(vmovn_u16(r0), vrshrn_n_u16(r1, 1));
|
||||
pix.val[1+blue] = vcombine_u8(rr.val[0], rr.val[1]);
|
||||
|
||||
vst4q_u8(dst-1, pix);
|
||||
}
|
||||
|
||||
return (int)(bayer - (bayer_end - width));
|
||||
}
|
||||
|
||||
int bayer2RGB_EA(const uchar*, int, uchar*, int, int) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef SIMDBayerStubInterpolator_<uchar> SIMDBayerInterpolator_8u;
|
||||
#endif
|
||||
@@ -559,7 +728,9 @@ public:
|
||||
}
|
||||
|
||||
// simd optimization only for dcn == 3
|
||||
int delta = dcn == 4 ? 0 : vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue);
|
||||
int delta = dcn == 4 ?
|
||||
vecOp.bayer2RGBA(bayer, bayer_step, dst, size.width, blue) :
|
||||
vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue);
|
||||
bayer += delta;
|
||||
dst += delta*dcn;
|
||||
|
||||
|
||||
@@ -702,7 +702,7 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
if ((ksize == 3 || ksize == 5) && ((borderType & BORDER_ISOLATED) != 0 || !_src.isSubmatrix()) &&
|
||||
((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)))
|
||||
((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)) && !ocl::useOpenCL())
|
||||
{
|
||||
int iscale = saturate_cast<int>(scale), idelta = saturate_cast<int>(delta);
|
||||
bool floatScale = std::fabs(scale - iscale) > DBL_EPSILON, needScale = iscale != 1;
|
||||
|
||||
@@ -2325,6 +2325,21 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
|
||||
s2 += b;
|
||||
}
|
||||
}
|
||||
else if( method == CV_COMP_KL_DIV )
|
||||
{
|
||||
for( j = 0; j < len; j++ )
|
||||
{
|
||||
double p = h1[j];
|
||||
double q = h2[j];
|
||||
if( fabs(p) <= DBL_EPSILON ) {
|
||||
continue;
|
||||
}
|
||||
if( fabs(q) <= DBL_EPSILON ) {
|
||||
q = 1e-10;
|
||||
}
|
||||
result += p * std::log( p / q );
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "Unknown comparison method" );
|
||||
}
|
||||
@@ -2360,7 +2375,7 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
|
||||
CV_Assert( H1.size(i) == H2.size(i) );
|
||||
|
||||
const SparseMat *PH1 = &H1, *PH2 = &H2;
|
||||
if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT)
|
||||
if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT && method != CV_COMP_KL_DIV )
|
||||
std::swap(PH1, PH2);
|
||||
|
||||
SparseMatConstIterator it = PH1->begin();
|
||||
@@ -2440,6 +2455,18 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
|
||||
s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.;
|
||||
result = std::sqrt(std::max(1. - result*s1, 0.));
|
||||
}
|
||||
else if( method == CV_COMP_KL_DIV )
|
||||
{
|
||||
for( i = 0; i < N1; i++, ++it )
|
||||
{
|
||||
double v1 = it.value<float>();
|
||||
const SparseMat::Node* node = it.node();
|
||||
double v2 = PH2->value<float>(node->idx, (size_t*)&node->hashval);
|
||||
if( !v2 )
|
||||
v2 = 1e-10;
|
||||
result += v1 * std::log( v1 / v2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "Unknown comparison method" );
|
||||
|
||||
@@ -2785,7 +2812,7 @@ cvCompareHist( const CvHistogram* hist1,
|
||||
CvSparseMatIterator iterator;
|
||||
CvSparseNode *node1, *node2;
|
||||
|
||||
if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT)
|
||||
if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT && method != CV_COMP_KL_DIV )
|
||||
{
|
||||
CvSparseMat* t;
|
||||
CV_SWAP( mat1, mat2, t );
|
||||
@@ -2887,6 +2914,13 @@ cvCompareHist( const CvHistogram* hist1,
|
||||
result = 1. - result*s1;
|
||||
result = sqrt(MAX(result,0.));
|
||||
}
|
||||
else if( method == CV_COMP_KL_DIV )
|
||||
{
|
||||
cv::SparseMat sH1, sH2;
|
||||
((const CvSparseMat*)hist1->bins)->copyToSparseMat(sH1);
|
||||
((const CvSparseMat*)hist2->bins)->copyToSparseMat(sH2);
|
||||
result = cv::compareHist( sH1, sH2, CV_COMP_KL_DIV );
|
||||
}
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "Unknown comparison method" );
|
||||
|
||||
|
||||
@@ -3582,7 +3582,9 @@ private:
|
||||
static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, InputArray _map2,
|
||||
int interpolation, int borderType, const Scalar& borderValue)
|
||||
{
|
||||
int cn = _src.channels(), type = _src.type(), depth = _src.depth();
|
||||
const ocl::Device & dev = ocl::Device::getDefault();
|
||||
int cn = _src.channels(), type = _src.type(), depth = _src.depth(),
|
||||
rowsPerWI = dev.isIntel() ? 4 : 1;
|
||||
|
||||
if (borderType == BORDER_TRANSPARENT || !(interpolation == INTER_LINEAR || interpolation == INTER_NEAREST)
|
||||
|| _map1.type() == CV_16SC1 || _map2.type() == CV_16SC1)
|
||||
@@ -3619,12 +3621,14 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
|
||||
static const char * const interMap[] = { "INTER_NEAREST", "INTER_LINEAR", "INTER_CUBIC", "INTER_LINEAR", "INTER_LANCZOS" };
|
||||
static const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", "BORDER_WRAP",
|
||||
"BORDER_REFLECT_101", "BORDER_TRANSPARENT" };
|
||||
String buildOptions = format("-D %s -D %s -D T=%s", interMap[interpolation], borderMap[borderType], ocl::typeToStr(type));
|
||||
String buildOptions = format("-D %s -D %s -D T=%s -D rowsPerWI=%d",
|
||||
interMap[interpolation], borderMap[borderType],
|
||||
ocl::typeToStr(type), rowsPerWI);
|
||||
|
||||
if (interpolation != INTER_NEAREST)
|
||||
{
|
||||
char cvt[3][40];
|
||||
int wdepth = std::max(CV_32F, dst.depth());
|
||||
int wdepth = std::max(CV_32F, depth);
|
||||
buildOptions = buildOptions
|
||||
+ format(" -D WT=%s -D convertToT=%s -D convertToWT=%s"
|
||||
" -D convertToWT2=%s -D WT2=%s",
|
||||
@@ -3636,10 +3640,9 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
|
||||
}
|
||||
int scalarcn = cn == 3 ? 4 : cn;
|
||||
int sctype = CV_MAKETYPE(depth, scalarcn);
|
||||
buildOptions += format(" -D T=%s -D T1=%s"
|
||||
" -D cn=%d -D ST=%s",
|
||||
buildOptions += format(" -D T=%s -D T1=%s -D cn=%d -D ST=%s -D depth=%d",
|
||||
ocl::typeToStr(type), ocl::typeToStr(depth),
|
||||
cn, ocl::typeToStr(sctype));
|
||||
cn, ocl::typeToStr(sctype), depth);
|
||||
|
||||
ocl::Kernel k(kernelName.c_str(), ocl::imgproc::remap_oclsrc, buildOptions);
|
||||
|
||||
@@ -3653,7 +3656,7 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
|
||||
else
|
||||
k.args(srcarg, dstarg, map1arg, ocl::KernelArg::ReadOnlyNoSize(map2), scalararg);
|
||||
|
||||
size_t globalThreads[2] = { dst.cols, dst.rows };
|
||||
size_t globalThreads[2] = { dst.cols, (dst.rows + rowsPerWI - 1) / rowsPerWI };
|
||||
return k.run(2, globalThreads, NULL, false);
|
||||
}
|
||||
|
||||
|
||||
+125
-80
@@ -202,6 +202,128 @@ static Moments contourMoments( const Mat& contour )
|
||||
* Spatial Raster Moments *
|
||||
\****************************************************************************************/
|
||||
|
||||
template<typename T, typename WT, typename MT>
|
||||
struct MomentsInTile_SSE
|
||||
{
|
||||
int operator() (const T *, int, WT &, WT &, WT &, MT &)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#if CV_SSE2
|
||||
|
||||
template <>
|
||||
struct MomentsInTile_SSE<uchar, int, int>
|
||||
{
|
||||
MomentsInTile_SSE()
|
||||
{
|
||||
useSIMD = checkHardwareSupport(CV_CPU_SSE2);
|
||||
}
|
||||
|
||||
int operator() (const uchar * ptr, int len, int & x0, int & x1, int & x2, int & x3)
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if( useSIMD )
|
||||
{
|
||||
__m128i qx_init = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
|
||||
__m128i dx = _mm_set1_epi16(8);
|
||||
__m128i z = _mm_setzero_si128(), qx0 = z, qx1 = z, qx2 = z, qx3 = z, qx = qx_init;
|
||||
|
||||
for( ; x <= len - 8; x += 8 )
|
||||
{
|
||||
__m128i p = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(ptr + x)), z);
|
||||
qx0 = _mm_add_epi32(qx0, _mm_sad_epu8(p, z));
|
||||
__m128i px = _mm_mullo_epi16(p, qx);
|
||||
__m128i sx = _mm_mullo_epi16(qx, qx);
|
||||
qx1 = _mm_add_epi32(qx1, _mm_madd_epi16(p, qx));
|
||||
qx2 = _mm_add_epi32(qx2, _mm_madd_epi16(p, sx));
|
||||
qx3 = _mm_add_epi32(qx3, _mm_madd_epi16(px, sx));
|
||||
|
||||
qx = _mm_add_epi16(qx, dx);
|
||||
}
|
||||
|
||||
int CV_DECL_ALIGNED(16) buf[4];
|
||||
_mm_store_si128((__m128i*)buf, qx0);
|
||||
x0 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx1);
|
||||
x1 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx2);
|
||||
x2 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx3);
|
||||
x3 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
bool useSIMD;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if CV_SSE4_1
|
||||
|
||||
template <>
|
||||
struct MomentsInTile_SSE<ushort, int, int64>
|
||||
{
|
||||
MomentsInTile_SSE()
|
||||
{
|
||||
useSIMD = checkHardwareSupport(CV_CPU_SSE4_1);
|
||||
}
|
||||
|
||||
int operator() (const ushort * ptr, int len, int & x0, int & x1, int & x2, int64 & x3)
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if (useSIMD)
|
||||
{
|
||||
__m128i vx_init0 = _mm_setr_epi32(0, 1, 2, 3), vx_init1 = _mm_setr_epi32(4, 5, 6, 7),
|
||||
v_delta = _mm_set1_epi32(8), v_zero = _mm_setzero_si128(), v_x0 = v_zero,
|
||||
v_x1 = v_zero, v_x2 = v_zero, v_x3 = v_zero, v_ix0 = vx_init0, v_ix1 = vx_init1;
|
||||
|
||||
for( ; x <= len - 8; x += 8 )
|
||||
{
|
||||
__m128i v_src = _mm_loadu_si128((const __m128i *)(ptr + x));
|
||||
__m128i v_src0 = _mm_unpacklo_epi16(v_src, v_zero), v_src1 = _mm_unpackhi_epi16(v_src, v_zero);
|
||||
|
||||
v_x0 = _mm_add_epi32(v_x0, _mm_add_epi32(v_src0, v_src1));
|
||||
__m128i v_x1_0 = _mm_mullo_epi32(v_src0, v_ix0), v_x1_1 = _mm_mullo_epi32(v_src1, v_ix1);
|
||||
v_x1 = _mm_add_epi32(v_x1, _mm_add_epi32(v_x1_0, v_x1_1));
|
||||
|
||||
__m128i v_2ix0 = _mm_mullo_epi32(v_ix0, v_ix0), v_2ix1 = _mm_mullo_epi32(v_ix1, v_ix1);
|
||||
v_x2 = _mm_add_epi32(v_x2, _mm_add_epi32(_mm_mullo_epi32(v_2ix0, v_src0), _mm_mullo_epi32(v_2ix1, v_src1)));
|
||||
|
||||
__m128i t = _mm_add_epi32(_mm_mullo_epi32(v_2ix0, v_x1_0), _mm_mullo_epi32(v_2ix1, v_x1_1));
|
||||
v_x3 = _mm_add_epi64(v_x3, _mm_add_epi64(_mm_unpacklo_epi32(t, v_zero), _mm_unpackhi_epi32(t, v_zero)));
|
||||
|
||||
v_ix0 = _mm_add_epi32(v_ix0, v_delta);
|
||||
v_ix1 = _mm_add_epi32(v_ix1, v_delta);
|
||||
}
|
||||
|
||||
int CV_DECL_ALIGNED(16) buf[4];
|
||||
int64 CV_DECL_ALIGNED(16) buf64[2];
|
||||
|
||||
_mm_store_si128((__m128i*)buf, v_x0);
|
||||
x0 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, v_x1);
|
||||
x1 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, v_x2);
|
||||
x2 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
|
||||
_mm_store_si128((__m128i*)buf64, v_x3);
|
||||
x3 = buf64[0] + buf64[1];
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
bool useSIMD;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T, typename WT, typename MT>
|
||||
#if defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 9
|
||||
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60196
|
||||
@@ -212,14 +334,16 @@ static void momentsInTile( const Mat& img, double* moments )
|
||||
Size size = img.size();
|
||||
int x, y;
|
||||
MT mom[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||
MomentsInTile_SSE<T, WT, MT> vop;
|
||||
|
||||
for( y = 0; y < size.height; y++ )
|
||||
{
|
||||
const T* ptr = (const T*)(img.data + y*img.step);
|
||||
WT x0 = 0, x1 = 0, x2 = 0;
|
||||
MT x3 = 0;
|
||||
x = vop(ptr, size.width, x0, x1, x2, x3);
|
||||
|
||||
for( x = 0; x < size.width; x++ )
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
WT p = ptr[x];
|
||||
WT xp = x * p, xxp;
|
||||
@@ -249,85 +373,6 @@ static void momentsInTile( const Mat& img, double* moments )
|
||||
moments[x] = (double)mom[x];
|
||||
}
|
||||
|
||||
|
||||
#if CV_SSE2
|
||||
|
||||
template<> void momentsInTile<uchar, int, int>( const cv::Mat& img, double* moments )
|
||||
{
|
||||
typedef uchar T;
|
||||
typedef int WT;
|
||||
typedef int MT;
|
||||
Size size = img.size();
|
||||
int y;
|
||||
MT mom[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||
bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);
|
||||
|
||||
for( y = 0; y < size.height; y++ )
|
||||
{
|
||||
const T* ptr = img.ptr<T>(y);
|
||||
int x0 = 0, x1 = 0, x2 = 0, x3 = 0, x = 0;
|
||||
|
||||
if( useSIMD )
|
||||
{
|
||||
__m128i qx_init = _mm_setr_epi16(0, 1, 2, 3, 4, 5, 6, 7);
|
||||
__m128i dx = _mm_set1_epi16(8);
|
||||
__m128i z = _mm_setzero_si128(), qx0 = z, qx1 = z, qx2 = z, qx3 = z, qx = qx_init;
|
||||
|
||||
for( ; x <= size.width - 8; x += 8 )
|
||||
{
|
||||
__m128i p = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(ptr + x)), z);
|
||||
qx0 = _mm_add_epi32(qx0, _mm_sad_epu8(p, z));
|
||||
__m128i px = _mm_mullo_epi16(p, qx);
|
||||
__m128i sx = _mm_mullo_epi16(qx, qx);
|
||||
qx1 = _mm_add_epi32(qx1, _mm_madd_epi16(p, qx));
|
||||
qx2 = _mm_add_epi32(qx2, _mm_madd_epi16(p, sx));
|
||||
qx3 = _mm_add_epi32(qx3, _mm_madd_epi16(px, sx));
|
||||
|
||||
qx = _mm_add_epi16(qx, dx);
|
||||
}
|
||||
int CV_DECL_ALIGNED(16) buf[4];
|
||||
_mm_store_si128((__m128i*)buf, qx0);
|
||||
x0 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx1);
|
||||
x1 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx2);
|
||||
x2 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
_mm_store_si128((__m128i*)buf, qx3);
|
||||
x3 = buf[0] + buf[1] + buf[2] + buf[3];
|
||||
}
|
||||
|
||||
for( ; x < size.width; x++ )
|
||||
{
|
||||
WT p = ptr[x];
|
||||
WT xp = x * p, xxp;
|
||||
|
||||
x0 += p;
|
||||
x1 += xp;
|
||||
xxp = xp * x;
|
||||
x2 += xxp;
|
||||
x3 += xxp * x;
|
||||
}
|
||||
|
||||
WT py = y * x0, sy = y*y;
|
||||
|
||||
mom[9] += ((MT)py) * sy; // m03
|
||||
mom[8] += ((MT)x1) * sy; // m12
|
||||
mom[7] += ((MT)x2) * y; // m21
|
||||
mom[6] += x3; // m30
|
||||
mom[5] += x0 * sy; // m02
|
||||
mom[4] += x1 * y; // m11
|
||||
mom[3] += x2; // m20
|
||||
mom[2] += py; // m01
|
||||
mom[1] += x1; // m10
|
||||
mom[0] += x0; // m00
|
||||
}
|
||||
|
||||
for(int x = 0; x < 10; x++ )
|
||||
moments[x] = (double)mom[x];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef void (*MomentsInTileFunc)(const Mat& img, double* moments);
|
||||
|
||||
Moments::Moments()
|
||||
|
||||
@@ -1257,7 +1257,7 @@ static bool IPPMorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kerne
|
||||
}
|
||||
#undef IPP_MORPH_CASE
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 8
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 8
|
||||
return false; /// It disables false positive warning in GCC 4.8 and further
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -114,25 +114,23 @@ __kernel void corner(__global const float * Dx, int dx_step, int dx_offset, int
|
||||
int dst_startX = gX * (THREADS-ksX+1) + dst_x_off;
|
||||
int dst_startY = (gY << 1) + dst_y_off;
|
||||
|
||||
float dx_data[ksY+1],dy_data[ksY+1], data[3][ksY+1];
|
||||
float data[3][ksY+1];
|
||||
__local float temp[6][THREADS];
|
||||
|
||||
#ifdef BORDER_CONSTANT
|
||||
for (int i=0; i < ksY+1; i++)
|
||||
{
|
||||
bool dx_con = dx_startX+col >= 0 && dx_startX+col < dx_whole_cols && dx_startY+i >= 0 && dx_startY+i < dx_whole_rows;
|
||||
int indexDx = (dx_startY+i)*(dx_step>>2)+(dx_startX+col);
|
||||
int indexDx = mad24(dx_startY+i, dx_step>>2, dx_startX+col);
|
||||
float dx_s = dx_con ? Dx[indexDx] : 0.0f;
|
||||
dx_data[i] = dx_s;
|
||||
|
||||
bool dy_con = dy_startX+col >= 0 && dy_startX+col < dy_whole_cols && dy_startY+i >= 0 && dy_startY+i < dy_whole_rows;
|
||||
int indexDy = (dy_startY+i)*(dy_step>>2)+(dy_startX+col);
|
||||
int indexDy = mad24(dy_startY+i, dy_step>>2, dy_startX+col);
|
||||
float dy_s = dy_con ? Dy[indexDy] : 0.0f;
|
||||
dy_data[i] = dy_s;
|
||||
|
||||
data[0][i] = dx_data[i] * dx_data[i];
|
||||
data[1][i] = dx_data[i] * dy_data[i];
|
||||
data[2][i] = dy_data[i] * dy_data[i];
|
||||
data[0][i] = dx_s * dx_s;
|
||||
data[1][i] = dx_s * dy_s;
|
||||
data[2][i] = dy_s * dy_s;
|
||||
}
|
||||
#else
|
||||
int clamped_col = min(2*dst_cols, col);
|
||||
@@ -141,16 +139,16 @@ __kernel void corner(__global const float * Dx, int dx_step, int dx_offset, int
|
||||
int dx_selected_row = dx_startY+i, dx_selected_col = dx_startX+clamped_col;
|
||||
EXTRAPOLATE(dx_selected_row, dx_whole_rows)
|
||||
EXTRAPOLATE(dx_selected_col, dx_whole_cols)
|
||||
dx_data[i] = Dx[dx_selected_row * (dx_step>>2) + dx_selected_col];
|
||||
float dx_s = Dx[mad24(dx_selected_row, dx_step>>2, dx_selected_col)];
|
||||
|
||||
int dy_selected_row = dy_startY+i, dy_selected_col = dy_startX+clamped_col;
|
||||
EXTRAPOLATE(dy_selected_row, dy_whole_rows)
|
||||
EXTRAPOLATE(dy_selected_col, dy_whole_cols)
|
||||
dy_data[i] = Dy[dy_selected_row * (dy_step>>2) + dy_selected_col];
|
||||
float dy_s = Dy[mad24(dy_selected_row, dy_step>>2, dy_selected_col)];
|
||||
|
||||
data[0][i] = dx_data[i] * dx_data[i];
|
||||
data[1][i] = dx_data[i] * dy_data[i];
|
||||
data[2][i] = dy_data[i] * dy_data[i];
|
||||
data[0][i] = dx_s * dx_s;
|
||||
data[1][i] = dx_s * dy_s;
|
||||
data[2][i] = dy_s * dy_s;
|
||||
}
|
||||
#endif
|
||||
float sum0 = 0.0f, sum1 = 0.0f, sum2 = 0.0f;
|
||||
@@ -180,7 +178,7 @@ __kernel void corner(__global const float * Dx, int dx_step, int dx_offset, int
|
||||
col += anX;
|
||||
int posX = dst_startX - dst_x_off + col - anX;
|
||||
int posY = (gly << 1);
|
||||
int till = (ksX + 1)%2;
|
||||
int till = (ksX + 1) & 1;
|
||||
float tmp_sum[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
for (int k=0; k<6; k++)
|
||||
{
|
||||
@@ -210,7 +208,7 @@ __kernel void corner(__global const float * Dx, int dx_step, int dx_offset, int
|
||||
float a = tmp_sum[0] * 0.5f;
|
||||
float b = tmp_sum[2];
|
||||
float c = tmp_sum[4] * 0.5f;
|
||||
*(__global float *)(dst + dst_index) = (float)((a+c) - sqrt((a-c)*(a-c) + b*b));
|
||||
*(__global float *)(dst + dst_index) = (float)((a+c) - native_sqrt((a-c)*(a-c) + b*b));
|
||||
}
|
||||
if (posX < dst_cols && (posY + 1) < dst_rows)
|
||||
{
|
||||
@@ -218,7 +216,7 @@ __kernel void corner(__global const float * Dx, int dx_step, int dx_offset, int
|
||||
float a = tmp_sum[1] * 0.5f;
|
||||
float b = tmp_sum[3];
|
||||
float c = tmp_sum[5] * 0.5f;
|
||||
*(__global float *)(dst + dst_index) = (float)((a+c) - sqrt((a-c)*(a-c) + b*b));
|
||||
*(__global float *)(dst + dst_index) = (float)((a+c) - native_sqrt((a-c)*(a-c) + b*b));
|
||||
}
|
||||
#else
|
||||
#error "No such corners type"
|
||||
|
||||
@@ -79,116 +79,207 @@
|
||||
|
||||
#define SRC(_x,_y) convertToFT(loadpix(srcData + mad24(_y, src_step, PIXSIZE * _x)))
|
||||
|
||||
#if kercn == 4
|
||||
#define SRC4(_x,_y) convert_float4(vload4(0, srcData + mad24(_y, src_step, PIXSIZE * _x)))
|
||||
#endif
|
||||
|
||||
#ifdef INTEL_DEVICE
|
||||
#define MAD(x,y,z) fma((x),(y),(z))
|
||||
#else
|
||||
#define MAD(x,y,z) mad((x),(y),(z))
|
||||
#endif
|
||||
|
||||
#define LOAD_LOCAL(col_gl, col_lcl) \
|
||||
sum0 = co3* SRC(col_gl, EXTRAPOLATE_(src_y - 2, src_rows)); \
|
||||
sum0 = MAD(co2, SRC(col_gl, EXTRAPOLATE_(src_y - 1, src_rows)), sum0); \
|
||||
temp = SRC(col_gl, EXTRAPOLATE_(src_y, src_rows)); \
|
||||
sum0 = MAD(co1, temp, sum0); \
|
||||
sum1 = co3 * temp; \
|
||||
temp = SRC(col_gl, EXTRAPOLATE_(src_y + 1, src_rows)); \
|
||||
sum0 = MAD(co2, temp, sum0); \
|
||||
sum1 = MAD(co2, temp, sum1); \
|
||||
temp = SRC(col_gl, EXTRAPOLATE_(src_y + 2, src_rows)); \
|
||||
sum0 = MAD(co3, temp, sum0); \
|
||||
sum1 = MAD(co1, temp, sum1); \
|
||||
smem[0][col_lcl] = sum0; \
|
||||
sum1 = MAD(co2, SRC(col_gl, EXTRAPOLATE_(src_y + 3, src_rows)), sum1); \
|
||||
sum1 = MAD(co3, SRC(col_gl, EXTRAPOLATE_(src_y + 4, src_rows)), sum1); \
|
||||
smem[1][col_lcl] = sum1;
|
||||
|
||||
|
||||
#if kercn == 4
|
||||
#define LOAD_LOCAL4(col_gl, col_lcl) \
|
||||
sum40 = co3* SRC4(col_gl, EXTRAPOLATE_(src_y - 2, src_rows)); \
|
||||
sum40 = MAD(co2, SRC4(col_gl, EXTRAPOLATE_(src_y - 1, src_rows)), sum40); \
|
||||
temp4 = SRC4(col_gl, EXTRAPOLATE_(src_y, src_rows)); \
|
||||
sum40 = MAD(co1, temp4, sum40); \
|
||||
sum41 = co3 * temp4; \
|
||||
temp4 = SRC4(col_gl, EXTRAPOLATE_(src_y + 1, src_rows)); \
|
||||
sum40 = MAD(co2, temp4, sum40); \
|
||||
sum41 = MAD(co2, temp4, sum41); \
|
||||
temp4 = SRC4(col_gl, EXTRAPOLATE_(src_y + 2, src_rows)); \
|
||||
sum40 = MAD(co3, temp4, sum40); \
|
||||
sum41 = MAD(co1, temp4, sum41); \
|
||||
vstore4(sum40, col_lcl, (__local float*) &smem[0][2]); \
|
||||
sum41 = MAD(co2, SRC4(col_gl, EXTRAPOLATE_(src_y + 3, src_rows)), sum41); \
|
||||
sum41 = MAD(co3, SRC4(col_gl, EXTRAPOLATE_(src_y + 4, src_rows)), sum41); \
|
||||
vstore4(sum41, col_lcl, (__local float*) &smem[1][2]);
|
||||
#endif
|
||||
|
||||
#define noconvert
|
||||
|
||||
__kernel void pyrDown(__global const uchar * src, int src_step, int src_offset, int src_rows, int src_cols,
|
||||
__global uchar * dst, int dst_step, int dst_offset, int dst_rows, int dst_cols)
|
||||
{
|
||||
const int x = get_global_id(0);
|
||||
const int y = get_group_id(1);
|
||||
const int x = get_global_id(0)*kercn;
|
||||
const int y = 2*get_global_id(1);
|
||||
|
||||
__local FT smem[LOCAL_SIZE + 4];
|
||||
__local FT smem[2][LOCAL_SIZE + 4];
|
||||
__global uchar * dstData = dst + dst_offset;
|
||||
__global const uchar * srcData = src + src_offset;
|
||||
|
||||
FT sum;
|
||||
FT sum0, sum1, temp;
|
||||
FT co1 = 0.375f;
|
||||
FT co2 = 0.25f;
|
||||
FT co3 = 0.0625f;
|
||||
|
||||
const int src_y = 2*y;
|
||||
int col;
|
||||
|
||||
if (src_y >= 2 && src_y < src_rows - 2 && x >= 2 && x < src_cols - 2)
|
||||
if (src_y >= 2 && src_y < src_rows - 4)
|
||||
{
|
||||
sum = co3 * SRC(x, src_y - 2);
|
||||
sum = sum + co2 * SRC(x, src_y - 1);
|
||||
sum = sum + co1 * SRC(x, src_y );
|
||||
sum = sum + co2 * SRC(x, src_y + 1);
|
||||
sum = sum + co3 * SRC(x, src_y + 2);
|
||||
|
||||
smem[2 + get_local_id(0)] = sum;
|
||||
|
||||
#define EXTRAPOLATE_(val, maxVal) val
|
||||
#if kercn == 1
|
||||
col = EXTRAPOLATE(x, src_cols);
|
||||
LOAD_LOCAL(col, 2 + get_local_id(0))
|
||||
#else
|
||||
if (x < src_cols-4)
|
||||
{
|
||||
float4 sum40, sum41, temp4;
|
||||
LOAD_LOCAL4(x, get_local_id(0))
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
col = EXTRAPOLATE(x+i, src_cols);
|
||||
LOAD_LOCAL(col, 2 + 4 * get_local_id(0) + i)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (get_local_id(0) < 2)
|
||||
{
|
||||
const int left_x = x - 2;
|
||||
|
||||
sum = co3 * SRC(left_x, src_y - 2);
|
||||
sum = sum + co2 * SRC(left_x, src_y - 1);
|
||||
sum = sum + co1 * SRC(left_x, src_y );
|
||||
sum = sum + co2 * SRC(left_x, src_y + 1);
|
||||
sum = sum + co3 * SRC(left_x, src_y + 2);
|
||||
|
||||
smem[get_local_id(0)] = sum;
|
||||
col = EXTRAPOLATE((int)(get_group_id(0)*LOCAL_SIZE + get_local_id(0) - 2), src_cols);
|
||||
LOAD_LOCAL(col, get_local_id(0))
|
||||
}
|
||||
|
||||
if (get_local_id(0) > LOCAL_SIZE - 3)
|
||||
else if (get_local_id(0) < 4)
|
||||
{
|
||||
const int right_x = x + 2;
|
||||
|
||||
sum = co3 * SRC(right_x, src_y - 2);
|
||||
sum = sum + co2 * SRC(right_x, src_y - 1);
|
||||
sum = sum + co1 * SRC(right_x, src_y );
|
||||
sum = sum + co2 * SRC(right_x, src_y + 1);
|
||||
sum = sum + co3 * SRC(right_x, src_y + 2);
|
||||
|
||||
smem[4 + get_local_id(0)] = sum;
|
||||
col = EXTRAPOLATE((int)((get_group_id(0)+1)*LOCAL_SIZE + get_local_id(0) - 2), src_cols);
|
||||
LOAD_LOCAL(col, LOCAL_SIZE + get_local_id(0))
|
||||
}
|
||||
}
|
||||
else
|
||||
else // need extrapolate y
|
||||
{
|
||||
int col = EXTRAPOLATE(x, src_cols);
|
||||
|
||||
sum = co3 * SRC(col, EXTRAPOLATE(src_y - 2, src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y - 1, src_rows));
|
||||
sum = sum + co1 * SRC(col, EXTRAPOLATE(src_y , src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y + 1, src_rows));
|
||||
sum = sum + co3 * SRC(col, EXTRAPOLATE(src_y + 2, src_rows));
|
||||
|
||||
smem[2 + get_local_id(0)] = sum;
|
||||
|
||||
#define EXTRAPOLATE_(val, maxVal) EXTRAPOLATE(val, maxVal)
|
||||
#if kercn == 1
|
||||
col = EXTRAPOLATE(x, src_cols);
|
||||
LOAD_LOCAL(col, 2 + get_local_id(0))
|
||||
#else
|
||||
if (x < src_cols-4)
|
||||
{
|
||||
float4 sum40, sum41, temp4;
|
||||
LOAD_LOCAL4(x, get_local_id(0))
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
col = EXTRAPOLATE(x+i, src_cols);
|
||||
LOAD_LOCAL(col, 2 + 4*get_local_id(0) + i)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (get_local_id(0) < 2)
|
||||
{
|
||||
col = EXTRAPOLATE(x - 2, src_cols);
|
||||
|
||||
sum = co3 * SRC(col, EXTRAPOLATE(src_y - 2, src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y - 1, src_rows));
|
||||
sum = sum + co1 * SRC(col, EXTRAPOLATE(src_y , src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y + 1, src_rows));
|
||||
sum = sum + co3 * SRC(col, EXTRAPOLATE(src_y + 2, src_rows));
|
||||
|
||||
smem[get_local_id(0)] = sum;
|
||||
col = EXTRAPOLATE((int)(get_group_id(0)*LOCAL_SIZE + get_local_id(0) - 2), src_cols);
|
||||
LOAD_LOCAL(col, get_local_id(0))
|
||||
}
|
||||
|
||||
if (get_local_id(0) > LOCAL_SIZE - 3)
|
||||
else if (get_local_id(0) < 4)
|
||||
{
|
||||
col = EXTRAPOLATE(x + 2, src_cols);
|
||||
|
||||
sum = co3 * SRC(col, EXTRAPOLATE(src_y - 2, src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y - 1, src_rows));
|
||||
sum = sum + co1 * SRC(col, EXTRAPOLATE(src_y , src_rows));
|
||||
sum = sum + co2 * SRC(col, EXTRAPOLATE(src_y + 1, src_rows));
|
||||
sum = sum + co3 * SRC(col, EXTRAPOLATE(src_y + 2, src_rows));
|
||||
|
||||
smem[4 + get_local_id(0)] = sum;
|
||||
col = EXTRAPOLATE((int)((get_group_id(0)+1)*LOCAL_SIZE + get_local_id(0) - 2), src_cols);
|
||||
LOAD_LOCAL(col, LOCAL_SIZE + get_local_id(0))
|
||||
}
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
#if kercn == 1
|
||||
if (get_local_id(0) < LOCAL_SIZE / 2)
|
||||
{
|
||||
const int tid2 = get_local_id(0) * 2;
|
||||
|
||||
sum = co3 * smem[2 + tid2 - 2];
|
||||
sum = sum + co2 * smem[2 + tid2 - 1];
|
||||
sum = sum + co1 * smem[2 + tid2 ];
|
||||
sum = sum + co2 * smem[2 + tid2 + 1];
|
||||
sum = sum + co3 * smem[2 + tid2 + 2];
|
||||
|
||||
const int dst_x = (get_group_id(0) * get_local_size(0) + tid2) / 2;
|
||||
|
||||
if (dst_x < dst_cols)
|
||||
storepix(convertToT(sum), dstData + y * dst_step + dst_x * PIXSIZE);
|
||||
{
|
||||
for (int yin = y, y1 = min(dst_rows, y + 2); yin < y1; yin++)
|
||||
{
|
||||
#if cn == 1
|
||||
#if fdepth <= 5
|
||||
FT sum = dot(vload4(0, (__local float*) (&smem) + tid2 + (yin - y) * (LOCAL_SIZE + 4)), (float4)(co3, co2, co1, co2));
|
||||
#else
|
||||
FT sum = dot(vload4(0, (__local double*) (&smem) + tid2 + (yin - y) * (LOCAL_SIZE + 4)), (double4)(co3, co2, co1, co2));
|
||||
#endif
|
||||
#else
|
||||
FT sum = co3 * smem[yin - y][2 + tid2 - 2];
|
||||
sum = MAD(co2, smem[yin - y][2 + tid2 - 1], sum);
|
||||
sum = MAD(co1, smem[yin - y][2 + tid2 ], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid2 + 1], sum);
|
||||
#endif
|
||||
sum = MAD(co3, smem[yin - y][2 + tid2 + 2], sum);
|
||||
storepix(convertToT(sum), dstData + yin * dst_step + dst_x * PIXSIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
int tid4 = get_local_id(0) * 4;
|
||||
int dst_x = (get_group_id(0) * LOCAL_SIZE + tid4) / 2;
|
||||
if (dst_x < dst_cols - 1)
|
||||
{
|
||||
for (int yin = y, y1 = min(dst_rows, y + 2); yin < y1; yin++)
|
||||
{
|
||||
|
||||
FT sum = co3* smem[yin - y][2 + tid4 + 2];
|
||||
sum = MAD(co3, smem[yin - y][2 + tid4 - 2], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 - 1], sum);
|
||||
sum = MAD(co1, smem[yin - y][2 + tid4 ], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 + 1], sum);
|
||||
storepix(convertToT(sum), dstData + mad24(yin, dst_step, dst_x * PIXSIZE));
|
||||
|
||||
dst_x ++;
|
||||
sum = co3* smem[yin - y][2 + tid4 + 4];
|
||||
sum = MAD(co3, smem[yin - y][2 + tid4 ], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 + 1], sum);
|
||||
sum = MAD(co1, smem[yin - y][2 + tid4 + 2], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 + 3], sum);
|
||||
storepix(convertToT(sum), dstData + mad24(yin, dst_step, dst_x * PIXSIZE));
|
||||
dst_x --;
|
||||
}
|
||||
|
||||
}
|
||||
else if (dst_x < dst_cols)
|
||||
{
|
||||
for (int yin = y, y1 = min(dst_rows, y + 2); yin < y1; yin++)
|
||||
{
|
||||
FT sum = co3* smem[yin - y][2 + tid4 + 2];
|
||||
sum = MAD(co3, smem[yin - y][2 + tid4 - 2], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 - 1], sum);
|
||||
sum = MAD(co1, smem[yin - y][2 + tid4 ], sum);
|
||||
sum = MAD(co2, smem[yin - y][2 + tid4 + 1], sum);
|
||||
|
||||
storepix(convertToT(sum), dstData + mad24(yin, dst_step, dst_x * PIXSIZE));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
+303
-211
@@ -147,37 +147,43 @@ __kernel void remap_2_32FC1(__global const uchar * srcptr, int src_step, int src
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
T scalar = convertScalar(nVal);
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int map1_index = mad24(y, map1_step, x * (int)sizeof(float) + map1_offset);
|
||||
int map2_index = mad24(y, map2_step, x * (int)sizeof(float) + map2_offset);
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
T scalar = convertScalar(nVal);
|
||||
|
||||
__global const float * map1 = (__global const float *)(map1ptr + map1_index);
|
||||
__global const float * map2 = (__global const float *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
int map1_index = mad24(y, map1_step, mad24(x, (int)sizeof(float), map1_offset));
|
||||
int map2_index = mad24(y, map2_step, mad24(x, (int)sizeof(float), map2_offset));
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
|
||||
int gx = convert_int_sat_rte(map1[0]);
|
||||
int gy = convert_int_sat_rte(map2[0]);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map1_index += map1_step, map2_index += map2_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const float * map1 = (__global const float *)(map1ptr + map1_index);
|
||||
__global const float * map2 = (__global const float *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
int gx = convert_int_sat_rte(map1[0]);
|
||||
int gy = convert_int_sat_rte(map2[0]);
|
||||
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
#ifndef BORDER_CONSTANT
|
||||
int2 gxy = (int2)(gx, gy);
|
||||
int2 gxy = (int2)(gx, gy);
|
||||
#endif
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, gx * TSIZE + src_offset);
|
||||
storepix(loadpix((__global const T*)(srcptr + src_index)), dst);
|
||||
}
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, mad24(gx, TSIZE, src_offset));
|
||||
storepix(loadpix((__global const T*)(srcptr + src_index)), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,31 +193,36 @@ __kernel void remap_32FC2(__global const uchar * srcptr, int src_step, int src_o
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
T scalar = convertScalar(nVal);
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map_index = mad24(y, map_step, x * (int)sizeof(float2) + map_offset);
|
||||
T scalar = convertScalar(nVal);
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map_index = mad24(y, map_step, mad24(x, (int)sizeof(float2), map_offset));
|
||||
|
||||
__global const float2 * map = (__global const float2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map_index += map_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const float2 * map = (__global const float2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
int2 gxy = convert_int2_sat_rte(map[0]);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
int2 gxy = convert_int2_sat_rte(map[0]);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, gx * TSIZE + src_offset);
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, mad24(gx, TSIZE, src_offset));
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,32 +233,37 @@ __kernel void remap_16SC2(__global const uchar * srcptr, int src_step, int src_o
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
T scalar = convertScalar(nVal);
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map_index = mad24(y, map_step, x * (int)sizeof(short2) + map_offset);
|
||||
T scalar = convertScalar(nVal);
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map_index = mad24(y, map_step, mad24(x, (int)sizeof(short2), map_offset));
|
||||
|
||||
__global const short2 * map = (__global const short2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map_index += map_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const short2 * map = (__global const short2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
int2 gxy = convert_int2(map[0]);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
int2 gxy = convert_int2(map[0]);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, gx * TSIZE + src_offset);
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
}
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, mad24(gx, TSIZE, src_offset));
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,41 +274,54 @@ __kernel void remap_16SC2_16UC1(__global const uchar * srcptr, int src_step, int
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
T scalar = convertScalar(nVal);
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map1_index = mad24(y, map1_step, x * (int)sizeof(short2) + map1_offset);
|
||||
int map2_index = mad24(y, map2_step, x * (int)sizeof(ushort) + map2_offset);
|
||||
T scalar = convertScalar(nVal);
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map1_index = mad24(y, map1_step, mad24(x, (int)sizeof(short2), map1_offset));
|
||||
int map2_index = mad24(y, map2_step, mad24(x, (int)sizeof(ushort), map2_offset));
|
||||
|
||||
__global const short2 * map1 = (__global const short2 *)(map1ptr + map1_index);
|
||||
__global const ushort * map2 = (__global const ushort *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map1_index += map1_step, map2_index += map2_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const short2 * map1 = (__global const short2 *)(map1ptr + map1_index);
|
||||
__global const ushort * map2 = (__global const ushort *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
int map2Value = convert_int(map2[0]) & (INTER_TAB_SIZE2 - 1);
|
||||
int dx = (map2Value & (INTER_TAB_SIZE - 1)) < (INTER_TAB_SIZE >> 1) ? 1 : 0;
|
||||
int dy = (map2Value >> INTER_BITS) < (INTER_TAB_SIZE >> 1) ? 1 : 0;
|
||||
int2 gxy = convert_int2(map1[0]) + (int2)(dx, dy);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
int map2Value = convert_int(map2[0]) & (INTER_TAB_SIZE2 - 1);
|
||||
int dx = (map2Value & (INTER_TAB_SIZE - 1)) < (INTER_TAB_SIZE >> 1) ? 1 : 0;
|
||||
int dy = (map2Value >> INTER_BITS) < (INTER_TAB_SIZE >> 1) ? 1 : 0;
|
||||
int2 gxy = convert_int2(map1[0]) + (int2)(dx, dy);
|
||||
int gx = gxy.x, gy = gxy.y;
|
||||
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, gx * TSIZE + src_offset);
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
}
|
||||
if (NEED_EXTRAPOLATION(gx, gy))
|
||||
{
|
||||
T v;
|
||||
EXTRAPOLATE(gxy, v)
|
||||
storepix(v, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
int src_index = mad24(gy, src_step, mad24(gx, TSIZE, src_offset));
|
||||
storepix(loadpix((__global const T *)(srcptr + src_index)), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif INTER_LINEAR
|
||||
#elif defined INTER_LINEAR
|
||||
|
||||
__constant float coeffs[64] =
|
||||
{ 1.000000f, 0.000000f, 0.968750f, 0.031250f, 0.937500f, 0.062500f, 0.906250f, 0.093750f, 0.875000f, 0.125000f, 0.843750f, 0.156250f,
|
||||
0.812500f, 0.187500f, 0.781250f, 0.218750f, 0.750000f, 0.250000f, 0.718750f, 0.281250f, 0.687500f, 0.312500f, 0.656250f, 0.343750f,
|
||||
0.625000f, 0.375000f, 0.593750f, 0.406250f, 0.562500f, 0.437500f, 0.531250f, 0.468750f, 0.500000f, 0.500000f, 0.468750f, 0.531250f,
|
||||
0.437500f, 0.562500f, 0.406250f, 0.593750f, 0.375000f, 0.625000f, 0.343750f, 0.656250f, 0.312500f, 0.687500f, 0.281250f, 0.718750f,
|
||||
0.250000f, 0.750000f, 0.218750f, 0.781250f, 0.187500f, 0.812500f, 0.156250f, 0.843750f, 0.125000f, 0.875000f, 0.093750f, 0.906250f,
|
||||
0.062500f, 0.937500f, 0.031250f, 0.968750f };
|
||||
|
||||
__kernel void remap_16SC2_16UC1(__global const uchar * srcptr, int src_step, int src_offset, int src_rows, int src_cols,
|
||||
__global uchar * dstptr, int dst_step, int dst_offset, int dst_rows, int dst_cols,
|
||||
@@ -301,54 +330,60 @@ __kernel void remap_16SC2_16UC1(__global const uchar * srcptr, int src_step, int
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map1_index = mad24(y, map1_step, x * (int)sizeof(short2) + map1_offset);
|
||||
int map2_index = mad24(y, map2_step, x * (int)sizeof(ushort) + map2_offset);
|
||||
|
||||
__global const short2 * map1 = (__global const short2 *)(map1ptr + map1_index);
|
||||
__global const ushort * map2 = (__global const ushort *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
int2 map_dataA = convert_int2(map1[0]);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
ushort map2Value = (ushort)(map2[0] & (INTER_TAB_SIZE2 - 1));
|
||||
WT2 u = (WT2)(map2Value & (INTER_TAB_SIZE - 1), map2Value >> INTER_BITS) / (WT2)(INTER_TAB_SIZE);
|
||||
|
||||
WT scalar = convertToWT(convertScalar(nVal));
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map1_index = mad24(y, map1_step, mad24(x, (int)sizeof(short2), map1_offset));
|
||||
int map2_index = mad24(y, map2_step, mad24(x, (int)sizeof(ushort), map2_offset));
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map1_index += map1_step, map2_index += map2_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const short2 * map1 = (__global const short2 *)(map1ptr + map1_index);
|
||||
__global const ushort * map2 = (__global const ushort *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
int2 map_dataA = convert_int2(map1[0]);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
ushort map2Value = (ushort)(map2[0] & (INTER_TAB_SIZE2 - 1));
|
||||
WT2 u = (WT2)(map2Value & (INTER_TAB_SIZE - 1), map2Value >> INTER_BITS) / (WT2)(INTER_TAB_SIZE);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,55 +394,106 @@ __kernel void remap_2_32FC1(__global const uchar * srcptr, int src_step, int src
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map1_index = mad24(y, map1_step, x * (int)sizeof(float) + map1_offset);
|
||||
int map2_index = mad24(y, map2_step, x * (int)sizeof(float) + map2_offset);
|
||||
|
||||
__global const float * map1 = (__global const float *)(map1ptr + map1_index);
|
||||
__global const float * map2 = (__global const float *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
float2 map_data = (float2)(map1[0], map2[0]);
|
||||
|
||||
int2 map_dataA = convert_int2_sat_rtn(map_data);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
float2 _u = map_data - convert_float2(map_dataA);
|
||||
WT2 u = convertToWT2(convert_int2_rte(convertToWT2(_u) * (WT2)INTER_TAB_SIZE)) / (WT2)INTER_TAB_SIZE;
|
||||
WT scalar = convertToWT(convertScalar(nVal));
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map1_index = mad24(y, map1_step, mad24(x, (int)sizeof(float), map1_offset));
|
||||
int map2_index = mad24(y, map2_step, mad24(x, (int)sizeof(float), map2_offset));
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map1_index += map1_step, map2_index += map2_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const float * map1 = (__global const float *)(map1ptr + map1_index);
|
||||
__global const float * map2 = (__global const float *)(map2ptr + map2_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
#if defined BORDER_CONSTANT
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
float xf = map1[0], yf = map2[0];
|
||||
int sx = convert_int_sat_rtn(xf), sy = convert_int_sat_rtn(yf);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
__constant float * coeffs_x = coeffs + ((convert_int_rte(xf * INTER_TAB_SIZE) & (INTER_TAB_SIZE - 1)) << 1);
|
||||
__constant float * coeffs_y = coeffs + ((convert_int_rte(yf * INTER_TAB_SIZE) & (INTER_TAB_SIZE - 1)) << 1);
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
WT sum = (WT)(0), xsum;
|
||||
int src_index = mad24(sy, src_step, mad24(sx, TSIZE, src_offset));
|
||||
|
||||
#pragma unroll
|
||||
for (int yp = 0; yp < 2; ++yp, src_index += src_step)
|
||||
{
|
||||
if (sy + yp >= 0 && sy + yp < src_rows)
|
||||
{
|
||||
xsum = (WT)(0);
|
||||
if (sx >= 0 && sx + 2 < src_cols)
|
||||
{
|
||||
#if depth == 0 && cn == 1
|
||||
uchar2 value = vload2(0, srcptr + src_index);
|
||||
xsum = dot(convert_float2(value), (float2)(coeffs_x[0], coeffs_x[1]));
|
||||
#else
|
||||
#pragma unroll
|
||||
for (int xp = 0; xp < 2; ++xp)
|
||||
xsum = fma(convertToWT(loadpix(srcptr + mad24(xp, TSIZE, src_index))), coeffs_x[xp], xsum);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma unroll
|
||||
for (int xp = 0; xp < 2; ++xp)
|
||||
xsum = fma(sx + xp >= 0 && sx + xp < src_cols ?
|
||||
convertToWT(loadpix(srcptr + mad24(xp, TSIZE, src_index))) : scalar, coeffs_x[xp], xsum);
|
||||
}
|
||||
sum = fma(xsum, coeffs_y[yp], sum);
|
||||
}
|
||||
else
|
||||
sum = fma(scalar, coeffs_y[yp], sum);
|
||||
}
|
||||
|
||||
storepix(convertToT(sum), dst);
|
||||
#else
|
||||
float2 map_data = (float2)(map1[0], map2[0]);
|
||||
|
||||
int2 map_dataA = convert_int2_sat_rtn(map_data);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
float2 _u = map_data - convert_float2(map_dataA);
|
||||
WT2 u = convertToWT2(convert_int2_rte(convertToWT2(_u) * (WT2)INTER_TAB_SIZE)) / (WT2)INTER_TAB_SIZE;
|
||||
WT scalar = convertToWT(convertScalar(nVal));
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,52 +503,58 @@ __kernel void remap_32FC2(__global const uchar * srcptr, int src_step, int src_o
|
||||
ST nVal)
|
||||
{
|
||||
int x = get_global_id(0);
|
||||
int y = get_global_id(1);
|
||||
int y = get_global_id(1) * rowsPerWI;
|
||||
|
||||
if (x < dst_cols && y < dst_rows)
|
||||
if (x < dst_cols)
|
||||
{
|
||||
int dst_index = mad24(y, dst_step, x * TSIZE + dst_offset);
|
||||
int map_index = mad24(y, map_step, x * (int)sizeof(float2) + map_offset);
|
||||
|
||||
__global const float2 * map = (__global const float2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
float2 map_data = map[0];
|
||||
int2 map_dataA = convert_int2_sat_rtn(map_data);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
float2 _u = map_data - convert_float2(map_dataA);
|
||||
WT2 u = convertToWT2(convert_int2_rte(convertToWT2(_u) * (WT2)INTER_TAB_SIZE)) / (WT2)INTER_TAB_SIZE;
|
||||
WT scalar = convertToWT(convertScalar(nVal));
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
|
||||
int map_index = mad24(y, map_step, mad24(x, (int)sizeof(float2), map_offset));
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
#pragma unroll
|
||||
for (int i = 0; i < rowsPerWI; ++i, ++y,
|
||||
map_index += map_step, dst_index += dst_step)
|
||||
if (y < dst_rows)
|
||||
{
|
||||
__global const float2 * map = (__global const float2 *)(mapptr + map_index);
|
||||
__global T * dst = (__global T *)(dstptr + dst_index);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
float2 map_data = map[0];
|
||||
int2 map_dataA = convert_int2_sat_rtn(map_data);
|
||||
int2 map_dataB = (int2)(map_dataA.x + 1, map_dataA.y);
|
||||
int2 map_dataC = (int2)(map_dataA.x, map_dataA.y + 1);
|
||||
int2 map_dataD = (int2)(map_dataA.x + 1, map_dataA.y + 1);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
float2 _u = map_data - convert_float2(map_dataA);
|
||||
WT2 u = convertToWT2(convert_int2_rte(convertToWT2(_u) * (WT2)INTER_TAB_SIZE)) / (WT2)INTER_TAB_SIZE;
|
||||
WT a = scalar, b = scalar, c = scalar, d = scalar;
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
if (!NEED_EXTRAPOLATION(map_dataA.x, map_dataA.y))
|
||||
a = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataA.y, src_step, map_dataA.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataA, a);
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
if (!NEED_EXTRAPOLATION(map_dataB.x, map_dataB.y))
|
||||
b = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataB.y, src_step, map_dataB.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataB, b);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataC.x, map_dataC.y))
|
||||
c = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataC.y, src_step, map_dataC.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataC, c);
|
||||
|
||||
if (!NEED_EXTRAPOLATION(map_dataD.x, map_dataD.y))
|
||||
d = convertToWT(loadpix((__global const T *)(srcptr + mad24(map_dataD.y, src_step, map_dataD.x * TSIZE + src_offset))));
|
||||
else
|
||||
EXTRAPOLATE(map_dataD, d);
|
||||
|
||||
WT dst_data = a * (1 - u.x) * (1 - u.y) +
|
||||
b * (u.x) * (1 - u.y) +
|
||||
c * (1 - u.x) * (u.y) +
|
||||
d * (u.x) * (u.y);
|
||||
storepix(convertToT(dst_data), dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,15 +98,15 @@ __kernel void warpAffine(__global const uchar * srcptr, int src_step, int src_of
|
||||
{
|
||||
int round_delta = (AB_SCALE >> 1);
|
||||
|
||||
int X0_ = rint(M[0] * dx * AB_SCALE);
|
||||
int Y0_ = rint(M[3] * dx * AB_SCALE);
|
||||
int X0 = rint(fma(M[0], dx, fma(M[1], dy0, M[2])) * AB_SCALE) + round_delta;
|
||||
int Y0 = rint(fma(M[3], dx, fma(M[4], dy0, M[5])) * AB_SCALE) + round_delta;
|
||||
|
||||
int XSTEP = (int)(M[1] * AB_SCALE);
|
||||
int YSTEP = (int)(M[4] * AB_SCALE);
|
||||
int dst_index = mad24(dy0, dst_step, mad24(dx, pixsize, dst_offset));
|
||||
|
||||
for (int dy = dy0, dy1 = min(dst_rows, dy0 + rowsPerWI); dy < dy1; ++dy, dst_index += dst_step)
|
||||
{
|
||||
int X0 = X0_ + rint(fma(M[1], dy, M[2]) * AB_SCALE) + round_delta;
|
||||
int Y0 = Y0_ + rint(fma(M[4], dy, M[5]) * AB_SCALE) + round_delta;
|
||||
|
||||
short sx = convert_short_sat(X0 >> AB_BITS);
|
||||
short sy = convert_short_sat(Y0 >> AB_BITS);
|
||||
|
||||
@@ -117,6 +117,9 @@ __kernel void warpAffine(__global const uchar * srcptr, int src_step, int src_of
|
||||
}
|
||||
else
|
||||
storepix(scalar, dstptr + dst_index);
|
||||
|
||||
X0 += XSTEP;
|
||||
Y0 += YSTEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,10 +405,10 @@ typedef void (*PyrFunc)(const Mat&, Mat&, int);
|
||||
|
||||
static bool ocl_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType)
|
||||
{
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
|
||||
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
|
||||
if (channels > 4 || (depth == CV_64F && !doubleSupport))
|
||||
if (cn > 4 || (depth == CV_64F && !doubleSupport))
|
||||
return false;
|
||||
|
||||
Size ssize = _src.size();
|
||||
@@ -423,17 +423,20 @@ static bool ocl_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, in
|
||||
|
||||
int float_depth = depth == CV_64F ? CV_64F : CV_32F;
|
||||
const int local_size = 256;
|
||||
int kercn = 1;
|
||||
if (depth == CV_8U && float_depth == CV_32F && cn == 1 && ocl::Device::getDefault().isIntel())
|
||||
kercn = 4;
|
||||
const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", "BORDER_WRAP",
|
||||
"BORDER_REFLECT_101" };
|
||||
char cvt[2][50];
|
||||
String buildOptions = format(
|
||||
"-D T=%s -D FT=%s -D convertToT=%s -D convertToFT=%s%s "
|
||||
"-D T1=%s -D cn=%d -D %s -D LOCAL_SIZE=%d",
|
||||
ocl::typeToStr(type), ocl::typeToStr(CV_MAKETYPE(float_depth, channels)),
|
||||
ocl::convertTypeStr(float_depth, depth, channels, cvt[0]),
|
||||
ocl::convertTypeStr(depth, float_depth, channels, cvt[1]),
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : "",
|
||||
ocl::typeToStr(depth), channels, borderMap[borderType], local_size
|
||||
"-D T1=%s -D cn=%d -D kercn=%d -D fdepth=%d -D %s -D LOCAL_SIZE=%d",
|
||||
ocl::typeToStr(type), ocl::typeToStr(CV_MAKETYPE(float_depth, cn)),
|
||||
ocl::convertTypeStr(float_depth, depth, cn, cvt[0]),
|
||||
ocl::convertTypeStr(depth, float_depth, cn, cvt[1]),
|
||||
doubleSupport ? " -D DOUBLE_SUPPORT" : "", ocl::typeToStr(depth),
|
||||
cn, kercn, float_depth, borderMap[borderType], local_size
|
||||
);
|
||||
ocl::Kernel k("pyrDown", ocl::imgproc::pyr_down_oclsrc, buildOptions);
|
||||
if (k.empty())
|
||||
@@ -441,8 +444,8 @@ static bool ocl_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, in
|
||||
|
||||
k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst));
|
||||
|
||||
size_t localThreads[2] = { local_size, 1 };
|
||||
size_t globalThreads[2] = { src.cols, dst.rows };
|
||||
size_t localThreads[2] = { local_size/kercn, 1 };
|
||||
size_t globalThreads[2] = { (src.cols + (kercn-1))/kercn, (dst.rows + 1) / 2 };
|
||||
return k.run(2, globalThreads, localThreads, false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user