mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
+96
-202
@@ -47,10 +47,6 @@
|
||||
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
#if CV_SIMD128
|
||||
#define CV_MALLOC_SIMD128 16
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -296,18 +292,11 @@ static bool ocl_Canny(InputArray _src, const UMat& dx_, const UMat& dy_, OutputA
|
||||
|
||||
#define CANNY_PUSH(map, stack) *map = 2, stack.push_back(map)
|
||||
|
||||
#define CANNY_CHECK_SIMD(m, high, map, stack) \
|
||||
if (m > high) \
|
||||
CANNY_PUSH(map, stack); \
|
||||
else \
|
||||
*map = 0
|
||||
|
||||
#define CANNY_CHECK(m, high, map, stack) \
|
||||
if (m > high) \
|
||||
CANNY_PUSH(map, stack); \
|
||||
else \
|
||||
*map = 0; \
|
||||
continue
|
||||
*map = 0
|
||||
|
||||
class parallelCanny : public ParallelLoopBody
|
||||
{
|
||||
@@ -317,9 +306,14 @@ public:
|
||||
src(_src), src2(_src), map(_map), _borderPeaksParallel(borderPeaksParallel),
|
||||
low(_low), high(_high), aperture_size(_aperture_size), L2gradient(_L2gradient)
|
||||
{
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
for(int i = 0; i < v_int8::nlanes; ++i)
|
||||
{
|
||||
smask[i] = 0;
|
||||
smask[i + v_int8::nlanes] = (schar)-1;
|
||||
}
|
||||
if (true)
|
||||
_map.create(src.rows + 2, (int)alignSize((size_t)(src.cols + CV_MALLOC_SIMD128 + 1), CV_MALLOC_SIMD128), CV_8UC1);
|
||||
_map.create(src.rows + 2, (int)alignSize((size_t)(src.cols + CV_SIMD_WIDTH + 1), CV_SIMD_WIDTH), CV_8UC1);
|
||||
else
|
||||
#endif
|
||||
_map.create(src.rows + 2, src.cols + 2, CV_8UC1);
|
||||
@@ -336,9 +330,14 @@ public:
|
||||
src(_dx), src2(_dy), map(_map), _borderPeaksParallel(borderPeaksParallel),
|
||||
low(_low), high(_high), aperture_size(0), L2gradient(_L2gradient)
|
||||
{
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
for(int i = 0; i < v_int8::nlanes; ++i)
|
||||
{
|
||||
smask[i] = 0;
|
||||
smask[i + v_int8::nlanes] = (schar)-1;
|
||||
}
|
||||
if (true)
|
||||
_map.create(src.rows + 2, (int)alignSize((size_t)(src.cols + CV_MALLOC_SIMD128 + 1), CV_MALLOC_SIMD128), CV_8UC1);
|
||||
_map.create(src.rows + 2, (int)alignSize((size_t)(src.cols + CV_SIMD_WIDTH + 1), CV_SIMD_WIDTH), CV_8UC1);
|
||||
else
|
||||
#endif
|
||||
_map.create(src.rows + 2, src.cols + 2, CV_8UC1);
|
||||
@@ -397,11 +396,11 @@ public:
|
||||
}
|
||||
|
||||
// _mag_p: previous row, _mag_a: actual row, _mag_n: next row
|
||||
#if CV_SIMD128
|
||||
AutoBuffer<int> buffer(3 * (mapstep * cn + CV_MALLOC_SIMD128));
|
||||
_mag_p = alignPtr(buffer.data() + 1, CV_MALLOC_SIMD128);
|
||||
_mag_a = alignPtr(_mag_p + mapstep * cn, CV_MALLOC_SIMD128);
|
||||
_mag_n = alignPtr(_mag_a + mapstep * cn, CV_MALLOC_SIMD128);
|
||||
#if CV_SIMD
|
||||
AutoBuffer<int> buffer(3 * (mapstep * cn + CV_SIMD_WIDTH));
|
||||
_mag_p = alignPtr(buffer.data() + 1, CV_SIMD_WIDTH);
|
||||
_mag_a = alignPtr(_mag_p + mapstep * cn, CV_SIMD_WIDTH);
|
||||
_mag_n = alignPtr(_mag_a + mapstep * cn, CV_SIMD_WIDTH);
|
||||
#else
|
||||
AutoBuffer<int> buffer(3 * (mapstep * cn));
|
||||
_mag_p = buffer.data() + 1;
|
||||
@@ -437,21 +436,19 @@ public:
|
||||
if (L2gradient)
|
||||
{
|
||||
int j = 0, width = src.cols * cn;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
for ( ; j <= width - v_int16::nlanes; j += v_int16::nlanes)
|
||||
{
|
||||
for ( ; j <= width - 8; j += 8)
|
||||
{
|
||||
v_int16x8 v_dx = v_load((const short*)(_dx + j));
|
||||
v_int16x8 v_dy = v_load((const short*)(_dy + j));
|
||||
v_int16 v_dx = vx_load((const short*)(_dx + j));
|
||||
v_int16 v_dy = vx_load((const short*)(_dy + j));
|
||||
|
||||
v_int32x4 v_dxp_low, v_dxp_high;
|
||||
v_int32x4 v_dyp_low, v_dyp_high;
|
||||
v_expand(v_dx, v_dxp_low, v_dxp_high);
|
||||
v_expand(v_dy, v_dyp_low, v_dyp_high);
|
||||
v_int32 v_dxp_low, v_dxp_high;
|
||||
v_int32 v_dyp_low, v_dyp_high;
|
||||
v_expand(v_dx, v_dxp_low, v_dxp_high);
|
||||
v_expand(v_dy, v_dyp_low, v_dyp_high);
|
||||
|
||||
v_store_aligned((int *)(_mag_n + j), v_dxp_low*v_dxp_low+v_dyp_low*v_dyp_low);
|
||||
v_store_aligned((int *)(_mag_n + j + 4), v_dxp_high*v_dxp_high+v_dyp_high*v_dyp_high);
|
||||
}
|
||||
v_store_aligned((int *)(_mag_n + j), v_dxp_low*v_dxp_low+v_dyp_low*v_dyp_low);
|
||||
v_store_aligned((int *)(_mag_n + j + v_int32::nlanes), v_dxp_high*v_dxp_high+v_dyp_high*v_dyp_high);
|
||||
}
|
||||
#endif
|
||||
for ( ; j < width; ++j)
|
||||
@@ -460,23 +457,21 @@ public:
|
||||
else
|
||||
{
|
||||
int j = 0, width = src.cols * cn;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
for(; j <= width - v_int16::nlanes; j += v_int16::nlanes)
|
||||
{
|
||||
for(; j <= width - 8; j += 8)
|
||||
{
|
||||
v_int16x8 v_dx = v_load((const short *)(_dx + j));
|
||||
v_int16x8 v_dy = v_load((const short *)(_dy + j));
|
||||
v_int16 v_dx = vx_load((const short *)(_dx + j));
|
||||
v_int16 v_dy = vx_load((const short *)(_dy + j));
|
||||
|
||||
v_dx = v_reinterpret_as_s16(v_abs(v_dx));
|
||||
v_dy = v_reinterpret_as_s16(v_abs(v_dy));
|
||||
v_dx = v_reinterpret_as_s16(v_abs(v_dx));
|
||||
v_dy = v_reinterpret_as_s16(v_abs(v_dy));
|
||||
|
||||
v_int32x4 v_dx_ml, v_dy_ml, v_dx_mh, v_dy_mh;
|
||||
v_expand(v_dx, v_dx_ml, v_dx_mh);
|
||||
v_expand(v_dy, v_dy_ml, v_dy_mh);
|
||||
v_int32 v_dx_ml, v_dy_ml, v_dx_mh, v_dy_mh;
|
||||
v_expand(v_dx, v_dx_ml, v_dx_mh);
|
||||
v_expand(v_dy, v_dy_ml, v_dy_mh);
|
||||
|
||||
v_store_aligned((int *)(_mag_n + j), v_dx_ml + v_dy_ml);
|
||||
v_store_aligned((int *)(_mag_n + j + 4), v_dx_mh + v_dy_mh);
|
||||
}
|
||||
v_store_aligned((int *)(_mag_n + j), v_dx_ml + v_dy_ml);
|
||||
v_store_aligned((int *)(_mag_n + j + v_int32::nlanes), v_dx_mh + v_dy_mh);
|
||||
}
|
||||
#endif
|
||||
for ( ; j < width; ++j)
|
||||
@@ -520,9 +515,9 @@ public:
|
||||
|
||||
// From here actual src row is (i - 1)
|
||||
// Set left and right border to 1
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
if (true)
|
||||
_pmap = map.ptr<uchar>(i) + CV_MALLOC_SIMD128;
|
||||
_pmap = map.ptr<uchar>(i) + CV_SIMD_WIDTH;
|
||||
else
|
||||
#endif
|
||||
_pmap = map.ptr<uchar>(i) + 1;
|
||||
@@ -542,167 +537,60 @@ public:
|
||||
|
||||
const int TG22 = 13573;
|
||||
int j = 0;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
const v_int32x4 v_low = v_setall_s32(low);
|
||||
const v_int8x16 v_one = v_setall_s8(1);
|
||||
const v_int32 v_low = vx_setall_s32(low);
|
||||
const v_int8 v_one = vx_setall_s8(1);
|
||||
|
||||
for (; j <= src.cols - 32; j += 32)
|
||||
for (; j <= src.cols - v_int8::nlanes; j += v_int8::nlanes)
|
||||
{
|
||||
v_int32x4 v_m1 = v_load_aligned((const int*)(_mag_a + j));
|
||||
v_int32x4 v_m2 = v_load_aligned((const int*)(_mag_a + j + 4));
|
||||
v_int32x4 v_m3 = v_load_aligned((const int*)(_mag_a + j + 8));
|
||||
v_int32x4 v_m4 = v_load_aligned((const int*)(_mag_a + j + 12));
|
||||
|
||||
v_int32x4 v_cmp1 = v_m1 > v_low;
|
||||
v_int32x4 v_cmp2 = v_m2 > v_low;
|
||||
v_int32x4 v_cmp3 = v_m3 > v_low;
|
||||
v_int32x4 v_cmp4 = v_m4 > v_low;
|
||||
|
||||
v_m1 = v_load_aligned((const int*)(_mag_a + j + 16));
|
||||
v_m2 = v_load_aligned((const int*)(_mag_a + j + 20));
|
||||
v_m3 = v_load_aligned((const int*)(_mag_a + j + 24));
|
||||
v_m4 = v_load_aligned((const int*)(_mag_a + j + 28));
|
||||
|
||||
v_store_aligned((signed char*)(_pmap + j), v_one);
|
||||
v_store_aligned((signed char*)(_pmap + j + 16), v_one);
|
||||
|
||||
v_int16x8 v_cmp80 = v_pack(v_cmp1, v_cmp2);
|
||||
v_int16x8 v_cmp81 = v_pack(v_cmp3, v_cmp4);
|
||||
|
||||
v_cmp1 = v_m1 > v_low;
|
||||
v_cmp2 = v_m2 > v_low;
|
||||
v_cmp3 = v_m3 > v_low;
|
||||
v_cmp4 = v_m4 > v_low;
|
||||
|
||||
v_int8x16 v_cmp = v_pack(v_cmp80, v_cmp81);
|
||||
|
||||
v_cmp80 = v_pack(v_cmp1, v_cmp2);
|
||||
v_cmp81 = v_pack(v_cmp3, v_cmp4);
|
||||
|
||||
unsigned int mask = v_signmask(v_cmp);
|
||||
|
||||
v_cmp = v_pack(v_cmp80, v_cmp81);
|
||||
mask |= v_signmask(v_cmp) << 16;
|
||||
|
||||
if (mask)
|
||||
v_int8 v_cmp = v_pack(v_pack(vx_load_aligned((const int*)(_mag_a + j )) > v_low,
|
||||
vx_load_aligned((const int*)(_mag_a + j + v_int32::nlanes)) > v_low),
|
||||
v_pack(vx_load_aligned((const int*)(_mag_a + j + 2*v_int32::nlanes)) > v_low,
|
||||
vx_load_aligned((const int*)(_mag_a + j + 3*v_int32::nlanes)) > v_low));
|
||||
while (v_check_any(v_cmp))
|
||||
{
|
||||
int k = j;
|
||||
int l = v_scan_forward(v_cmp);
|
||||
v_cmp &= vx_load(smask + v_int8::nlanes - 1 - l);
|
||||
int k = j + l;
|
||||
|
||||
do
|
||||
int m = _mag_a[k];
|
||||
short xs = _dx[k];
|
||||
short ys = _dy[k];
|
||||
int x = (int)std::abs(xs);
|
||||
int y = (int)std::abs(ys) << 15;
|
||||
|
||||
int tg22x = x * TG22;
|
||||
|
||||
if (y < tg22x)
|
||||
{
|
||||
int l = trailingZeros32(mask);
|
||||
k += l;
|
||||
mask >>= l;
|
||||
|
||||
int m = _mag_a[k];
|
||||
short xs = _dx[k];
|
||||
short ys = _dy[k];
|
||||
int x = (int)std::abs(xs);
|
||||
int y = (int)std::abs(ys) << 15;
|
||||
|
||||
int tg22x = x * TG22;
|
||||
|
||||
if (y < tg22x)
|
||||
if (m > _mag_a[k - 1] && m >= _mag_a[k + 1])
|
||||
{
|
||||
if (m > _mag_a[k - 1] && m >= _mag_a[k + 1])
|
||||
CANNY_CHECK(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int tg67x = tg22x + (x << 16);
|
||||
if (y > tg67x)
|
||||
{
|
||||
if (m > _mag_p[k] && m >= _mag_n[k])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
CANNY_CHECK(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int tg67x = tg22x + (x << 16);
|
||||
if (y > tg67x)
|
||||
int s = (xs ^ ys) < 0 ? -1 : 1;
|
||||
if(m > _mag_p[k - s] && m > _mag_n[k + s])
|
||||
{
|
||||
if (m > _mag_p[k] && m >= _mag_n[k])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = (xs ^ ys) < 0 ? -1 : 1;
|
||||
if(m > _mag_p[k - s] && m > _mag_n[k + s])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
}
|
||||
CANNY_CHECK(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
++k;
|
||||
} while((mask >>= 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j <= src.cols - 16)
|
||||
{
|
||||
v_int32x4 v_m1 = v_load_aligned((const int*)(_mag_a + j));
|
||||
v_int32x4 v_m2 = v_load_aligned((const int*)(_mag_a + j + 4));
|
||||
v_int32x4 v_m3 = v_load_aligned((const int*)(_mag_a + j + 8));
|
||||
v_int32x4 v_m4 = v_load_aligned((const int*)(_mag_a + j + 12));
|
||||
|
||||
v_store_aligned((signed char*)(_pmap + j), v_one);
|
||||
|
||||
v_int32x4 v_cmp1 = v_m1 > v_low;
|
||||
v_int32x4 v_cmp2 = v_m2 > v_low;
|
||||
v_int32x4 v_cmp3 = v_m3 > v_low;
|
||||
v_int32x4 v_cmp4 = v_m4 > v_low;
|
||||
|
||||
v_int16x8 v_cmp80 = v_pack(v_cmp1, v_cmp2);
|
||||
v_int16x8 v_cmp81 = v_pack(v_cmp3, v_cmp4);
|
||||
|
||||
v_int8x16 v_cmp = v_pack(v_cmp80, v_cmp81);
|
||||
unsigned int mask = v_signmask(v_cmp);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
int k = j;
|
||||
|
||||
do
|
||||
{
|
||||
int l = trailingZeros32(mask);
|
||||
k += l;
|
||||
mask >>= l;
|
||||
|
||||
int m = _mag_a[k];
|
||||
short xs = _dx[k];
|
||||
short ys = _dy[k];
|
||||
int x = (int)std::abs(xs);
|
||||
int y = (int)std::abs(ys) << 15;
|
||||
|
||||
int tg22x = x * TG22;
|
||||
|
||||
if (y < tg22x)
|
||||
{
|
||||
if (m > _mag_a[k - 1] && m >= _mag_a[k + 1])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int tg67x = tg22x + (x << 16);
|
||||
if (y > tg67x)
|
||||
{
|
||||
if (m > _mag_p[k] && m >= _mag_n[k])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = (xs ^ ys) < 0 ? -1 : 1;
|
||||
if(m > _mag_p[k - s] && m > _mag_n[k + s])
|
||||
{
|
||||
CANNY_CHECK_SIMD(m, high, (_pmap+k), stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
++k;
|
||||
} while((mask >>= 1));
|
||||
}
|
||||
j += 16;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (; j < src.cols; j++)
|
||||
@@ -723,6 +611,7 @@ public:
|
||||
if (m > _mag_a[j - 1] && m >= _mag_a[j + 1])
|
||||
{
|
||||
CANNY_CHECK(m, high, (_pmap+j), stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -733,6 +622,7 @@ public:
|
||||
if (m > _mag_p[j] && m >= _mag_n[j])
|
||||
{
|
||||
CANNY_CHECK(m, high, (_pmap+j), stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -741,6 +631,7 @@ public:
|
||||
if(m > _mag_p[j - s] && m > _mag_n[j + s])
|
||||
{
|
||||
CANNY_CHECK(m, high, (_pmap+j), stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -802,6 +693,9 @@ private:
|
||||
ptrdiff_t mapstep;
|
||||
int cn;
|
||||
mutable Mutex mutex;
|
||||
#if CV_SIMD
|
||||
schar smask[2*v_int8::nlanes];
|
||||
#endif
|
||||
};
|
||||
|
||||
class finalPass : public ParallelLoopBody
|
||||
@@ -824,31 +718,31 @@ public:
|
||||
int j = 0;
|
||||
uchar *pdst = dst.ptr<uchar>(i);
|
||||
const uchar *pmap = map.ptr<uchar>(i + 1);
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
if (true)
|
||||
pmap += CV_MALLOC_SIMD128;
|
||||
pmap += CV_SIMD_WIDTH;
|
||||
else
|
||||
#endif
|
||||
pmap += 1;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
const v_uint8x16 v_zero = v_setzero_u8();
|
||||
const v_uint8x16 v_ff = ~v_zero;
|
||||
const v_uint8x16 v_two(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
|
||||
const v_uint8 v_zero = vx_setzero_u8();
|
||||
const v_uint8 v_ff = ~v_zero;
|
||||
const v_uint8 v_two = vx_setall_u8(2);
|
||||
|
||||
for (; j <= dst.cols - 16; j += 16)
|
||||
for (; j <= dst.cols - v_uint8::nlanes; j += v_uint8::nlanes)
|
||||
{
|
||||
v_uint8x16 v_pmap = v_load_aligned((const unsigned char*)(pmap + j));
|
||||
v_uint8 v_pmap = vx_load_aligned((const unsigned char*)(pmap + j));
|
||||
v_pmap = v_select(v_pmap == v_two, v_ff, v_zero);
|
||||
v_store((pdst + j), v_pmap);
|
||||
}
|
||||
|
||||
if (j <= dst.cols - 8)
|
||||
if (j <= dst.cols - v_uint8::nlanes/2)
|
||||
{
|
||||
v_uint8x16 v_pmap = v_load_low((const unsigned char*)(pmap + j));
|
||||
v_uint8 v_pmap = vx_load_low((const unsigned char*)(pmap + j));
|
||||
v_pmap = v_select(v_pmap == v_two, v_ff, v_zero);
|
||||
v_store_low((pdst + j), v_pmap);
|
||||
j += 8;
|
||||
j += v_uint8::nlanes/2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2542,7 +2542,8 @@ namespace cv{
|
||||
|
||||
//Array used to store info and labeled pixel by each thread.
|
||||
//Different threads affect different memory location of chunksSizeAndLabels
|
||||
int *chunksSizeAndLabels = (int *)cv::fastMalloc(h * sizeof(int));
|
||||
const int chunksSizeAndLabelsSize = h + 1;
|
||||
int *chunksSizeAndLabels = (int *)cv::fastMalloc(chunksSizeAndLabelsSize * sizeof(int));
|
||||
|
||||
//Tree of labels
|
||||
LabelT *P = (LabelT *)cv::fastMalloc(Plength * sizeof(LabelT));
|
||||
@@ -2561,6 +2562,7 @@ namespace cv{
|
||||
|
||||
LabelT nLabels = 1;
|
||||
for (int i = 0; i < h; i = chunksSizeAndLabels[i]){
|
||||
CV_Assert(i + 1 < chunksSizeAndLabelsSize);
|
||||
flattenL(P, LabelT((i + 1) / 2) * LabelT((w + 1) / 2) + 1, chunksSizeAndLabels[i + 1], nLabels);
|
||||
}
|
||||
|
||||
|
||||
@@ -1061,19 +1061,13 @@ cvFindNextContour( CvContourScanner scanner )
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CV_SIMD_WIDTH > 16
|
||||
v_uint8 vx_prev = vx_setall_u8((uchar)prev);
|
||||
while (x <= width - v_uint8::nlanes &&
|
||||
v_check_all(vx_load((uchar*)(img + x)) == vx_prev))
|
||||
x += v_uint8::nlanes;
|
||||
#endif
|
||||
v_uint8x16 v_prev = v_setall_u8((uchar)prev);
|
||||
for (; x <= width - v_uint8x16::nlanes; x += v_uint8x16::nlanes)
|
||||
v_uint8 v_prev = vx_setall_u8((uchar)prev);
|
||||
for (; x <= width - v_uint8::nlanes; x += v_uint8::nlanes)
|
||||
{
|
||||
unsigned int mask = (unsigned int)v_signmask(v_load((uchar*)(img + x)) != v_prev);
|
||||
if (mask)
|
||||
v_uint8 vmask = (vx_load((uchar*)(img + x)) != v_prev);
|
||||
if (v_check_any(vmask))
|
||||
{
|
||||
p = img[(x += cv::trailingZeros32(mask))];
|
||||
p = img[(x += v_scan_forward(vmask))];
|
||||
goto _next_contour;
|
||||
}
|
||||
}
|
||||
@@ -1334,19 +1328,13 @@ CvLinkedRunPoint;
|
||||
inline int findStartContourPoint(uchar *src_data, CvSize img_size, int j)
|
||||
{
|
||||
#if CV_SIMD
|
||||
#if CV_SIMD_WIDTH > 16
|
||||
v_uint8 vx_zero = vx_setzero_u8();
|
||||
while (j <= img_size.width - v_uint8::nlanes &&
|
||||
v_check_all(vx_load((uchar*)(src_data + j)) == vx_zero))
|
||||
j += v_uint8::nlanes;
|
||||
#endif
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
for (; j <= img_size.width - v_uint8x16::nlanes; j += v_uint8x16::nlanes)
|
||||
v_uint8 v_zero = vx_setzero_u8();
|
||||
for (; j <= img_size.width - v_uint8::nlanes; j += v_uint8::nlanes)
|
||||
{
|
||||
unsigned int mask = (unsigned int)v_signmask(v_load((uchar*)(src_data + j)) != v_zero);
|
||||
if (mask)
|
||||
v_uint8 vmask = (vx_load((uchar*)(src_data + j)) != v_zero);
|
||||
if (v_check_any(vmask))
|
||||
{
|
||||
j += cv::trailingZeros32(mask);
|
||||
j += v_scan_forward(vmask);
|
||||
return j;
|
||||
}
|
||||
}
|
||||
@@ -1365,19 +1353,13 @@ inline int findEndContourPoint(uchar *src_data, CvSize img_size, int j)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CV_SIMD_WIDTH > 16
|
||||
v_uint8 vx_zero = vx_setzero_u8();
|
||||
while (j <= img_size.width - v_uint8::nlanes &&
|
||||
v_check_all(vx_load((uchar*)(src_data + j)) != vx_zero))
|
||||
j += v_uint8::nlanes;
|
||||
#endif
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
v_uint8 v_zero = vx_setzero_u8();
|
||||
for (; j <= img_size.width - v_uint8::nlanes; j += v_uint8::nlanes)
|
||||
{
|
||||
unsigned int mask = (unsigned int)v_signmask(v_load((uchar*)(src_data + j)) == v_zero);
|
||||
if (mask)
|
||||
v_uint8 vmask = (vx_load((uchar*)(src_data + j)) == v_zero);
|
||||
if (v_check_any(vmask))
|
||||
{
|
||||
j += cv::trailingZeros32(mask);
|
||||
j += v_scan_forward(vmask);
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,9 +1160,7 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type,
|
||||
corrDepth = ddepth == CV_64F ? CV_64F : CV_32F;
|
||||
temp.create(Size(width, height), CV_MAKETYPE(corrDepth, dst_channels));
|
||||
}
|
||||
crossCorr(src, kernel, temp, src.size(),
|
||||
CV_MAKETYPE(corrDepth, src_channels),
|
||||
anchor, 0, borderType);
|
||||
crossCorr(src, kernel, temp, anchor, 0, borderType);
|
||||
add(temp, delta, temp);
|
||||
if (temp.data != dst_data) {
|
||||
temp.convertTo(dst, dst.type());
|
||||
@@ -1172,9 +1170,7 @@ static bool dftFilter2D(int stype, int dtype, int kernel_type,
|
||||
temp = Mat(Size(width, height), dtype, dst_data, dst_step);
|
||||
else
|
||||
temp.create(Size(width, height), dtype);
|
||||
crossCorr(src, kernel, temp, src.size(),
|
||||
CV_MAKETYPE(ddepth, src_channels),
|
||||
anchor, delta, borderType);
|
||||
crossCorr(src, kernel, temp, anchor, delta, borderType);
|
||||
if (temp.data != dst_data)
|
||||
temp.copyTo(dst);
|
||||
}
|
||||
|
||||
@@ -366,7 +366,6 @@ static inline Point normalizeAnchor( Point anchor, Size ksize )
|
||||
|
||||
void preprocess2DKernel( const Mat& kernel, std::vector<Point>& coords, std::vector<uchar>& coeffs );
|
||||
void crossCorr( const Mat& src, const Mat& templ, Mat& dst,
|
||||
Size corrsize, int ctype,
|
||||
Point anchor=Point(0,0), double delta=0,
|
||||
int borderType=BORDER_REFLECT_101 );
|
||||
|
||||
|
||||
@@ -1139,32 +1139,23 @@ public:
|
||||
|
||||
for(; x < numCols; ++x )
|
||||
{
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
v_uint8x16 v_zero = v_setzero_u8();
|
||||
v_uint8 v_zero = vx_setzero_u8();
|
||||
|
||||
for(; x <= numCols - 32; x += 32) {
|
||||
v_uint8x16 v_edge1 = v_load(edgeData + x);
|
||||
v_uint8x16 v_edge2 = v_load(edgeData + x + 16);
|
||||
for(; x <= numCols - 2*v_uint8::nlanes; x += 2*v_uint8::nlanes) {
|
||||
v_uint8 v_edge1 = (vx_load(edgeData + x ) != v_zero);
|
||||
v_uint8 v_edge2 = (vx_load(edgeData + x + v_uint8::nlanes) != v_zero);
|
||||
|
||||
v_uint8x16 v_cmp1 = (v_edge1 == v_zero);
|
||||
v_uint8x16 v_cmp2 = (v_edge2 == v_zero);
|
||||
|
||||
unsigned int mask1 = v_signmask(v_cmp1);
|
||||
unsigned int mask2 = v_signmask(v_cmp2);
|
||||
|
||||
mask1 ^= 0x0000ffff;
|
||||
mask2 ^= 0x0000ffff;
|
||||
|
||||
if(mask1)
|
||||
if(v_check_any(v_edge1))
|
||||
{
|
||||
x += trailingZeros32(mask1);
|
||||
x += v_scan_forward(v_edge1);
|
||||
goto _next_step;
|
||||
}
|
||||
|
||||
if(mask2)
|
||||
if(v_check_any(v_edge2))
|
||||
{
|
||||
x += trailingZeros32(mask2 << 16);
|
||||
x += v_uint8::nlanes + v_scan_forward(v_edge2);
|
||||
goto _next_step;
|
||||
}
|
||||
}
|
||||
@@ -1175,7 +1166,7 @@ public:
|
||||
|
||||
if(x == numCols)
|
||||
continue;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
_next_step:
|
||||
#endif
|
||||
float vx, vy;
|
||||
@@ -1506,36 +1497,35 @@ inline int HoughCircleEstimateRadiusInvoker<NZPointList>::filterCircles(const Po
|
||||
int nzCount = 0;
|
||||
const Point* nz_ = &nz[0];
|
||||
int j = 0;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
const v_float32x4 v_minRadius2 = v_setall_f32(minRadius2);
|
||||
const v_float32x4 v_maxRadius2 = v_setall_f32(maxRadius2);
|
||||
const v_float32 v_minRadius2 = vx_setall_f32(minRadius2);
|
||||
const v_float32 v_maxRadius2 = vx_setall_f32(maxRadius2);
|
||||
|
||||
v_float32x4 v_curCenterX = v_setall_f32(curCenter.x);
|
||||
v_float32x4 v_curCenterY = v_setall_f32(curCenter.y);
|
||||
v_float32 v_curCenterX = vx_setall_f32(curCenter.x);
|
||||
v_float32 v_curCenterY = vx_setall_f32(curCenter.y);
|
||||
|
||||
float CV_DECL_ALIGNED(16) rbuf[4];
|
||||
for(; j <= nzSz - 4; j += 4)
|
||||
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) rbuf[v_float32::nlanes];
|
||||
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) rmask[v_int32::nlanes];
|
||||
for(; j <= nzSz - v_float32::nlanes; j += v_float32::nlanes)
|
||||
{
|
||||
v_float32x4 v_nzX, v_nzY;
|
||||
v_float32 v_nzX, v_nzY;
|
||||
v_load_deinterleave((const float*)&nz_[j], v_nzX, v_nzY); // FIXIT use proper datatype
|
||||
|
||||
v_float32x4 v_x = v_cvt_f32(v_reinterpret_as_s32(v_nzX));
|
||||
v_float32x4 v_y = v_cvt_f32(v_reinterpret_as_s32(v_nzY));
|
||||
v_float32 v_x = v_cvt_f32(v_reinterpret_as_s32(v_nzX));
|
||||
v_float32 v_y = v_cvt_f32(v_reinterpret_as_s32(v_nzY));
|
||||
|
||||
v_float32x4 v_dx = v_x - v_curCenterX;
|
||||
v_float32x4 v_dy = v_y - v_curCenterY;
|
||||
v_float32 v_dx = v_x - v_curCenterX;
|
||||
v_float32 v_dy = v_y - v_curCenterY;
|
||||
|
||||
v_float32x4 v_r2 = (v_dx * v_dx) + (v_dy * v_dy);
|
||||
v_float32x4 vmask = (v_minRadius2 <= v_r2) & (v_r2 <= v_maxRadius2);
|
||||
unsigned int mask = v_signmask(vmask);
|
||||
if (mask)
|
||||
v_float32 v_r2 = (v_dx * v_dx) + (v_dy * v_dy);
|
||||
v_float32 vmask = (v_minRadius2 <= v_r2) & (v_r2 <= v_maxRadius2);
|
||||
if (v_check_any(vmask))
|
||||
{
|
||||
v_store_aligned(rmask, v_reinterpret_as_s32(vmask));
|
||||
v_store_aligned(rbuf, v_r2);
|
||||
if (mask & 1) ddata[nzCount++] = rbuf[0];
|
||||
if (mask & 2) ddata[nzCount++] = rbuf[1];
|
||||
if (mask & 4) ddata[nzCount++] = rbuf[2];
|
||||
if (mask & 8) ddata[nzCount++] = rbuf[3];
|
||||
for (int i = 0; i < v_int32::nlanes; ++i)
|
||||
if (rmask[i]) ddata[nzCount++] = rbuf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1566,12 +1556,13 @@ inline int HoughCircleEstimateRadiusInvoker<NZPointSet>::filterCircles(const Poi
|
||||
const Range xOuter = Range(std::max(int(curCenter.x - rOuter), 0), std::min(int(curCenter.x + rOuter), positions.cols));
|
||||
const Range yOuter = Range(std::max(int(curCenter.y - rOuter), 0), std::min(int(curCenter.y + rOuter), positions.rows));
|
||||
|
||||
#if CV_SIMD128
|
||||
const int numSIMDPoints = 4;
|
||||
|
||||
const v_float32x4 v_minRadius2 = v_setall_f32(minRadius2);
|
||||
const v_float32x4 v_maxRadius2 = v_setall_f32(maxRadius2);
|
||||
const v_float32x4 v_curCenterX_0123 = v_setall_f32(curCenter.x) - v_float32x4(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
#if CV_SIMD
|
||||
float v_seq[v_float32::nlanes];
|
||||
for (int i = 0; i < v_float32::nlanes; ++i)
|
||||
v_seq[i] = (float)i;
|
||||
const v_float32 v_minRadius2 = vx_setall_f32(minRadius2);
|
||||
const v_float32 v_maxRadius2 = vx_setall_f32(maxRadius2);
|
||||
const v_float32 v_curCenterX_0123 = vx_setall_f32(curCenter.x) - vx_load(v_seq);
|
||||
#endif
|
||||
|
||||
for (int y = yOuter.start; y < yOuter.end; y++)
|
||||
@@ -1581,29 +1572,28 @@ inline int HoughCircleEstimateRadiusInvoker<NZPointSet>::filterCircles(const Poi
|
||||
float dy2 = dy * dy;
|
||||
|
||||
int x = xOuter.start;
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
{
|
||||
const v_float32x4 v_dy2 = v_setall_f32(dy2);
|
||||
const v_uint32x4 v_zero_u32 = v_setall_u32(0);
|
||||
float CV_DECL_ALIGNED(16) rbuf[4];
|
||||
for (; x <= xOuter.end - 4; x += numSIMDPoints)
|
||||
const v_float32 v_dy2 = vx_setall_f32(dy2);
|
||||
const v_uint32 v_zero_u32 = vx_setall_u32(0);
|
||||
float CV_DECL_ALIGNED(CV_SIMD_WIDTH) rbuf[v_float32::nlanes];
|
||||
int CV_DECL_ALIGNED(CV_SIMD_WIDTH) rmask[v_int32::nlanes];
|
||||
for (; x <= xOuter.end - v_float32::nlanes; x += v_float32::nlanes)
|
||||
{
|
||||
v_uint32x4 v_mask = v_load_expand_q(ptr + x);
|
||||
v_uint32 v_mask = vx_load_expand_q(ptr + x);
|
||||
v_mask = v_mask != v_zero_u32;
|
||||
|
||||
v_float32x4 v_x = v_cvt_f32(v_setall_s32(x));
|
||||
v_float32x4 v_dx = v_x - v_curCenterX_0123;
|
||||
v_float32 v_x = v_cvt_f32(vx_setall_s32(x));
|
||||
v_float32 v_dx = v_x - v_curCenterX_0123;
|
||||
|
||||
v_float32x4 v_r2 = (v_dx * v_dx) + v_dy2;
|
||||
v_float32x4 vmask = (v_minRadius2 <= v_r2) & (v_r2 <= v_maxRadius2) & v_reinterpret_as_f32(v_mask);
|
||||
unsigned int mask = v_signmask(vmask);
|
||||
if (mask)
|
||||
v_float32 v_r2 = (v_dx * v_dx) + v_dy2;
|
||||
v_float32 vmask = (v_minRadius2 <= v_r2) & (v_r2 <= v_maxRadius2) & v_reinterpret_as_f32(v_mask);
|
||||
if (v_check_any(vmask))
|
||||
{
|
||||
v_store_aligned(rmask, v_reinterpret_as_s32(vmask));
|
||||
v_store_aligned(rbuf, v_r2);
|
||||
if (mask & 1) ddata[nzCount++] = rbuf[0];
|
||||
if (mask & 2) ddata[nzCount++] = rbuf[1];
|
||||
if (mask & 4) ddata[nzCount++] = rbuf[2];
|
||||
if (mask & 8) ddata[nzCount++] = rbuf[3];
|
||||
for (int i = 0; i < v_int32::nlanes; ++i)
|
||||
if (rmask[i]) ddata[nzCount++] = rbuf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,7 +564,6 @@ static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _
|
||||
#include "opencv2/core/hal/hal.hpp"
|
||||
|
||||
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
||||
Size corrsize, int ctype,
|
||||
Point anchor, double delta, int borderType )
|
||||
{
|
||||
const double blockScale = 4.5;
|
||||
@@ -574,7 +573,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
||||
Mat templ = _templ;
|
||||
int depth = img.depth(), cn = img.channels();
|
||||
int tdepth = templ.depth(), tcn = templ.channels();
|
||||
int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype);
|
||||
int cdepth = corr.depth(), ccn = corr.channels();
|
||||
|
||||
CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 );
|
||||
|
||||
@@ -585,13 +584,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
||||
}
|
||||
|
||||
CV_Assert( depth == tdepth || tdepth == CV_32F);
|
||||
CV_Assert( corrsize.height <= img.rows + templ.rows - 1 &&
|
||||
corrsize.width <= img.cols + templ.cols - 1 );
|
||||
CV_Assert( corr.rows <= img.rows + templ.rows - 1 &&
|
||||
corr.cols <= img.cols + templ.cols - 1 );
|
||||
|
||||
CV_Assert( ccn == 1 || delta == 0 );
|
||||
|
||||
corr.create(corrsize, ctype);
|
||||
|
||||
int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth);
|
||||
Size blocksize, dftsize;
|
||||
|
||||
@@ -815,8 +812,8 @@ static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _
|
||||
Mat mask2_templ = templ.mul(mask2);
|
||||
|
||||
Mat corr(corrSize, CV_32F);
|
||||
crossCorr( img, mask2_templ, corr, corr.size(), corr.type(), Point(0,0), 0, 0 );
|
||||
crossCorr( img2, mask, result, result.size(), result.type(), Point(0,0), 0, 0 );
|
||||
crossCorr( img, mask2_templ, corr, Point(0,0), 0, 0 );
|
||||
crossCorr( img2, mask, result, Point(0,0), 0, 0 );
|
||||
|
||||
result -= corr * 2;
|
||||
result += templSum2;
|
||||
@@ -830,8 +827,8 @@ static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _
|
||||
}
|
||||
|
||||
Mat corr(corrSize, CV_32F);
|
||||
crossCorr( img2, mask2, corr, corr.size(), corr.type(), Point(0,0), 0, 0 );
|
||||
crossCorr( img, mask_templ, result, result.size(), result.type(), Point(0,0), 0, 0 );
|
||||
crossCorr( img2, mask2, corr, Point(0,0), 0, 0 );
|
||||
crossCorr( img, mask_templ, result, Point(0,0), 0, 0 );
|
||||
|
||||
sqrt(corr, corr);
|
||||
result = result.mul(1/corr);
|
||||
@@ -1125,7 +1122,7 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_matchTemplate(img, templ, result, method))
|
||||
|
||||
crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);
|
||||
crossCorr( img, templ, result, Point(0,0), 0, 0);
|
||||
|
||||
common_matchTemplate(img, templ, result, method, cn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user