the rest modes of cv::Mat::convertTo
[profile/ivi/opencv.git] / modules / imgproc / src / corner.cpp
index eeb20fb..096997a 100644 (file)
@@ -41,7 +41,7 @@
 //M*/
 
 #include "precomp.hpp"
-#include "opencl_kernels.hpp"
+#include "opencl_kernels_imgproc.hpp"
 
 namespace cv
 {
@@ -62,8 +62,8 @@ static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
 
     for( i = 0; i < size.height; i++ )
     {
-        const float* cov = (const float*)(_cov.data + _cov.step*i);
-        float* dst = (float*)(_dst.data + _dst.step*i);
+        const float* cov = _cov.ptr<float>(i);
+        float* dst = _dst.ptr<float>(i);
         j = 0;
     #if CV_SSE
         if( simd )
@@ -118,15 +118,15 @@ static void calcHarris( const Mat& _cov, Mat& _dst, double k )
 
     for( i = 0; i < size.height; i++ )
     {
-        const float* cov = (const float*)(_cov.data + _cov.step*i);
-        float* dst = (float*)(_dst.data + _dst.step*i);
+        const float* cov = _cov.ptr<float>(i);
+        float* dst = _dst.ptr<float>(i);
         j = 0;
 
     #if CV_SSE
         if( simd )
         {
             __m128 k4 = _mm_set1_ps((float)k);
-            for( ; j <= size.width - 5; j += 4 )
+            for( ; j <= size.width - 4; j += 4 )
             {
                 __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
@@ -146,6 +146,17 @@ static void calcHarris( const Mat& _cov, Mat& _dst, double k )
                 _mm_storeu_ps(dst + j, a);
             }
         }
+    #elif CV_NEON
+        float32x4_t v_k = vdupq_n_f32((float)k);
+
+        for( ; j <= size.width - 4; j += 4 )
+        {
+            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)));
+        }
     #endif
 
         for( ; j < size.width; j++ )
@@ -227,8 +238,8 @@ static void calcEigenValsVecs( const Mat& _cov, Mat& _dst )
 
     for( int i = 0; i < size.height; i++ )
     {
-        const float* cov = (const float*)(_cov.data + _cov.step*i);
-        float* dst = (float*)(_dst.data + _dst.step*i);
+        const float* cov = _cov.ptr<float>(i);
+        float* dst = _dst.ptr<float>(i);
 
         eigen2x2(cov, dst, size.width);
     }
@@ -276,9 +287,9 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
 
     for( i = 0; i < size.height; i++ )
     {
-        float* cov_data = (float*)(cov.data + i*cov.step);
-        const float* dxdata = (const float*)(Dx.data + i*Dx.step);
-        const float* dydata = (const float*)(Dy.data + i*Dy.step);
+        float* cov_data = cov.ptr<float>(i);
+        const float* dxdata = Dx.ptr<float>(i);
+        const float* dydata = Dy.ptr<float>(i);
 
         for( j = 0; j < size.width; j++ )
         {
@@ -503,9 +514,9 @@ void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, in
             if (ok >= 0)
             {
                 AutoBuffer<uchar> buffer(bufferSize);
-                ok = minEigenValFunc(src.data, (int) src.step, (Ipp32f*) dst.data, (int) dst.step, srcRoi, kerType, kerSize, blockSize, buffer);
+                ok = minEigenValFunc(src.ptr(), (int) src.step, dst.ptr<Ipp32f>(), (int) dst.step, srcRoi, kerType, kerSize, blockSize, buffer);
                 CV_SUPPRESS_DEPRECATED_START
-                if (ok >= 0) ok = ippiMulC_32f_C1IR(norm_coef, (Ipp32f*) dst.data, (int) dst.step, srcRoi);
+                if (ok >= 0) ok = ippiMulC_32f_C1IR(norm_coef, dst.ptr<Ipp32f>(), (int) dst.step, srcRoi);
                 CV_SUPPRESS_DEPRECATED_END
                 if (ok >= 0)
                     return;
@@ -607,19 +618,55 @@ 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
+    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);
+#endif
 
     Size size = src.size();
     int i, j;
     for( i = 0; i < size.height; i++ )
     {
-        float* dstdata = (float*)(dst.data + i*dst.step);
-        const float* dxdata = (const float*)(Dx.data + i*Dx.step);
-        const float* dydata = (const float*)(Dy.data + i*Dy.step);
-        const float* d2xdata = (const float*)(D2x.data + i*D2x.step);
-        const float* d2ydata = (const float*)(D2y.data + i*D2y.step);
-        const float* dxydata = (const float*)(Dxy.data + i*Dxy.step);
+        float* dstdata = dst.ptr<float>(i);
+        const float* dxdata = Dx.ptr<float>(i);
+        const float* dydata = Dy.ptr<float>(i);
+        const float* d2xdata = D2x.ptr<float>(i);
+        const float* d2ydata = D2y.ptr<float>(i);
+        const float* dxydata = Dxy.ptr<float>(i);
 
-        for( j = 0; j < size.width; j++ )
+        j = 0;
+
+#if CV_SSE2
+        if (haveSSE2)
+        {
+            for( ; j <= size.width - 4; j += 4 )
+            {
+                __m128 v_dx = _mm_loadu_ps((const float *)(dxdata + j));
+                __m128 v_dy = _mm_loadu_ps((const float *)(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);
+            }
+        }
+#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++ )
         {
             float dx = dxdata[j];
             float dy = dydata[j];