1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

Merge branch 'UserColormap' of https://github.com/LaurentBerger/opencv into UserColormap

This commit is contained in:
LaurentBerger
2017-02-06 16:50:31 +01:00
108 changed files with 2464 additions and 1266 deletions
+191 -127
View File
@@ -43,16 +43,98 @@
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "opencv2/core/hal/intrin.hpp"
namespace cv
{
#if CV_AVX
// load three 8-packed float vector and deinterleave
// probably it's better to write down somewhere else
static inline void load_deinterleave(const float* ptr, __m256& a, __m256& b, __m256& c)
{
__m256 s0 = _mm256_loadu_ps(ptr); // a0, b0, c0, a1, b1, c1, a2, b2,
__m256 s1 = _mm256_loadu_ps(ptr + 8); // c2, a3, b3, c3, a4, b4, c4, a5,
__m256 s2 = _mm256_loadu_ps(ptr + 16); // b5, c5, a6, b6, c6, a7, b7, c7,
__m256 s3 = _mm256_permute2f128_ps(s1, s2, 0x21); // a4, b4, c4, a5, b5, c5, a6, b6,
__m256 s4 = _mm256_permute2f128_ps(s2, s2, 0x33); // c6, a7, b7, c7, c6, a7, b7, c7,
__m256 v00 = _mm256_unpacklo_ps(s0, s3); // a0, a4, b0, b4, b1, b5, c1, c5,
__m256 v01 = _mm256_unpackhi_ps(s0, s3); // c0, c4, a1, a5, a2, a6, b2, b6,
__m256 v02 = _mm256_unpacklo_ps(s1, s4); // c2, c6, a3, a7, x, x, x, x,
__m256 v03 = _mm256_unpackhi_ps(s1, s4); // b3, b7, c3, c7, x, x, x, x,
__m256 v04 = _mm256_permute2f128_ps(v02, v03, 0x20); // c2, c6, a3, a7, b3, b7, c3, c7,
__m256 v05 = _mm256_permute2f128_ps(v01, v03, 0x21); // a2, a6, b2, b6, b3, b7, c3, c7,
__m256 v10 = _mm256_unpacklo_ps(v00, v05); // a0, a2, a4, a6, b1, b3, b5, b7,
__m256 v11 = _mm256_unpackhi_ps(v00, v05); // b0, b2, b4, b6, c1, c3, c5, c7,
__m256 v12 = _mm256_unpacklo_ps(v01, v04); // c0, c2, c4, c6, x, x, x, x,
__m256 v13 = _mm256_unpackhi_ps(v01, v04); // a1, a3, a5, a7, x, x, x, x,
__m256 v14 = _mm256_permute2f128_ps(v11, v12, 0x20); // b0, b2, b4, b6, c0, c2, c4, c6,
__m256 v15 = _mm256_permute2f128_ps(v10, v11, 0x31); // b1, b3, b5, b7, c1, c3, c5, c7,
__m256 v20 = _mm256_unpacklo_ps(v14, v15); // b0, b1, b2, b3, c0, c1, c2, c3,
__m256 v21 = _mm256_unpackhi_ps(v14, v15); // b4, b5, b6, b7, c4, c5, c6, c7,
__m256 v22 = _mm256_unpacklo_ps(v10, v13); // a0, a1, a2, a3, x, x, x, x,
__m256 v23 = _mm256_unpackhi_ps(v10, v13); // a4, a5, a6, a7, x, x, x, x,
a = _mm256_permute2f128_ps(v22, v23, 0x20); // a0, a1, a2, a3, a4, a5, a6, a7,
b = _mm256_permute2f128_ps(v20, v21, 0x20); // b0, b1, b2, b3, b4, b5, b6, b7,
c = _mm256_permute2f128_ps(v20, v21, 0x31); // c0, c1, c2, c3, c4, c5, c6, c7,
}
// realign four 3-packed vector to three 4-packed vector
static inline void v_pack4x3to3x4(const __m128i& s0, const __m128i& s1, const __m128i& s2, const __m128i& s3, __m128i& d0, __m128i& d1, __m128i& d2)
{
d0 = _mm_or_si128(s0, _mm_slli_si128(s1, 12));
d1 = _mm_or_si128(_mm_srli_si128(s1, 4), _mm_slli_si128(s2, 8));
d2 = _mm_or_si128(_mm_srli_si128(s2, 8), _mm_slli_si128(s3, 4));
}
// separate high and low 128 bit and cast to __m128i
static inline void v_separate_lo_hi(const __m256& src, __m128i& lo, __m128i& hi)
{
lo = _mm_castps_si128(_mm256_castps256_ps128(src));
hi = _mm_castps_si128(_mm256_extractf128_ps(src, 1));
}
// interleave three 8-float vector and store
static inline void store_interleave(float* ptr, const __m256& a, const __m256& b, const __m256& c)
{
__m128i a0, a1, b0, b1, c0, c1;
v_separate_lo_hi(a, a0, a1);
v_separate_lo_hi(b, b0, b1);
v_separate_lo_hi(c, c0, c1);
v_uint32x4 z = v_setzero_u32();
v_uint32x4 u0, u1, u2, u3;
v_transpose4x4(v_uint32x4(a0), v_uint32x4(b0), v_uint32x4(c0), z, u0, u1, u2, u3);
v_pack4x3to3x4(u0.val, u1.val, u2.val, u3.val, a0, b0, c0);
v_transpose4x4(v_uint32x4(a1), v_uint32x4(b1), v_uint32x4(c1), z, u0, u1, u2, u3);
v_pack4x3to3x4(u0.val, u1.val, u2.val, u3.val, a1, b1, c1);
#if !defined(__GNUC__) || defined(__INTEL_COMPILER)
_mm256_storeu_ps(ptr, _mm256_setr_m128(_mm_castsi128_ps(a0), _mm_castsi128_ps(b0)));
_mm256_storeu_ps(ptr + 8, _mm256_setr_m128(_mm_castsi128_ps(c0), _mm_castsi128_ps(a1)));
_mm256_storeu_ps(ptr + 16, _mm256_setr_m128(_mm_castsi128_ps(b1), _mm_castsi128_ps(c1)));
#else
// GCC: workaround for missing AVX intrinsic: "_mm256_setr_m128()"
_mm256_storeu_ps(ptr, _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_castsi128_ps(a0)), _mm_castsi128_ps(b0), 1));
_mm256_storeu_ps(ptr + 8, _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_castsi128_ps(c0)), _mm_castsi128_ps(a1), 1));
_mm256_storeu_ps(ptr + 16, _mm256_insertf128_ps(_mm256_castps128_ps256(_mm_castsi128_ps(b1)), _mm_castsi128_ps(c1), 1));
#endif
}
#endif // CV_AVX
static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
{
int i, j;
Size size = _cov.size();
#if CV_SSE
volatile bool simd = checkHardwareSupport(CV_CPU_SSE);
#if CV_AVX
bool haveAvx = checkHardwareSupport(CV_CPU_AVX);
#endif
#if CV_SIMD128
bool haveSimd = hasSIMD128();
#endif
if( _cov.isContinuous() && _dst.isContinuous() )
@@ -66,45 +148,40 @@ static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
const float* cov = _cov.ptr<float>(i);
float* dst = _dst.ptr<float>(i);
j = 0;
#if CV_SSE
if( simd )
#if CV_AVX
if( haveAvx )
{
__m128 half = _mm_set1_ps(0.5f);
for( ; j <= size.width - 4; j += 4 )
__m256 half = _mm256_set1_ps(0.5f);
for( ; j <= size.width - 8; j += 8 )
{
__m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
__m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
__m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
__m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
__m128 a, b, c, t;
t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
a = _mm_movelh_ps(t, b);
b = _mm_movehl_ps(b, t);
a = _mm_mul_ps(a, half);
c = _mm_mul_ps(c, half);
t = _mm_sub_ps(a, c);
t = _mm_add_ps(_mm_mul_ps(t, t), _mm_mul_ps(b,b));
a = _mm_sub_ps(_mm_add_ps(a, c), _mm_sqrt_ps(t));
_mm_storeu_ps(dst + j, a);
__m256 v_a, v_b, v_c, v_t;
load_deinterleave(cov + j*3, v_a, v_b, v_c);
v_a = _mm256_mul_ps(v_a, half);
v_c = _mm256_mul_ps(v_c, half);
v_t = _mm256_sub_ps(v_a, v_c);
v_t = _mm256_add_ps(_mm256_mul_ps(v_b, v_b), _mm256_mul_ps(v_t, v_t));
_mm256_storeu_ps(dst + j, _mm256_sub_ps(_mm256_add_ps(v_a, v_c), _mm256_sqrt_ps(v_t)));
}
}
#elif CV_NEON
float32x4_t v_half = vdupq_n_f32(0.5f);
for( ; j <= size.width - 4; j += 4 )
{
float32x4x3_t v_src = vld3q_f32(cov + j * 3);
float32x4_t v_a = vmulq_f32(v_src.val[0], v_half);
float32x4_t v_b = v_src.val[1];
float32x4_t v_c = vmulq_f32(v_src.val[2], v_half);
#endif // CV_AVX
float32x4_t v_t = vsubq_f32(v_a, v_c);
v_t = vmlaq_f32(vmulq_f32(v_t, v_t), v_b, v_b);
vst1q_f32(dst + j, vsubq_f32(vaddq_f32(v_a, v_c), cv_vsqrtq_f32(v_t)));
#if CV_SIMD128
if( haveSimd )
{
v_float32x4 half = v_setall_f32(0.5f);
for( ; j <= size.width - v_float32x4::nlanes; j += v_float32x4::nlanes )
{
v_float32x4 v_a, v_b, v_c, v_t;
v_load_deinterleave(cov + j*3, v_a, v_b, v_c);
v_a *= half;
v_c *= half;
v_t = v_a - v_c;
v_t = v_muladd(v_b, v_b, (v_t * v_t));
v_store(dst + j, (v_a + v_c) - v_sqrt(v_t));
}
}
#endif
#endif // CV_SIMD128
for( ; j < size.width; j++ )
{
float a = cov[j*3]*0.5f;
@@ -120,8 +197,11 @@ static void calcHarris( const Mat& _cov, Mat& _dst, double k )
{
int i, j;
Size size = _cov.size();
#if CV_SSE
volatile bool simd = checkHardwareSupport(CV_CPU_SSE);
#if CV_AVX
bool haveAvx = checkHardwareSupport(CV_CPU_AVX);
#endif
#if CV_SIMD128
bool haveSimd = hasSIMD128();
#endif
if( _cov.isContinuous() && _dst.isContinuous() )
@@ -136,42 +216,41 @@ static void calcHarris( const Mat& _cov, Mat& _dst, double k )
float* dst = _dst.ptr<float>(i);
j = 0;
#if CV_SSE
if( simd )
#if CV_AVX
if( haveAvx )
{
__m128 k4 = _mm_set1_ps((float)k);
for( ; j <= size.width - 4; j += 4 )
__m256 v_k = _mm256_set1_ps((float)k);
for( ; j <= size.width - 8; j += 8 )
{
__m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
__m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
__m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
__m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
__m128 a, b, c, t;
t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
a = _mm_movelh_ps(t, b);
b = _mm_movehl_ps(b, t);
t = _mm_add_ps(a, c);
a = _mm_sub_ps(_mm_mul_ps(a, c), _mm_mul_ps(b, b));
t = _mm_mul_ps(_mm_mul_ps(k4, t), t);
a = _mm_sub_ps(a, t);
_mm_storeu_ps(dst + j, a);
__m256 v_a, v_b, v_c;
load_deinterleave(cov + j * 3, v_a, v_b, v_c);
__m256 v_ac_bb = _mm256_sub_ps(_mm256_mul_ps(v_a, v_c), _mm256_mul_ps(v_b, v_b));
__m256 v_ac = _mm256_add_ps(v_a, v_c);
__m256 v_dst = _mm256_sub_ps(v_ac_bb, _mm256_mul_ps(v_k, _mm256_mul_ps(v_ac, v_ac)));
_mm256_storeu_ps(dst + j, v_dst);
}
}
#elif CV_NEON
float32x4_t v_k = vdupq_n_f32((float)k);
#endif // CV_AVX
for( ; j <= size.width - 4; j += 4 )
#if CV_SIMD128
if( haveSimd )
{
float32x4x3_t v_src = vld3q_f32(cov + j * 3);
float32x4_t v_a = v_src.val[0], v_b = v_src.val[1], v_c = v_src.val[2];
float32x4_t v_ac_bb = vmlsq_f32(vmulq_f32(v_a, v_c), v_b, v_b);
float32x4_t v_ac = vaddq_f32(v_a, v_c);
vst1q_f32(dst + j, vmlsq_f32(v_ac_bb, v_k, vmulq_f32(v_ac, v_ac)));
v_float32x4 v_k = v_setall_f32((float)k);
for( ; j <= size.width - v_float32x4::nlanes; j += v_float32x4::nlanes )
{
v_float32x4 v_a, v_b, v_c;
v_load_deinterleave(cov + j * 3, v_a, v_b, v_c);
v_float32x4 v_ac_bb = v_a * v_c - v_b * v_b;
v_float32x4 v_ac = v_a + v_c;
v_float32x4 v_dst = v_ac_bb - v_k * v_ac * v_ac;
v_store(dst + j, v_dst);
}
}
#endif
#endif // CV_SIMD128
for( ; j < size.width; j++ )
{
@@ -272,8 +351,11 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
if (tegra::useTegra() && tegra::cornerEigenValsVecs(src, eigenv, block_size, aperture_size, op_type, k, borderType))
return;
#endif
#if CV_SSE2
bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
#if CV_AVX
bool haveAvx = checkHardwareSupport(CV_CPU_AVX);
#endif
#if CV_SIMD128
bool haveSimd = hasSIMD128();
#endif
int depth = src.depth();
@@ -309,47 +391,41 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
const float* dydata = Dy.ptr<float>(i);
j = 0;
#if CV_NEON
for( ; j <= size.width - 4; j += 4 )
{
float32x4_t v_dx = vld1q_f32(dxdata + j);
float32x4_t v_dy = vld1q_f32(dydata + j);
float32x4x3_t v_dst;
v_dst.val[0] = vmulq_f32(v_dx, v_dx);
v_dst.val[1] = vmulq_f32(v_dx, v_dy);
v_dst.val[2] = vmulq_f32(v_dy, v_dy);
vst3q_f32(cov_data + j * 3, v_dst);
}
#elif CV_SSE2
if (haveSSE2)
#if CV_AVX
if( haveAvx )
{
for( ; j <= size.width - 8; j += 8 )
{
__m128 v_dx_0 = _mm_loadu_ps(dxdata + j);
__m128 v_dx_1 = _mm_loadu_ps(dxdata + j + 4);
__m128 v_dy_0 = _mm_loadu_ps(dydata + j);
__m128 v_dy_1 = _mm_loadu_ps(dydata + j + 4);
__m256 v_dx = _mm256_loadu_ps(dxdata + j);
__m256 v_dy = _mm256_loadu_ps(dydata + j);
__m128 v_dx2_0 = _mm_mul_ps(v_dx_0, v_dx_0);
__m128 v_dxy_0 = _mm_mul_ps(v_dx_0, v_dy_0);
__m128 v_dy2_0 = _mm_mul_ps(v_dy_0, v_dy_0);
__m128 v_dx2_1 = _mm_mul_ps(v_dx_1, v_dx_1);
__m128 v_dxy_1 = _mm_mul_ps(v_dx_1, v_dy_1);
__m128 v_dy2_1 = _mm_mul_ps(v_dy_1, v_dy_1);
__m256 v_dst0, v_dst1, v_dst2;
v_dst0 = _mm256_mul_ps(v_dx, v_dx);
v_dst1 = _mm256_mul_ps(v_dx, v_dy);
v_dst2 = _mm256_mul_ps(v_dy, v_dy);
_mm_interleave_ps(v_dx2_0, v_dx2_1, v_dxy_0, v_dxy_1, v_dy2_0, v_dy2_1);
_mm_storeu_ps(cov_data + j * 3, v_dx2_0);
_mm_storeu_ps(cov_data + j * 3 + 4, v_dx2_1);
_mm_storeu_ps(cov_data + j * 3 + 8, v_dxy_0);
_mm_storeu_ps(cov_data + j * 3 + 12, v_dxy_1);
_mm_storeu_ps(cov_data + j * 3 + 16, v_dy2_0);
_mm_storeu_ps(cov_data + j * 3 + 20, v_dy2_1);
store_interleave(cov_data + j * 3, v_dst0, v_dst1, v_dst2);
}
}
#endif
#endif // CV_AVX
#if CV_SIMD128
if( haveSimd )
{
for( ; j <= size.width - v_float32x4::nlanes; j += v_float32x4::nlanes )
{
v_float32x4 v_dx = v_load(dxdata + j);
v_float32x4 v_dy = v_load(dydata + j);
v_float32x4 v_dst0, v_dst1, v_dst2;
v_dst0 = v_dx * v_dx;
v_dst1 = v_dx * v_dy;
v_dst2 = v_dy * v_dy;
v_store_interleave(cov_data + j * 3, v_dst0, v_dst1, v_dst2);
}
}
#endif // CV_SIMD128
for( ; j < size.width; j++ )
{
@@ -751,13 +827,10 @@ void cv::preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int bord
if( src.depth() == CV_8U )
factor *= 255;
factor = 1./(factor * factor * factor);
#if CV_NEON || CV_SSE2
#if CV_SIMD128
float factor_f = (float)factor;
#endif
#if CV_SSE2
volatile bool haveSSE2 = cv::checkHardwareSupport(CV_CPU_SSE2);
__m128 v_factor = _mm_set1_ps(factor_f), v_m2 = _mm_set1_ps(-2.0f);
bool haveSimd = hasSIMD128();
v_float32x4 v_factor = v_setall_f32(factor_f), v_m2 = v_setall_f32(-2.0f);
#endif
Size size = src.size();
@@ -773,30 +846,21 @@ void cv::preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int bord
j = 0;
#if CV_SSE2
if (haveSSE2)
#if CV_SIMD128
if (haveSimd)
{
for( ; j <= size.width - 4; j += 4 )
for( ; j <= size.width - v_float32x4::nlanes; j += v_float32x4::nlanes )
{
__m128 v_dx = _mm_loadu_ps((const float *)(dxdata + j));
__m128 v_dy = _mm_loadu_ps((const float *)(dydata + j));
v_float32x4 v_dx = v_load(dxdata + j);
v_float32x4 v_dy = v_load(dydata + j);
__m128 v_s1 = _mm_mul_ps(_mm_mul_ps(v_dx, v_dx), _mm_loadu_ps((const float *)(d2ydata + j)));
__m128 v_s2 = _mm_mul_ps(_mm_mul_ps(v_dy, v_dy), _mm_loadu_ps((const float *)(d2xdata + j)));
__m128 v_s3 = _mm_mul_ps(_mm_mul_ps(v_dx, v_dy), _mm_loadu_ps((const float *)(dxydata + j)));
v_s1 = _mm_mul_ps(v_factor, _mm_add_ps(v_s1, _mm_add_ps(v_s2, _mm_mul_ps(v_s3, v_m2))));
_mm_storeu_ps(dstdata + j, v_s1);
v_float32x4 v_s1 = (v_dx * v_dx) * v_load(d2ydata + j);
v_float32x4 v_s2 = v_muladd((v_dy * v_dy), v_load(d2xdata + j), v_s1);
v_float32x4 v_s3 = v_muladd((v_dy * v_dx) * v_load(dxydata + j), v_m2, v_s2);
v_store(dstdata + j, v_s3 * v_factor);
}
}
#elif CV_NEON
for( ; j <= size.width - 4; j += 4 )
{
float32x4_t v_dx = vld1q_f32(dxdata + j), v_dy = vld1q_f32(dydata + j);
float32x4_t v_s = vmulq_f32(v_dx, vmulq_f32(v_dx, vld1q_f32(d2ydata + j)));
v_s = vmlaq_f32(v_s, vld1q_f32(d2xdata + j), vmulq_f32(v_dy, v_dy));
v_s = vmlaq_f32(v_s, vld1q_f32(dxydata + j), vmulq_n_f32(vmulq_f32(v_dy, v_dx), -2));
vst1q_f32(dstdata + j, vmulq_n_f32(v_s, factor_f));
}
#endif
for( ; j < size.width; j++ )
+22
View File
@@ -50,6 +50,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou
double eps = 1.e-5;
double mmm;
double result = 0;
bool anyA = false, anyB = false;
HuMoments( moments(contour1), ma );
HuMoments( moments(contour2), mb );
@@ -62,6 +63,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if (ama > 0)
anyA = true;
if (amb > 0)
anyB = true;
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
@@ -90,6 +96,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if (ama > 0)
anyA = true;
if (amb > 0)
anyB = true;
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
@@ -118,6 +129,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou
double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if (ama > 0)
anyA = true;
if (amb > 0)
anyB = true;
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
@@ -145,6 +161,12 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou
CV_Error( CV_StsBadArg, "Unknown comparison method" );
}
//If anyA and anyB are both true, the result is correct.
//If anyA and anyB are both false, the distance is 0, perfect match.
//If only one is true, then it's a false 0 and return large error.
if (anyA != anyB)
result = DBL_MAX;
return result;
}
+2 -10
View File
@@ -186,21 +186,13 @@ __kernel void calcLut(__global __const uchar * src, const int srcStep,
#else
clipped = smem[0];
#endif
// broadcast evaluated value
__local int totalClipped;
if (tid == 0)
totalClipped = clipped;
barrier(CLK_LOCAL_MEM_FENCE);
// redistribute clipped samples evenly
int redistBatch = totalClipped / 256;
int redistBatch = clipped / 256;
tHistVal += redistBatch;
int residual = totalClipped - redistBatch * 256;
int residual = clipped - redistBatch * 256;
int rStep = 256 / residual;
if (rStep < 1)
rStep = 1;
+5 -16
View File
@@ -129,7 +129,7 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
int i_start = 0;
int j_start = 0;
#if CV_SIMD128 && CV_SSE2
#if CV_SIMD128
if(hasSIMD128())
{
uchar *m_src;
@@ -160,18 +160,13 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
n_dx = dx.ptr<short>(i+1);
n_dy = dy.ptr<short>(i+1);
v_uint8x16 v_select_m = v_uint8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0xFF);
// Process rest of columns 16-column chunks at a time
for ( j = 1; j < W - 16; j += 16 )
{
// Load top row for 3x3 Sobel filter
v_uint8x16 v_um = v_load(&p_src[j-1]);
v_uint8x16 v_un = v_load(&p_src[j]);
v_uint8x16 v_up = v_load(&p_src[j+1]);
// TODO: Replace _mm_slli_si128 with hal method
v_uint8x16 v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
v_uint8x16(_mm_srli_si128(v_um.val, 1)));
v_uint16x8 v_um1, v_um2, v_un1, v_un2, v_up1, v_up2;
v_expand(v_um, v_um1, v_um2);
v_expand(v_un, v_un1, v_un2);
@@ -185,10 +180,8 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
// Load second row for 3x3 Sobel filter
v_um = v_load(&c_src[j-1]);
v_un = v_load(&c_src[j]);
v_up = v_load(&c_src[j+1]);
// TODO: Replace _mm_slli_si128 with hal method
v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
v_uint8x16(_mm_srli_si128(v_um.val, 1)));
v_expand(v_um, v_um1, v_um2);
v_expand(v_un, v_un1, v_un2);
v_expand(v_up, v_up1, v_up2);
@@ -201,10 +194,8 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
// Load third row for 3x3 Sobel filter
v_um = v_load(&n_src[j-1]);
v_un = v_load(&n_src[j]);
v_up = v_load(&n_src[j+1]);
// TODO: Replace _mm_slli_si128 with hal method
v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
v_uint8x16(_mm_srli_si128(v_um.val, 1)));
v_expand(v_um, v_um1, v_um2);
v_expand(v_un, v_un1, v_un2);
v_expand(v_up, v_up1, v_up2);
@@ -236,10 +227,8 @@ void spatialGradient( InputArray _src, OutputArray _dx, OutputArray _dy,
// Load fourth row for 3x3 Sobel filter
v_um = v_load(&m_src[j-1]);
v_un = v_load(&m_src[j]);
v_up = v_load(&m_src[j+1]);
// TODO: Replace _mm_slli_si128 with hal method
v_un = v_select(v_select_m, v_uint8x16(_mm_slli_si128(v_up.val, 1)),
v_uint8x16(_mm_srli_si128(v_um.val, 1)));
v_expand(v_um, v_um1, v_um2);
v_expand(v_un, v_un1, v_un2);
v_expand(v_up, v_up1, v_up2);