cv:;sortIdx
authorIlya Lavrenov <ilya.lavrenov@itseez.com>
Tue, 15 Apr 2014 10:43:44 +0000 (14:43 +0400)
committerIlya Lavrenov <ilya.lavrenov@itseez.com>
Fri, 18 Apr 2014 10:31:27 +0000 (14:31 +0400)
modules/core/perf/perf_sort.cpp
modules/core/src/matrix.cpp

index fac2b45..d9e12bc 100644 (file)
@@ -30,3 +30,23 @@ PERF_TEST_P(sortFixture, sort, TYPICAL_MATS_SORT)
 
     SANITY_CHECK(b);
 }
+
+typedef sortFixture sortIdxFixture;
+
+#undef SORT_TYPES
+#define SORT_TYPES SORT_EVERY_COLUMN | SORT_ASCENDING, SORT_EVERY_COLUMN | SORT_DESCENDING
+
+PERF_TEST_P(sortIdxFixture, sorIdx, TYPICAL_MATS_SORT)
+{
+    const sortParams params = GetParam();
+    const Size sz = get<0>(params);
+    const int type = get<1>(params), flags = get<2>(params);
+
+    cv::Mat a(sz, type), b(sz, type);
+
+    declare.in(a, WARMUP_RNG).out(b);
+
+    TEST_CYCLE() cv::sortIdx(a, b, flags);
+
+    SANITY_CHECK(b);
+}
index f1dd8a8..f81252a 100644 (file)
@@ -3556,7 +3556,29 @@ public:
     const _Tp* arr;
 };
 
+#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY
+
+typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(void *, int *, int);
+
+static IppSortIndexFunc getSortIndexFunc(int depth, bool sortDescending)
+{
+    if (!sortDescending)
+        return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexAscend_8u_I :
+            depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexAscend_16u_I :
+            depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexAscend_16s_I :
+            depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexAscend_32s_I :
+            depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexAscend_32f_I :
+            depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexAscend_64f_I : 0;
+    else
+        return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexDescend_8u_I :
+            depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexDescend_16u_I :
+            depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexDescend_16s_I :
+            depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexDescend_32s_I :
+            depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexDescend_32f_I :
+            depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexDescend_64f_I : 0;
+}
 
+#endif
 
 template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
 {
@@ -3581,6 +3603,10 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
     bptr = (T*)buf;
     _iptr = (int*)ibuf;
 
+#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY
+    IppSortIndexFunc ippFunc = getSortIndexFunc(src.depth(), sortDescending);
+#endif
+
     for( i = 0; i < n; i++ )
     {
         T* ptr = bptr;
@@ -3598,10 +3624,17 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
         }
         for( j = 0; j < len; j++ )
             iptr[j] = j;
-        std::sort( iptr, iptr + len, LessThanIdx<T>(ptr) );
-        if( sortDescending )
-            for( j = 0; j < len/2; j++ )
-                std::swap(iptr[j], iptr[len-1-j]);
+
+#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY
+        if (sortRows || !ippFunc || ippFunc(ptr, iptr, len) < 0)
+#endif
+        {
+            std::sort( iptr, iptr + len, LessThanIdx<T>(ptr) );
+            if( sortDescending )
+                for( j = 0; j < len/2; j++ )
+                    std::swap(iptr[j], iptr[len-1-j]);
+        }
+
         if( !sortRows )
             for( j = 0; j < len; j++ )
                 ((int*)(dst.data + dst.step*j))[i] = iptr[j];