Merge commit 'b51a1a7d' (PR #895 from 2.4)
authorRoman Donchenko <roman.donchenko@itseez.com>
Wed, 22 May 2013 13:21:19 +0000 (17:21 +0400)
committerRoman Donchenko <roman.donchenko@itseez.com>
Wed, 22 May 2013 14:28:28 +0000 (18:28 +0400)
Conflicts:
modules/ocl/CMakeLists.txt
modules/ocl/perf/perf_color.cpp
modules/ocl/perf/perf_match_template.cpp
modules/ocl/perf/precomp.cpp
modules/ocl/perf/precomp.hpp

1  2 
modules/ocl/perf/perf_canny.cpp
modules/ocl/perf/perf_color.cpp
modules/ocl/perf/perf_haar.cpp
modules/ocl/perf/perf_hough.cpp
modules/ocl/perf/perf_imgproc.cpp
modules/ocl/perf/perf_match_template.cpp
modules/ocl/perf/precomp.cpp
modules/ocl/perf/precomp.hpp

@@@ -45,9 -46,9 +46,9 @@@
  #include "precomp.hpp"
  
  ///////////// Canny ////////////////////////
- TEST(Canny)
PERFTEST(Canny)
  {
 -    Mat img = imread(abspath("aloeL.jpg"), CV_LOAD_IMAGE_GRAYSCALE);
 +    Mat img = imread(abspath("aloeL.jpg"), IMREAD_GRAYSCALE);
  
      if (img.empty())
      {
@@@ -69,12 -70,15 +70,15 @@@ PERFTEST(cvtColor
              d_src.upload(src);
  
              WARMUP_ON;
 -            ocl::cvtColor(d_src, d_dst, CV_RGBA2GRAY, 4);
 +            ocl::cvtColor(d_src, d_dst, COLOR_RGBA2GRAY, 4);
              WARMUP_OFF;
  
+             cv::Mat ocl_mat;
+             d_dst.download(ocl_mat);
+             TestSystem::instance().setAccurate(ExceptedMatSimilar(dst, ocl_mat, 1e-5));
              GPU_ON;
 -            ocl::cvtColor(d_src, d_dst, CV_RGBA2GRAY, 4);
 +            ocl::cvtColor(d_src, d_dst, COLOR_RGBA2GRAY, 4);
-              ;
              GPU_OFF;
  
              GPU_FULL_ON;
@@@ -88,4 -92,4 +92,4 @@@
      }
  
  
--}
++}
@@@ -84,9 -83,9 +85,9 @@@ public
  
  }
  }
- TEST(Haar)
PERFTEST(Haar)
  {
 -    Mat img = imread(abspath("basketball1.png"), CV_LOAD_IMAGE_GRAYSCALE);
 +    Mat img = imread(abspath("basketball1.png"), IMREAD_GRAYSCALE);
  
      if (img.empty())
      {
  
      GPU_FULL_ON;
      d_img.upload(img);
-     faceCascade.detectMultiScale(d_img, faces,
+     faceCascade.detectMultiScale(d_img, oclfaces,
                                   1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
      GPU_FULL_OFF;
 -}
 +}
 +
 +#endif
index d0d130e,0000000..53c7b3b
mode 100644,000000..100644
--- /dev/null
@@@ -1,98 -1,0 +1,98 @@@
-     
 +/*M///////////////////////////////////////////////////////////////////////////////////////
 +//
 +//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 +//
 +//  By downloading, copying, installing or using the software you agree to this license.
 +//  If you do not agree to this license, do not download, install,
 +//  copy or use the software.
 +//
 +//
 +//                           License Agreement
 +//                For Open Source Computer Vision Library
 +//
 +// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
 +// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
 +// Third party copyrights are property of their respective owners.
 +//
 +// Redistribution and use in source and binary forms, with or without modification,
 +// are permitted provided that the following conditions are met:
 +//
 +//   * Redistribution's of source code must retain the above copyright notice,
 +//     this list of conditions and the following disclaimer.
 +//
 +//   * Redistribution's in binary form must reproduce the above copyright notice,
 +//     this list of conditions and the following disclaimer in the documentation
 +//     and/or other oclMaterials provided with the distribution.
 +//
 +//   * The name of the copyright holders may not be used to endorse or promote products
 +//     derived from this software without specific prior written permission.
 +//
 +// This software is provided by the copyright holders and contributors as is and
 +// any express or implied warranties, including, but not limited to, the implied
 +// warranties of merchantability and fitness for a particular purpose are disclaimed.
 +// In no event shall the Intel Corporation or contributors be liable for any direct,
 +// indirect, incidental, special, exemplary, or consequential damages
 +// (including, but not limited to, procurement of substitute goods or services;
 +// loss of use, data, or profits; or business interruption) however caused
 +// and on any theory of liability, whether in contract, strict liability,
 +// or tort (including negligence or otherwise) arising in any way out of
 +// the use of this software, even if advised of the possibility of such damage.
 +//
 +//M*/
 +
 +#include "precomp.hpp"
 +
 +#ifdef HAVE_OPENCL
 +
 +using namespace cv;
 +using namespace perf;
 +
 +//////////////////////////////////////////////////////////////////////
 +// HoughCircles
 +
 +typedef std::tr1::tuple<cv::Size, float, float> Size_Dp_MinDist_t;
 +typedef perf::TestBaseWithParam<Size_Dp_MinDist_t> Size_Dp_MinDist;
 +
 +PERF_TEST_P(Size_Dp_MinDist, OCL_HoughCircles,
 +            testing::Combine(
 +                testing::Values(perf::sz720p, perf::szSXGA, perf::sz1080p),
 +                testing::Values(1.0f, 2.0f, 4.0f),
 +                testing::Values(1.0f, 10.0f)))
 +{
 +    const cv::Size size = std::tr1::get<0>(GetParam());
 +    const float dp      = std::tr1::get<1>(GetParam());
 +    const float minDist = std::tr1::get<2>(GetParam());
 +
 +    const int minRadius = 10;
 +    const int maxRadius = 30;
 +    const int cannyThreshold = 100;
 +    const int votesThreshold = 15;
 +
 +    cv::RNG rng(123456789);
 +
 +    cv::Mat src(size, CV_8UC1, cv::Scalar::all(0));
 +
 +    const int numCircles = rng.uniform(50, 100);
 +    for (int i = 0; i < numCircles; ++i)
 +    {
 +        cv::Point center(rng.uniform(0, src.cols), rng.uniform(0, src.rows));
 +        const int radius = rng.uniform(minRadius, maxRadius + 1);
 +
 +        cv::circle(src, center, radius, cv::Scalar::all(255), -1);
 +    }
-     
++
 +    cv::ocl::oclMat ocl_src(src);
 +    cv::ocl::oclMat ocl_circles;
 +
 +    declare.time(10.0).iterations(25);
-         cv::ocl::HoughCircles(ocl_src, ocl_circles, CV_HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius);
++
 +    TEST_CYCLE()
 +    {
-     
-     cv::Mat circles(ocl_circles);    
++        cv::ocl::HoughCircles(ocl_src, ocl_circles, HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius);
 +    }
++
++    cv::Mat circles(ocl_circles);
 +    SANITY_CHECK(circles);
 +}
 +
 +#endif // HAVE_OPENCL
@@@ -522,9 -543,189 +543,189 @@@ PERFTEST(threshold
      }
  }
  ///////////// meanShiftFiltering////////////////////////
- TEST(meanShiftFiltering)
+ COOR do_meanShift(int x0, int y0, uchar *sptr, uchar *dptr, int sstep, cv::Size size, int sp, int sr, int maxIter, float eps, int *tab)
+ {
+     int isr2 = sr * sr;
+     int c0, c1, c2, c3;
+     int iter;
+     uchar *ptr = NULL;
+     uchar *pstart = NULL;
+     int revx = 0, revy = 0;
+     c0 = sptr[0];
+     c1 = sptr[1];
+     c2 = sptr[2];
+     c3 = sptr[3];
+     // iterate meanshift procedure
+     for(iter = 0; iter < maxIter; iter++ )
+     {
+         int count = 0;
+         int s0 = 0, s1 = 0, s2 = 0, sx = 0, sy = 0;
+         //mean shift: process pixels in window (p-sigmaSp)x(p+sigmaSp)
+         int minx = x0 - sp;
+         int miny = y0 - sp;
+         int maxx = x0 + sp;
+         int maxy = y0 + sp;
+         //deal with the image boundary
+         if(minx < 0) minx = 0;
+         if(miny < 0) miny = 0;
+         if(maxx >= size.width) maxx = size.width - 1;
+         if(maxy >= size.height) maxy = size.height - 1;
+         if(iter == 0)
+         {
+             pstart = sptr;
+         }
+         else
+         {
+             pstart = pstart + revy * sstep + (revx << 2); //point to the new position
+         }
+         ptr = pstart;
+         ptr = ptr + (miny - y0) * sstep + ((minx - x0) << 2); //point to the start in the row
+         for( int y = miny; y <= maxy; y++, ptr += sstep - ((maxx - minx + 1) << 2))
+         {
+             int rowCount = 0;
+             int x = minx;
+ #if CV_ENABLE_UNROLLED
+             for( ; x + 4 <= maxx; x += 4, ptr += 16)
+             {
+                 int t0, t1, t2;
+                 t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
+                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
+                 {
+                     s0 += t0;
+                     s1 += t1;
+                     s2 += t2;
+                     sx += x;
+                     rowCount++;
+                 }
+                 t0 = ptr[4], t1 = ptr[5], t2 = ptr[6];
+                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
+                 {
+                     s0 += t0;
+                     s1 += t1;
+                     s2 += t2;
+                     sx += x + 1;
+                     rowCount++;
+                 }
+                 t0 = ptr[8], t1 = ptr[9], t2 = ptr[10];
+                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
+                 {
+                     s0 += t0;
+                     s1 += t1;
+                     s2 += t2;
+                     sx += x + 2;
+                     rowCount++;
+                 }
+                 t0 = ptr[12], t1 = ptr[13], t2 = ptr[14];
+                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
+                 {
+                     s0 += t0;
+                     s1 += t1;
+                     s2 += t2;
+                     sx += x + 3;
+                     rowCount++;
+                 }
+             }
+ #endif
+             for(; x <= maxx; x++, ptr += 4)
+             {
+                 int t0 = ptr[0], t1 = ptr[1], t2 = ptr[2];
+                 if(tab[t0 - c0 + 255] + tab[t1 - c1 + 255] + tab[t2 - c2 + 255] <= isr2)
+                 {
+                     s0 += t0;
+                     s1 += t1;
+                     s2 += t2;
+                     sx += x;
+                     rowCount++;
+                 }
+             }
+             if(rowCount == 0)
+                 continue;
+             count += rowCount;
+             sy += y * rowCount;
+         }
+         if( count == 0 )
+             break;
+         int x1 = sx / count;
+         int y1 = sy / count;
+         s0 = s0 / count;
+         s1 = s1 / count;
+         s2 = s2 / count;
+         bool stopFlag = (x0 == x1 && y0 == y1) || (abs(x1 - x0) + abs(y1 - y0) +
+             tab[s0 - c0 + 255] + tab[s1 - c1 + 255] + tab[s2 - c2 + 255] <= eps);
+         //revise the pointer corresponding to the new (y0,x0)
+         revx = x1 - x0;
+         revy = y1 - y0;
+         x0 = x1;
+         y0 = y1;
+         c0 = s0;
+         c1 = s1;
+         c2 = s2;
+         if( stopFlag )
+             break;
+     } //for iter
+     dptr[0] = (uchar)c0;
+     dptr[1] = (uchar)c1;
+     dptr[2] = (uchar)c2;
+     dptr[3] = (uchar)c3;
+     COOR coor;
+     coor.x = static_cast<short>(x0);
+     coor.y = static_cast<short>(y0);
+     return coor;
+ }
+ void meanShiftFiltering_(const Mat &src_roi, Mat &dst_roi, int sp, int sr, cv::TermCriteria crit);
+ void meanShiftFiltering_(const Mat &src_roi, Mat &dst_roi, int sp, int sr, cv::TermCriteria crit)
+ {
+     if( src_roi.empty() )
 -        CV_Error( CV_StsBadArg, "The input image is empty" );
++        CV_Error( Error::StsBadArg, "The input image is empty" );
+     if( src_roi.depth() != CV_8U || src_roi.channels() != 4 )
 -        CV_Error( CV_StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
++        CV_Error( Error::StsUnsupportedFormat, "Only 8-bit, 4-channel images are supported" );
+     CV_Assert( (src_roi.cols == dst_roi.cols) && (src_roi.rows == dst_roi.rows) );
+     CV_Assert( !(dst_roi.step & 0x3) );
+     if( !(crit.type & cv::TermCriteria::MAX_ITER) )
+         crit.maxCount = 5;
+     int maxIter = std::min(std::max(crit.maxCount, 1), 100);
+     float eps;
+     if( !(crit.type & cv::TermCriteria::EPS) )
+         eps = 1.f;
+     eps = (float)std::max(crit.epsilon, 0.0);
+     int tab[512];
+     for(int i = 0; i < 512; i++)
+         tab[i] = (i - 255) * (i - 255);
+     uchar *sptr = src_roi.data;
+     uchar *dptr = dst_roi.data;
+     int sstep = (int)src_roi.step;
+     int dstep = (int)dst_roi.step;
+     cv::Size size = src_roi.size();
+     for(int i = 0; i < size.height; i++, sptr += sstep - (size.width << 2),
+         dptr += dstep - (size.width << 2))
+     {
+         for(int j = 0; j < size.width; j++, sptr += 4, dptr += 4)
+         {
+             do_meanShift(j, i, sptr, dptr, sstep, size, sp, sr, maxIter, eps, tab);
+         }
+     }
+ }
+ PERFTEST(meanShiftFiltering)
  {
-     int sp = 10, sr = 10;
+     int sp = 5, sr = 6;
      Mat src, dst;
  
      ocl::oclMat d_src, d_dst;
@@@ -892,9 -1104,14 +1104,14 @@@ PERFTEST(remap
              ocl::remap(d_src, d_dst, d_xmap, d_ymap, interpolation, borderMode);
              WARMUP_OFF;
  
 -                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), 1.0));            
+             if(interpolation == 0)
++                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), 1.0));
+             else
+                 TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), 2.0));
              GPU_ON;
              ocl::remap(d_src, d_dst, d_xmap, d_ymap, interpolation, borderMode);
-              ;
              GPU_OFF;
  
              GPU_FULL_ON;
          }
  
      }
--}
++}
@@@ -86,12 -87,13 +87,13 @@@ PERFTEST(matchTemplate
                  d_templ.upload(templ);
  
                  WARMUP_ON;
 -                ocl::matchTemplate(d_src, d_templ, d_dst, CV_TM_CCORR);
 +                ocl::matchTemplate(d_src, d_templ, d_dst, TM_CCORR);
                  WARMUP_OFF;
  
 -                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), templ.rows * templ.cols * 1e-1));            
++                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), templ.rows * templ.cols * 1e-1));
                  GPU_ON;
 -                ocl::matchTemplate(d_src, d_templ, d_dst, CV_TM_CCORR);
 +                ocl::matchTemplate(d_src, d_templ, d_dst, TM_CCORR);
-                  ;
                  GPU_OFF;
  
                  GPU_FULL_ON;
                  ocl::oclMat d_templ(templ), d_dst;
  
                  WARMUP_ON;
 -                ocl::matchTemplate(d_src, d_templ, d_dst, CV_TM_CCORR_NORMED);
 +                ocl::matchTemplate(d_src, d_templ, d_dst, TM_CCORR_NORMED);
                  WARMUP_OFF;
  
 -                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), templ.rows * templ.cols * 1e-1));            
++                TestSystem::instance().setAccurate(ExpectedMatNear(dst, cv::Mat(d_dst), templ.rows * templ.cols * 1e-1));
                  GPU_ON;
 -                ocl::matchTemplate(d_src, d_templ, d_dst, CV_TM_CCORR_NORMED);
 +                ocl::matchTemplate(d_src, d_templ, d_dst, TM_CCORR_NORMED);
-                  ;
                  GPU_OFF;
  
                  GPU_FULL_ON;
              }
          }
      }
--}
++}
@@@ -252,11 -271,39 +271,39 @@@ void TestSystem::printSummary(
  }
  
  
- void TestSystem::printMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup)
+ enum GTestColor {
+     COLOR_DEFAULT,
+     COLOR_RED,
+     COLOR_GREEN,
+     COLOR_YELLOW
+ };
+ #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
+ // Returns the character attribute for the given color.
+ WORD GetColorAttribute(GTestColor color) {
+     switch (color) {
+     case COLOR_RED:    return FOREGROUND_RED;
+     case COLOR_GREEN:  return FOREGROUND_GREEN;
+     case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+     default:           return 0;
+     }
+ }
+ #else
+ static const char* GetAnsiColorCode(GTestColor color) {
+     switch (color) {
+     case COLOR_RED:     return "1";
+     case COLOR_GREEN:   return "2";
+     case COLOR_YELLOW:  return "3";
+     default:            return NULL;
+     };
+ }
+ #endif
+ static void printMetricsUti(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, std::stringstream& stream, std::stringstream& cur_subtest_description)
  {
-     cout << TAB << setiosflags(ios_base::left);
-     stringstream stream;
 -    //cout <<TAB<< setw(7) << stream.str(); 
 -    cout <<TAB; 
++    //cout <<TAB<< setw(7) << stream.str();
++    cout <<TAB;
  
+     stream.str("");
      stream << cpu_time;
      cout << setw(10) << stream.str();
  
      cout << resetiosflags(ios_base::left) << endl;
  }
  
- void TestSystem::writeMetrics(double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, double gpu_min, double gpu_max, double std_dev)
+ void TestSystem::printMetrics(int is_accurate, double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup)
+ {
+     cout << setiosflags(ios_base::left);
+     stringstream stream;
+ #if 0
+     if(is_accurate == 1)
+             stream << "Pass";
+     else if(is_accurate_ == 0)
+             stream << "Fail";
+     else if(is_accurate == -1)
+         stream << " ";
+     else
+     {
+         std::cout<<"is_accurate errer: "<<is_accurate<<"\n";
+         exit(-1);
+     }
+ #endif
+     std::stringstream &cur_subtest_description = getCurSubtestDescription();
 -   
++
+ #if GTEST_OS_WINDOWS&&!GTEST_OS_WINDOWS_MOBILE
 -    
++
+     WORD color;
+     const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+     // Gets the current text color.
+     CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+     GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
+     const WORD old_color_attrs = buffer_info.wAttributes;
+     // We need to flush the stream buffers into the console before each
+     // SetConsoleTextAttribute call lest it affect the text that is already
+     // printed but has not yet reached the console.
+     fflush(stdout);
+     if(is_accurate == 1||is_accurate == -1)
+     {
+         color = old_color_attrs;
+         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
+     }else
+     {
+         color = GetColorAttribute(COLOR_RED);
+         SetConsoleTextAttribute(stdout_handle,
+             color| FOREGROUND_INTENSITY);
+         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
+         fflush(stdout);
+         // Restores the text color.
+         SetConsoleTextAttribute(stdout_handle, old_color_attrs);
+     }
+ #else
+     GTestColor color = COLOR_RED;
+     if(is_accurate == 1|| is_accurate == -1)
+     {
+         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
+     }else
+     {
+         printf("\033[0;3%sm", GetAnsiColorCode(color));
+         printMetricsUti(cpu_time, gpu_time, gpu_full_time, speedup, fullspeedup, stream, cur_subtest_description);
+         printf("\033[m");  // Resets the terminal to default.
+     }
+ #endif
+ }
+ void TestSystem::writeMetrics(int is_accurate, double cpu_time, double gpu_time, double gpu_full_time, double speedup, double fullspeedup, double gpu_min, double gpu_max, double std_dev)
  {
      if (!record_)
      {
@@@ -349,3 -602,60 +602,48 @@@ string abspath(const string &relpath
  {
      return TestSystem::instance().workingDir() + relpath;
  }
 -
 -int CV_CDECL cvErrorCallback(int /*status*/, const char * /*func_name*/,
 -    const char *err_msg, const char * /*file_name*/,
 -    int /*line*/, void * /*userdata*/)
 -{
 -    TestSystem::instance().printError(err_msg);
 -    return 0;
 -}
 -
 -    matchTemplate(m1, m2, diff, CV_TM_CCORR_NORMED);
+ double checkNorm(const Mat &m)
+ {
+     return norm(m, NORM_INF);
+ }
+ double checkNorm(const Mat &m1, const Mat &m2)
+ {
+     return norm(m1, m2, NORM_INF);
+ }
+ double checkSimilarity(const Mat &m1, const Mat &m2)
+ {
+     Mat diff;
 -    assert(dst.size() == cpu_dst.size()); 
++    matchTemplate(m1, m2, diff, TM_CCORR_NORMED);
+     return std::abs(diff.at<float>(0, 0) - 1.f);
+ }
+ int ExpectedMatNear(cv::Mat dst, cv::Mat cpu_dst, double eps)
+ {
+     assert(dst.type() == cpu_dst.type());
+     assert(dst.size() == cpu_dst.size());
+     if(checkNorm(cv::Mat(dst), cv::Mat(cpu_dst)) < eps ||checkNorm(cv::Mat(dst), cv::Mat(cpu_dst)) == eps)
+         return 1;
+     return 0;
+ }
+ int ExceptDoubleNear(double val1, double val2, double abs_error)
+ {
+     const double diff = fabs(val1 - val2);
+     if (diff <= abs_error)
+         return 1;
+     return 0;
+ }
+ int ExceptedMatSimilar(cv::Mat dst, cv::Mat cpu_dst, double eps)
+ {
+     assert(dst.type() == cpu_dst.type());
 -
 -
 -
++    assert(dst.size() == cpu_dst.size());
+     if(checkSimilarity(cv::Mat(cpu_dst), cv::Mat(dst)) <= eps)
+         return 1;
+     return 0;
+ }
  //
  //M*/
  
++#ifdef __GNUC__
++#  pragma GCC diagnostic ignored "-Wmissing-declarations"
++#  if defined __clang__ || defined __APPLE__
++#    pragma GCC diagnostic ignored "-Wmissing-prototypes"
++#    pragma GCC diagnostic ignored "-Wextra"
++#  endif
++#endif
++
  #include <iomanip>
  #include <stdexcept>
  #include <string>
  #include <cstdio>
  #include <vector>
  #include <numeric>
 -#include "opencv2/core/core.hpp"
 -#include "opencv2/imgproc/imgproc.hpp"
 -#include "opencv2/highgui/highgui.hpp"
 -#include "opencv2/calib3d/calib3d.hpp"
 -#include "opencv2/video/video.hpp"
 -#include "opencv2/objdetect/objdetect.hpp"
 -#include "opencv2/features2d/features2d.hpp"
 -#include "opencv2/ocl/ocl.hpp"
 -#include "opencv2/ts/ts.hpp"
 +#include "opencv2/core.hpp"
 +#include "opencv2/imgproc.hpp"
 +#include "opencv2/highgui.hpp"
++#include "opencv2/calib3d.hpp"
 +#include "opencv2/video.hpp"
 +#include "opencv2/objdetect.hpp"
 +#include "opencv2/features2d.hpp"
 +#include "opencv2/ocl.hpp"
++#include "opencv2/ts.hpp"
+ #include "opencv2/ts/ts_perf.hpp"
+ #include "opencv2/ts/ts_gtest.h"
  
 +#include "opencv2/core/utility.hpp"
  
  #define Min_Size 1000
  #define Max_Size 4000
@@@ -66,8 -69,10 +78,10 @@@ using namespace std
  using namespace cv;
  
  void gen(Mat &mat, int rows, int cols, int type, Scalar low, Scalar high);
+ void gen(Mat &mat, int rows, int cols, int type, int low, int high, int n);
  string abspath(const string &relpath);
 -int CV_CDECL cvErrorCallback(int, const char *, const char *, const char *, int, void *);
 +
  typedef struct
  {
      short x;
@@@ -78,6 -83,50 +92,50 @@@ COOR do_meanShift(int x0, int y0, ucha
  void meanShiftProc_(const Mat &src_roi, Mat &dst_roi, Mat &dstCoor_roi,
                      int sp, int sr, cv::TermCriteria crit);
  
 -    if (lhs.AlmostEquals(rhs)) 
+ template<class T1, class T2>
+ int ExpectedEQ(T1 expected, T2 actual)
+ {
+     if(expected == actual)
+         return 1;
+     return 0;
+ }
+ template<class T1>
+ int EeceptDoubleEQ(T1 expected, T1 actual)
+ {
+     testing::internal::Double lhs(expected);
+     testing::internal::Double rhs(actual);
++    if (lhs.AlmostEquals(rhs))
+     {
+         return 1;
+     }
+     return 0;
+ }
+ template<class T>
+ int AssertEQ(T expected, T actual)
+ {
+     if(expected == actual)
+     {
+         return 1;
+     }
+     return 0;
+ }
+ int ExceptDoubleNear(double val1, double val2, double abs_error);
+ bool match_rect(cv::Rect r1, cv::Rect r2, int threshold);
+ double checkNorm(const cv::Mat &m);
+ double checkNorm(const cv::Mat &m1, const cv::Mat &m2);
+ double checkSimilarity(const cv::Mat &m1, const cv::Mat &m2);
+ int ExpectedMatNear(cv::Mat dst, cv::Mat cpu_dst, double eps);
+ int ExceptedMatSimilar(cv::Mat dst, cv::Mat cpu_dst, double eps);
  class Runnable
  {
  public:
@@@ -263,7 -332,8 +341,8 @@@ private
          speedup_full_faster_count_(0), speedup_full_slower_count_(0), speedup_full_equal_count_(0), is_list_mode_(false),
          num_iters_(10), cpu_num_iters_(2),
          gpu_warmup_iters_(1), cur_iter_idx_(0), cur_warmup_idx_(0),
-         record_(0), recordname_("performance"), itname_changed_(true)
 -        record_(0), recordname_("performance"), itname_changed_(true), 
++        record_(0), recordname_("performance"), itname_changed_(true),
+         is_accurate_(-1)
      {
          cpu_times_.reserve(num_iters_);
          gpu_times_.reserve(num_iters_);
  
  #define GLOBAL_INIT(name) \
  struct name##_init: Runnable { \
 -      name##_init(): Runnable(#name) { \
 -      TestSystem::instance().addInit(this); \
 +    name##_init(): Runnable(#name) { \
 +    TestSystem::instance().addInit(this); \
  } \
 -      void run(); \
 +    void run(); \
  } name##_init_instance; \
 -      void name##_init::run()
 +    void name##_init::run()
  
  
- #define TEST(name) \
+ #define PERFTEST(name) \
  struct name##_test: Runnable { \
 -      name##_test(): Runnable(#name) { \
 -      TestSystem::instance().addTest(this); \
 +    name##_test(): Runnable(#name) { \
 +    TestSystem::instance().addTest(this); \
  } \
 -      void run(); \
 +    void run(); \
  } name##_test_instance; \
 -      void name##_test::run()
 +    void name##_test::run()
  
  #define SUBTEST TestSystem::instance().startNewSubtest()