From 2c198f6cd6802ebfc8d7216f2b06b7c7fb42f6b9 Mon Sep 17 00:00:00 2001 From: yao Date: Wed, 19 Jun 2013 13:03:35 +0800 Subject: [PATCH] revise accuracy and perf tests --- modules/ocl/perf/main.cpp | 2 + .../perf_calib3d.cpp} | 85 ++++--- modules/ocl/perf/perf_filters.cpp | 16 +- modules/ocl/perf/perf_hog.cpp | 76 +----- modules/ocl/perf/perf_imgproc.cpp | 46 +++- .../{perf_columnsum.cpp => perf_moments.cpp} | 62 ++--- modules/ocl/perf/precomp.cpp | 14 -- modules/ocl/test/test_haar.cpp | 180 -------------- modules/ocl/test/test_imgproc.cpp | 46 +++- .../test/{test_hog.cpp => test_objdetect.cpp} | 231 ++++++++++-------- .../{test_pyrdown.cpp => test_pyramids.cpp} | 44 +++- modules/ocl/test/test_pyrup.cpp | 91 ------- modules/ocl/test/utility.cpp | 102 ++++---- modules/ocl/test/utility.hpp | 11 +- 14 files changed, 392 insertions(+), 614 deletions(-) rename modules/ocl/{test/test_columnsum.cpp => perf/perf_calib3d.cpp} (65%) rename modules/ocl/perf/{perf_columnsum.cpp => perf_moments.cpp} (68%) delete mode 100644 modules/ocl/test/test_haar.cpp rename modules/ocl/test/{test_hog.cpp => test_objdetect.cpp} (51%) rename modules/ocl/test/{test_pyrdown.cpp => test_pyramids.cpp} (75%) delete mode 100644 modules/ocl/test/test_pyrup.cpp diff --git a/modules/ocl/perf/main.cpp b/modules/ocl/perf/main.cpp index 2da17755e..dfcac20bc 100644 --- a/modules/ocl/perf/main.cpp +++ b/modules/ocl/perf/main.cpp @@ -52,6 +52,8 @@ int main(int argc, const char *argv[]) cerr << "no device found\n"; return -1; } + // set this to overwrite binary cache every time the test starts + ocl::setBinaryDiskCache(ocl::CACHE_UPDATE); int devidx = 0; diff --git a/modules/ocl/test/test_columnsum.cpp b/modules/ocl/perf/perf_calib3d.cpp similarity index 65% rename from modules/ocl/test/test_columnsum.cpp rename to modules/ocl/perf/perf_calib3d.cpp index 231f0657b..f998ddf0f 100644 --- a/modules/ocl/test/test_columnsum.cpp +++ b/modules/ocl/perf/perf_calib3d.cpp @@ -15,8 +15,8 @@ // Third party copyrights are property of their respective owners. // // @Authors -// Chunpeng Zhang chunpeng@multicorewareinc.com -// +// Fangfang Bai, fangfang@multicorewareinc.com +// Jin Ma, jin@multicorewareinc.com // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ // * 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 +// 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, @@ -45,50 +45,57 @@ //M*/ #include "precomp.hpp" -#include - -#ifdef HAVE_OPENCL - -PARAM_TEST_CASE(ColumnSum, cv::Size) +///////////// StereoMatchBM //////////////////////// +PERFTEST(StereoMatchBM) { - cv::Size size; - cv::Mat src; + Mat left_image = imread(abspath("aloeL.jpg"), cv::IMREAD_GRAYSCALE); + Mat right_image = imread(abspath("aloeR.jpg"), cv::IMREAD_GRAYSCALE); + Mat disp,dst; + ocl::oclMat d_left, d_right,d_disp; + int n_disp= 128; + int winSize =19; - virtual void SetUp() - { - size = GET_PARAM(0); - } -}; + SUBTEST << left_image.cols << 'x' << left_image.rows << "; aloeL.jpg ;"<< right_image.cols << 'x' << right_image.rows << "; aloeR.jpg "; -TEST_P(ColumnSum, Accuracy) -{ - cv::Mat src = randomMat(size, CV_32FC1); - cv::ocl::oclMat d_dst; - cv::ocl::oclMat d_src(src); + StereoBM bm(0, n_disp, winSize); + bm(left_image, right_image, dst); - cv::ocl::columnSum(d_src, d_dst); + CPU_ON; + bm(left_image, right_image, dst); + CPU_OFF; - cv::Mat dst(d_dst); + d_left.upload(left_image); + d_right.upload(right_image); - for (int j = 0; j < src.cols; ++j) - { - float gold = src.at(0, j); - float res = dst.at(0, j); - ASSERT_NEAR(res, gold, 1e-5); - } + ocl::StereoBM_OCL d_bm(0, n_disp, winSize); - for (int i = 1; i < src.rows; ++i) - { - for (int j = 0; j < src.cols; ++j) - { - float gold = src.at(i, j) += src.at(i - 1, j); - float res = dst.at(i, j); - ASSERT_NEAR(res, gold, 1e-5); - } - } + WARMUP_ON; + d_bm(d_left, d_right, d_disp); + WARMUP_OFF; + + cv::Mat ocl_mat; + d_disp.download(ocl_mat); + ocl_mat.convertTo(ocl_mat, dst.type()); + + GPU_ON; + d_bm(d_left, d_right, d_disp); + GPU_OFF; + + GPU_FULL_ON; + d_left.upload(left_image); + d_right.upload(right_image); + d_bm(d_left, d_right, d_disp); + d_disp.download(disp); + GPU_FULL_OFF; + + TestSystem::instance().setAccurate(-1, 0.); } -INSTANTIATE_TEST_CASE_P(OCL_ImgProc, ColumnSum, DIFFERENT_SIZES); -#endif + + + + + + \ No newline at end of file diff --git a/modules/ocl/perf/perf_filters.cpp b/modules/ocl/perf/perf_filters.cpp index a05301b34..e988ce09d 100644 --- a/modules/ocl/perf/perf_filters.cpp +++ b/modules/ocl/perf/perf_filters.cpp @@ -284,6 +284,7 @@ PERFTEST(GaussianBlur) Mat src, dst, ocl_dst; int all_type[] = {CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4}; std::string type_name[] = {"CV_8UC1", "CV_8UC4", "CV_32FC1", "CV_32FC4"}; + const int ksize = 7; for (int size = Min_Size; size <= Max_Size; size *= Multiple) { @@ -291,29 +292,28 @@ PERFTEST(GaussianBlur) { SUBTEST << size << 'x' << size << "; " << type_name[j] ; - gen(src, size, size, all_type[j], 5, 16); + gen(src, size, size, all_type[j], 0, 256); - GaussianBlur(src, dst, Size(9, 9), 0); + GaussianBlur(src, dst, Size(ksize, ksize), 0); CPU_ON; - GaussianBlur(src, dst, Size(9, 9), 0); + GaussianBlur(src, dst, Size(ksize, ksize), 0); CPU_OFF; ocl::oclMat d_src(src); - ocl::oclMat d_dst(src.size(), src.type()); - ocl::oclMat d_buf; + ocl::oclMat d_dst; WARMUP_ON; - ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0); + ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0); WARMUP_OFF; GPU_ON; - ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0); + ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0); GPU_OFF; GPU_FULL_ON; d_src.upload(src); - ocl::GaussianBlur(d_src, d_dst, Size(9, 9), 0); + ocl::GaussianBlur(d_src, d_dst, Size(ksize, ksize), 0); d_dst.download(ocl_dst); GPU_FULL_OFF; diff --git a/modules/ocl/perf/perf_hog.cpp b/modules/ocl/perf/perf_hog.cpp index 05093811f..7daa61396 100644 --- a/modules/ocl/perf/perf_hog.cpp +++ b/modules/ocl/perf/perf_hog.cpp @@ -46,11 +46,6 @@ #include "precomp.hpp" ///////////// HOG//////////////////////// -bool match_rect(cv::Rect r1, cv::Rect r2, int threshold) -{ - return ((abs(r1.x - r2.x) < threshold) && (abs(r1.y - r2.y) < threshold) && - (abs(r1.width - r2.width) < threshold) && (abs(r1.height - r2.height) < threshold)); -} PERFTEST(HOG) { @@ -61,13 +56,12 @@ PERFTEST(HOG) throw runtime_error("can't open road.png"); } - cv::HOGDescriptor hog; hog.setSVMDetector(hog.getDefaultPeopleDetector()); std::vector found_locations; std::vector d_found_locations; - SUBTEST << 768 << 'x' << 576 << "; road.png"; + SUBTEST << src.cols << 'x' << src.rows << "; road.png"; hog.detectMultiScale(src, found_locations); @@ -84,70 +78,10 @@ PERFTEST(HOG) ocl_hog.detectMultiScale(d_src, d_found_locations); WARMUP_OFF; - // Ground-truth rectangular people window - cv::Rect win1_64x128(231, 190, 72, 144); - cv::Rect win2_64x128(621, 156, 97, 194); - cv::Rect win1_48x96(238, 198, 63, 126); - cv::Rect win2_48x96(619, 161, 92, 185); - cv::Rect win3_48x96(488, 136, 56, 112); - - // Compare whether ground-truth windows are detected and compare the number of windows detected. - std::vector d_comp(4); - std::vector comp(4); - for(int i = 0; i < (int)d_comp.size(); i++) - { - d_comp[i] = 0; - comp[i] = 0; - } - - int threshold = 10; - int val = 32; - d_comp[0] = (int)d_found_locations.size(); - comp[0] = (int)found_locations.size(); - - cv::Size winSize = hog.winSize; - - if (winSize == cv::Size(48, 96)) - { - for(int i = 0; i < (int)d_found_locations.size(); i++) - { - if (match_rect(d_found_locations[i], win1_48x96, threshold)) - d_comp[1] = val; - if (match_rect(d_found_locations[i], win2_48x96, threshold)) - d_comp[2] = val; - if (match_rect(d_found_locations[i], win3_48x96, threshold)) - d_comp[3] = val; - } - for(int i = 0; i < (int)found_locations.size(); i++) - { - if (match_rect(found_locations[i], win1_48x96, threshold)) - comp[1] = val; - if (match_rect(found_locations[i], win2_48x96, threshold)) - comp[2] = val; - if (match_rect(found_locations[i], win3_48x96, threshold)) - comp[3] = val; - } - } - else if (winSize == cv::Size(64, 128)) - { - for(int i = 0; i < (int)d_found_locations.size(); i++) - { - if (match_rect(d_found_locations[i], win1_64x128, threshold)) - d_comp[1] = val; - if (match_rect(d_found_locations[i], win2_64x128, threshold)) - d_comp[2] = val; - } - for(int i = 0; i < (int)found_locations.size(); i++) - { - if (match_rect(found_locations[i], win1_64x128, threshold)) - comp[1] = val; - if (match_rect(found_locations[i], win2_64x128, threshold)) - comp[2] = val; - } - } - - cv::Mat gpu_rst(d_comp), cpu_rst(comp); - TestSystem::instance().ExpectedMatNear(gpu_rst, cpu_rst, 3); + if(d_found_locations.size() == found_locations.size()) + TestSystem::instance().setAccurate(1, 0); + else + TestSystem::instance().setAccurate(0, abs((int)found_locations.size() - (int)d_found_locations.size())); GPU_ON; ocl_hog.detectMultiScale(d_src, found_locations); diff --git a/modules/ocl/perf/perf_imgproc.cpp b/modules/ocl/perf/perf_imgproc.cpp index e87e8213d..b330c5ffa 100644 --- a/modules/ocl/perf/perf_imgproc.cpp +++ b/modules/ocl/perf/perf_imgproc.cpp @@ -743,12 +743,12 @@ PERFTEST(meanShiftFiltering) WARMUP_OFF; GPU_ON; - ocl::meanShiftFiltering(d_src, d_dst, sp, sr); + ocl::meanShiftFiltering(d_src, d_dst, sp, sr, crit); GPU_OFF; GPU_FULL_ON; d_src.upload(src); - ocl::meanShiftFiltering(d_src, d_dst, sp, sr); + ocl::meanShiftFiltering(d_src, d_dst, sp, sr, crit); d_dst.download(ocl_dst); GPU_FULL_OFF; @@ -969,3 +969,45 @@ PERFTEST(CLAHE) } } } + +///////////// columnSum//////////////////////// +PERFTEST(columnSum) +{ + Mat src, dst, ocl_dst; + ocl::oclMat d_src, d_dst; + + for (int size = Min_Size; size <= Max_Size; size *= Multiple) + { + SUBTEST << size << 'x' << size << "; CV_32FC1"; + + gen(src, size, size, CV_32FC1, 0, 256); + + CPU_ON; + dst.create(src.size(), src.type()); + for (int j = 0; j < src.cols; j++) + dst.at(0, j) = src.at(0, j); + + for (int i = 1; i < src.rows; ++i) + for (int j = 0; j < src.cols; ++j) + dst.at(i, j) = dst.at(i - 1 , j) + src.at(i , j); + CPU_OFF; + + d_src.upload(src); + + WARMUP_ON; + ocl::columnSum(d_src, d_dst); + WARMUP_OFF; + + GPU_ON; + ocl::columnSum(d_src, d_dst); + GPU_OFF; + + GPU_FULL_ON; + d_src.upload(src); + ocl::columnSum(d_src, d_dst); + d_dst.download(ocl_dst); + GPU_FULL_OFF; + + TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 5e-1); + } +} diff --git a/modules/ocl/perf/perf_columnsum.cpp b/modules/ocl/perf/perf_moments.cpp similarity index 68% rename from modules/ocl/perf/perf_columnsum.cpp rename to modules/ocl/perf/perf_moments.cpp index ff7ebcd1d..7fa3948de 100644 --- a/modules/ocl/perf/perf_columnsum.cpp +++ b/modules/ocl/perf/perf_moments.cpp @@ -44,45 +44,49 @@ // //M*/ #include "precomp.hpp" - -///////////// columnSum//////////////////////// -PERFTEST(columnSum) +///////////// Moments //////////////////////// +PERFTEST(Moments) { - Mat src, dst, ocl_dst; - ocl::oclMat d_src, d_dst; + Mat src; + bool binaryImage = 0; + + int all_type[] = {CV_8UC1, CV_16SC1, CV_32FC1, CV_64FC1}; + std::string type_name[] = {"CV_8UC1", "CV_16SC1", "CV_32FC1", "CV_64FC1"}; for (int size = Min_Size; size <= Max_Size; size *= Multiple) { - SUBTEST << size << 'x' << size << "; CV_32FC1"; + for (size_t j = 0; j < sizeof(all_type) / sizeof(int); j++) + { + SUBTEST << size << 'x' << size << "; " << type_name[j]; - gen(src, size, size, CV_32FC1, 0, 256); + gen(src, size, size, all_type[j], 0, 256); - CPU_ON; - dst.create(src.size(), src.type()); - for (int j = 0; j < src.cols; j++) - dst.at(0, j) = src.at(0, j); + cv::Moments CvMom = moments(src, binaryImage); - for (int i = 1; i < src.rows; ++i) - for (int j = 0; j < src.cols; ++j) - dst.at(i, j) = dst.at(i - 1 , j) + src.at(i , j); - CPU_OFF; + CPU_ON; + moments(src, binaryImage); + CPU_OFF; - d_src.upload(src); + cv::Moments oclMom; + WARMUP_ON; + oclMom = ocl::ocl_moments(src, binaryImage); + WARMUP_OFF; - WARMUP_ON; - ocl::columnSum(d_src, d_dst); - WARMUP_OFF; + Mat gpu_dst, cpu_dst; + HuMoments(CvMom, cpu_dst); + HuMoments(oclMom, gpu_dst); - GPU_ON; - ocl::columnSum(d_src, d_dst); - GPU_OFF; + GPU_ON; + ocl::ocl_moments(src, binaryImage); + GPU_OFF; - GPU_FULL_ON; - d_src.upload(src); - ocl::columnSum(d_src, d_dst); - d_dst.download(ocl_dst); - GPU_FULL_OFF; + GPU_FULL_ON; + ocl::ocl_moments(src, binaryImage); + GPU_FULL_OFF; + + TestSystem::instance().ExpectedMatNear(gpu_dst, cpu_dst, .5); + + } - TestSystem::instance().ExpectedMatNear(dst, ocl_dst, 5e-1); } -} \ No newline at end of file +} diff --git a/modules/ocl/perf/precomp.cpp b/modules/ocl/perf/precomp.cpp index 71a13a1ee..9fc634290 100644 --- a/modules/ocl/perf/precomp.cpp +++ b/modules/ocl/perf/precomp.cpp @@ -331,20 +331,6 @@ void TestSystem::printMetrics(int is_accurate, double cpu_time, double gpu_time, 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: "< faces, oclfaces; - - Mat gray, smallImg(cvRound (img.rows / scale), cvRound(img.cols / scale), CV_8UC1 ); - MemStorage storage(cvCreateMemStorage(0)); - cvtColor( img, gray, CV_BGR2GRAY ); - resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR ); - equalizeHist( smallImg, smallImg ); - - cv::ocl::oclMat image; - CvSeq *_objects; - image.upload(smallImg); - _objects = cascade.oclHaarDetectObjects( image, storage, 1.1, - 3, flags, Size(30, 30), Size(0, 0) ); - vector vecAvgComp; - Seq(_objects).copyTo(vecAvgComp); - oclfaces.resize(vecAvgComp.size()); - std::transform(vecAvgComp.begin(), vecAvgComp.end(), oclfaces.begin(), getRect()); - - cpucascade.detectMultiScale( smallImg, faces, 1.1, 3, - flags, - Size(30, 30), Size(0, 0) ); - EXPECT_EQ(faces.size(), oclfaces.size()); -} - -TEST_P(Haar, FaceDetectUseBuf) -{ - string imgName = workdir + "lena.jpg"; - Mat img = imread( imgName, 1 ); - - if(img.empty()) - { - std::cout << "Couldn't read " << imgName << std::endl; - return ; - } - - vector faces, oclfaces; - - Mat gray, smallImg(cvRound (img.rows / scale), cvRound(img.cols / scale), CV_8UC1 ); - cvtColor( img, gray, CV_BGR2GRAY ); - resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR ); - equalizeHist( smallImg, smallImg ); - - cv::ocl::oclMat image; - image.upload(smallImg); - - cv::ocl::OclCascadeClassifierBuf cascadebuf; - if( !cascadebuf.load( cascadeName ) ) - { - cout << "ERROR: Could not load classifier cascade for FaceDetectUseBuf!" << endl; - return; - } - cascadebuf.detectMultiScale( image, oclfaces, 1.1, 3, - flags, - Size(30, 30), Size(0, 0) ); - - cpucascade.detectMultiScale( smallImg, faces, 1.1, 3, - flags, - Size(30, 30), Size(0, 0) ); - EXPECT_EQ(faces.size(), oclfaces.size()); - - // intentionally run ocl facedetect again and check if it still works after the first run - cascadebuf.detectMultiScale( image, oclfaces, 1.1, 3, - flags, - Size(30, 30)); - cascadebuf.release(); - EXPECT_EQ(faces.size(), oclfaces.size()); -} - -INSTANTIATE_TEST_CASE_P(FaceDetect, Haar, - Combine(Values(1.0), - Values(CV_HAAR_SCALE_IMAGE, 0), Values(cascade_frontalface_alt, cascade_frontalface_alt2))); - -#endif // HAVE_OPENCL diff --git a/modules/ocl/test/test_imgproc.cpp b/modules/ocl/test/test_imgproc.cpp index b9f4740b1..3a98671d5 100644 --- a/modules/ocl/test/test_imgproc.cpp +++ b/modules/ocl/test/test_imgproc.cpp @@ -1573,6 +1573,47 @@ TEST_P(Convolve, Mat) } } +//////////////////////////////// ColumnSum ////////////////////////////////////// +PARAM_TEST_CASE(ColumnSum, cv::Size) +{ + cv::Size size; + cv::Mat src; + + virtual void SetUp() + { + size = GET_PARAM(0); + } +}; + +TEST_P(ColumnSum, Accuracy) +{ + cv::Mat src = randomMat(size, CV_32FC1); + cv::ocl::oclMat d_dst; + cv::ocl::oclMat d_src(src); + + cv::ocl::columnSum(d_src, d_dst); + + cv::Mat dst(d_dst); + + for (int j = 0; j < src.cols; ++j) + { + float gold = src.at(0, j); + float res = dst.at(0, j); + ASSERT_NEAR(res, gold, 1e-5); + } + + for (int i = 1; i < src.rows; ++i) + { + for (int j = 0; j < src.cols; ++j) + { + float gold = src.at(i, j) += src.at(i - 1, j); + float res = dst.at(i, j); + ASSERT_NEAR(res, gold, 1e-5); + } + } +} +///////////////////////////////////////////////////////////////////////////////////// + INSTANTIATE_TEST_CASE_P(ImgprocTestBase, equalizeHist, Combine( ONE_TYPE(CV_8UC1), NULL_TYPE, @@ -1688,7 +1729,6 @@ INSTANTIATE_TEST_CASE_P(ImgProc, CLAHE, Combine( Values(cv::Size(128, 128), cv::Size(113, 113), cv::Size(1300, 1300)), Values(0.0, 40.0))); -//INSTANTIATE_TEST_CASE_P(ConvolveTestBase, Convolve, Combine( -// Values(CV_32FC1, CV_32FC1), -// Values(false))); // Values(false) is the reserved parameter +INSTANTIATE_TEST_CASE_P(OCL_ImgProc, ColumnSum, DIFFERENT_SIZES); + #endif // HAVE_OPENCL diff --git a/modules/ocl/test/test_hog.cpp b/modules/ocl/test/test_objdetect.cpp similarity index 51% rename from modules/ocl/test/test_hog.cpp rename to modules/ocl/test/test_objdetect.cpp index cfc4e3963..86590f798 100644 --- a/modules/ocl/test/test_hog.cpp +++ b/modules/ocl/test/test_objdetect.cpp @@ -15,7 +15,7 @@ // Third party copyrights are property of their respective owners. // // @Authors -// Wenju He, wenju@multicorewareinc.com +// Yao Wang, bitwangyaoyao@gmail.com // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -45,51 +45,58 @@ #include "precomp.hpp" #include "opencv2/core/core.hpp" -using namespace std; +#include "opencv2/objdetect/objdetect.hpp" + +using namespace cv; +using namespace testing; #ifdef HAVE_OPENCL extern string workdir; -PARAM_TEST_CASE(HOG, cv::Size, int) + +///////////////////// HOG ///////////////////////////// +PARAM_TEST_CASE(HOG, Size, int) { - cv::Size winSize; + Size winSize; int type; + Mat img_rgb; virtual void SetUp() { winSize = GET_PARAM(0); type = GET_PARAM(1); + img_rgb = readImage(workdir + "../gpu/road.png"); + if(img_rgb.empty()) + { + std::cout << "Couldn't read road.png" << std::endl; + } } }; TEST_P(HOG, GetDescriptors) { - // Load image - cv::Mat img_rgb = readImage(workdir + "lena.jpg"); - ASSERT_FALSE(img_rgb.empty()); - // Convert image - cv::Mat img; + Mat img; switch (type) { case CV_8UC1: - cv::cvtColor(img_rgb, img, CV_BGR2GRAY); + cvtColor(img_rgb, img, CV_BGR2GRAY); break; case CV_8UC4: default: - cv::cvtColor(img_rgb, img, CV_BGR2BGRA); + cvtColor(img_rgb, img, CV_BGR2BGRA); break; } - cv::ocl::oclMat d_img(img); + ocl::oclMat d_img(img); // HOGs - cv::ocl::HOGDescriptor ocl_hog; + ocl::HOGDescriptor ocl_hog; ocl_hog.gamma_correction = true; - cv::HOGDescriptor hog; + HOGDescriptor hog; hog.gammaCorrection = true; // Compute descriptor - cv::ocl::oclMat d_descriptors; + ocl::oclMat d_descriptors; ocl_hog.getDescriptors(d_img, ocl_hog.win_size, d_descriptors, ocl_hog.DESCR_FORMAT_COL_BY_COL); - cv::Mat down_descriptors; + Mat down_descriptors; d_descriptors.download(down_descriptors); down_descriptors = down_descriptors.reshape(0, down_descriptors.cols * down_descriptors.rows); @@ -105,45 +112,34 @@ TEST_P(HOG, GetDescriptors) hog.compute(img_rgb, descriptors, ocl_hog.win_size); break; } - cv::Mat cpu_descriptors(descriptors); + Mat cpu_descriptors(descriptors); EXPECT_MAT_SIMILAR(down_descriptors, cpu_descriptors, 1e-2); } - -bool match_rect(cv::Rect r1, cv::Rect r2, int threshold) -{ - return ((abs(r1.x - r2.x) < threshold) && (abs(r1.y - r2.y) < threshold) && - (abs(r1.width - r2.width) < threshold) && (abs(r1.height - r2.height) < threshold)); -} - TEST_P(HOG, Detect) { - // Load image - cv::Mat img_rgb = readImage(workdir + "lena.jpg"); - ASSERT_FALSE(img_rgb.empty()); - // Convert image - cv::Mat img; + Mat img; switch (type) { case CV_8UC1: - cv::cvtColor(img_rgb, img, CV_BGR2GRAY); + cvtColor(img_rgb, img, CV_BGR2GRAY); break; case CV_8UC4: default: - cv::cvtColor(img_rgb, img, CV_BGR2BGRA); + cvtColor(img_rgb, img, CV_BGR2BGRA); break; } - cv::ocl::oclMat d_img(img); + ocl::oclMat d_img(img); // HOGs - if ((winSize != cv::Size(48, 96)) && (winSize != cv::Size(64, 128))) - winSize = cv::Size(64, 128); - cv::ocl::HOGDescriptor ocl_hog(winSize); + if ((winSize != Size(48, 96)) && (winSize != Size(64, 128))) + winSize = Size(64, 128); + ocl::HOGDescriptor ocl_hog(winSize); ocl_hog.gamma_correction = true; - cv::HOGDescriptor hog; + HOGDescriptor hog; hog.winSize = winSize; hog.gammaCorrection = true; @@ -165,88 +161,117 @@ TEST_P(HOG, Detect) } // OpenCL detection - std::vector d_found; - ocl_hog.detectMultiScale(d_img, d_found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2); + std::vector d_found; + ocl_hog.detectMultiScale(d_img, d_found, 0, Size(8, 8), Size(0, 0), 1.05, 6); // CPU detection - std::vector found; + std::vector found; switch (type) { case CV_8UC1: - hog.detectMultiScale(img, found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2); + hog.detectMultiScale(img, found, 0, Size(8, 8), Size(0, 0), 1.05, 6); break; case CV_8UC4: default: - hog.detectMultiScale(img_rgb, found, 0, cv::Size(8, 8), cv::Size(0, 0), 1.05, 2); + hog.detectMultiScale(img_rgb, found, 0, Size(8, 8), Size(0, 0), 1.05, 6); break; } - // Ground-truth rectangular people window - cv::Rect win1_64x128(231, 190, 72, 144); - cv::Rect win2_64x128(621, 156, 97, 194); - cv::Rect win1_48x96(238, 198, 63, 126); - cv::Rect win2_48x96(619, 161, 92, 185); - cv::Rect win3_48x96(488, 136, 56, 112); - - // Compare whether ground-truth windows are detected and compare the number of windows detected. - std::vector d_comp(4); - std::vector comp(4); - for(int i = 0; i < (int)d_comp.size(); i++) - { - d_comp[i] = 0; - comp[i] = 0; - } - - int threshold = 10; - int val = 32; - d_comp[0] = (int)d_found.size(); - comp[0] = (int)found.size(); - if (winSize == cv::Size(48, 96)) - { - for(int i = 0; i < (int)d_found.size(); i++) - { - if (match_rect(d_found[i], win1_48x96, threshold)) - d_comp[1] = val; - if (match_rect(d_found[i], win2_48x96, threshold)) - d_comp[2] = val; - if (match_rect(d_found[i], win3_48x96, threshold)) - d_comp[3] = val; - } - for(int i = 0; i < (int)found.size(); i++) - { - if (match_rect(found[i], win1_48x96, threshold)) - comp[1] = val; - if (match_rect(found[i], win2_48x96, threshold)) - comp[2] = val; - if (match_rect(found[i], win3_48x96, threshold)) - comp[3] = val; - } - } - else if (winSize == cv::Size(64, 128)) - { - for(int i = 0; i < (int)d_found.size(); i++) - { - if (match_rect(d_found[i], win1_64x128, threshold)) - d_comp[1] = val; - if (match_rect(d_found[i], win2_64x128, threshold)) - d_comp[2] = val; - } - for(int i = 0; i < (int)found.size(); i++) - { - if (match_rect(found[i], win1_64x128, threshold)) - comp[1] = val; - if (match_rect(found[i], win2_64x128, threshold)) - comp[2] = val; - } - } - - EXPECT_MAT_NEAR(cv::Mat(d_comp), cv::Mat(comp), 3); + EXPECT_LT(checkRectSimilarity(img.size(), found, d_found), 1.0); } INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, HOG, testing::Combine( - testing::Values(cv::Size(64, 128), cv::Size(48, 96)), + testing::Values(Size(64, 128), Size(48, 96)), testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)))); +///////////////////////////// Haar ////////////////////////////// +IMPLEMENT_PARAM_CLASS(CascadeName, std::string); +CascadeName cascade_frontalface_alt(std::string("haarcascade_frontalface_alt.xml")); +CascadeName cascade_frontalface_alt2(std::string("haarcascade_frontalface_alt2.xml")); +struct getRect +{ + Rect operator ()(const CvAvgComp &e) const + { + return e.rect; + } +}; -#endif //HAVE_OPENCL +PARAM_TEST_CASE(Haar, int, CascadeName) +{ + ocl::OclCascadeClassifier cascade, nestedCascade; + CascadeClassifier cpucascade, cpunestedCascade; + + int flags; + std::string cascadeName; + vector faces, oclfaces; + Mat img; + ocl::oclMat d_img; + + virtual void SetUp() + { + flags = GET_PARAM(0); + cascadeName = (workdir + "../../data/haarcascades/").append(GET_PARAM(1)); + if( (!cascade.load( cascadeName )) || (!cpucascade.load(cascadeName)) ) + { + std::cout << "ERROR: Could not load classifier cascade" << std::endl; + return; + } + img = readImage(workdir + "lena.jpg", IMREAD_GRAYSCALE); + if(img.empty()) + { + std::cout << "Couldn't read lena.jpg" << std::endl; + return ; + } + equalizeHist(img, img); + d_img.upload(img); + } +}; + +TEST_P(Haar, FaceDetect) +{ + MemStorage storage(cvCreateMemStorage(0)); + CvSeq *_objects; + _objects = cascade.oclHaarDetectObjects(d_img, storage, 1.1, 3, + flags, Size(30, 30), Size(0, 0)); + vector vecAvgComp; + Seq(_objects).copyTo(vecAvgComp); + oclfaces.resize(vecAvgComp.size()); + std::transform(vecAvgComp.begin(), vecAvgComp.end(), oclfaces.begin(), getRect()); + + cpucascade.detectMultiScale(img, faces, 1.1, 3, + flags, + Size(30, 30), Size(0, 0)); + + EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0); +} + +TEST_P(Haar, FaceDetectUseBuf) +{ + ocl::OclCascadeClassifierBuf cascadebuf; + if(!cascadebuf.load(cascadeName)) + { + std::cout << "ERROR: Could not load classifier cascade for FaceDetectUseBuf!" << std::endl; + return; + } + cascadebuf.detectMultiScale(d_img, oclfaces, 1.1, 3, + flags, + Size(30, 30), Size(0, 0)); + cpucascade.detectMultiScale(img, faces, 1.1, 3, + flags, + Size(30, 30), Size(0, 0)); + + // intentionally run ocl facedetect again and check if it still works after the first run + cascadebuf.detectMultiScale(d_img, oclfaces, 1.1, 3, + flags, + Size(30, 30)); + cascadebuf.release(); + + EXPECT_LT(checkRectSimilarity(img.size(), faces, oclfaces), 1.0); +} + +INSTANTIATE_TEST_CASE_P(OCL_ObjDetect, Haar, + Combine(Values(CV_HAAR_SCALE_IMAGE, 0), + Values(cascade_frontalface_alt/*, cascade_frontalface_alt2*/))); + +#endif //HAVE_OPENCL \ No newline at end of file diff --git a/modules/ocl/test/test_pyrdown.cpp b/modules/ocl/test/test_pyramids.cpp similarity index 75% rename from modules/ocl/test/test_pyrdown.cpp rename to modules/ocl/test/test_pyramids.cpp index 6d00fb5e4..1bd188dea 100644 --- a/modules/ocl/test/test_pyrdown.cpp +++ b/modules/ocl/test/test_pyramids.cpp @@ -15,7 +15,6 @@ // Third party copyrights are property of their respective owners. // // @Authors -// Dachuan Zhao, dachuan@multicorewareinc.com // Yao Wang yao@multicorewareinc.com // // Redistribution and use in source and binary forms, with or without modification, @@ -56,11 +55,12 @@ using namespace cvtest; using namespace testing; using namespace std; -PARAM_TEST_CASE(PyrDown, MatType, int) +PARAM_TEST_CASE(PyrBase, MatType, int) { int type; int channels; - + Mat dst_cpu; + oclMat gdst; virtual void SetUp() { type = GET_PARAM(0); @@ -69,19 +69,19 @@ PARAM_TEST_CASE(PyrDown, MatType, int) }; +/////////////////////// PyrDown ////////////////////////// +struct PyrDown : PyrBase {}; TEST_P(PyrDown, Mat) { for(int j = 0; j < LOOP_TIMES; j++) { - cv::Size size(MWIDTH, MHEIGHT); - cv::RNG &rng = TS::ptr()->get_rng(); - cv::Mat src = randomMat(rng, size, CV_MAKETYPE(type, channels), 0, 100, false); - - cv::ocl::oclMat gsrc(src), gdst; - cv::Mat dst_cpu; - cv::pyrDown(src, dst_cpu); - cv::ocl::pyrDown(gsrc, gdst); + Size size(MWIDTH, MHEIGHT); + Mat src = randomMat(size, CV_MAKETYPE(type, channels)); + oclMat gsrc(src); + + pyrDown(src, dst_cpu); + pyrDown(gsrc, gdst); EXPECT_MAT_NEAR(dst_cpu, Mat(gdst), type == CV_32F ? 1e-4f : 1.0f); } @@ -90,5 +90,27 @@ TEST_P(PyrDown, Mat) INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrDown, Combine( Values(CV_8U, CV_32F), Values(1, 3, 4))); +/////////////////////// PyrUp ////////////////////////// +struct PyrUp : PyrBase {}; + +TEST_P(PyrUp, Accuracy) +{ + for(int j = 0; j < LOOP_TIMES; j++) + { + Size size(MWIDTH, MHEIGHT); + Mat src = randomMat(size, CV_MAKETYPE(type, channels)); + oclMat gsrc(src); + + pyrUp(src, dst_cpu); + pyrUp(gsrc, gdst); + + EXPECT_MAT_NEAR(dst_cpu, Mat(gdst), (type == CV_32F ? 1e-4f : 1.0)); + } + +} + + +INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrUp, testing::Combine( + Values(CV_8U, CV_32F), Values(1, 3, 4))); #endif // HAVE_OPENCL diff --git a/modules/ocl/test/test_pyrup.cpp b/modules/ocl/test/test_pyrup.cpp deleted file mode 100644 index afd3e8b1b..000000000 --- a/modules/ocl/test/test_pyrup.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/*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. -// -// @Authors -// Zhang Chunpeng chunpeng@multicorewareinc.com -// Yao Wang yao@multicorewareinc.com -// -// 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" -#include "opencv2/core/core.hpp" - -#ifdef HAVE_OPENCL - -using namespace cv; -using namespace cvtest; -using namespace testing; -using namespace std; - -PARAM_TEST_CASE(PyrUp, MatType, int) -{ - int type; - int channels; - - virtual void SetUp() - { - type = GET_PARAM(0); - channels = GET_PARAM(1); - } -}; - -TEST_P(PyrUp, Accuracy) -{ - for(int j = 0; j < LOOP_TIMES; j++) - { - Size size(MWIDTH, MHEIGHT); - Mat src = randomMat(size, CV_MAKETYPE(type, channels)); - Mat dst_gold; - pyrUp(src, dst_gold); - ocl::oclMat dst; - ocl::oclMat srcMat(src); - ocl::pyrUp(srcMat, dst); - - EXPECT_MAT_NEAR(dst_gold, Mat(dst), (type == CV_32F ? 1e-4f : 1.0)); - } - -} - - -INSTANTIATE_TEST_CASE_P(OCL_ImgProc, PyrUp, testing::Combine( - Values(CV_8U, CV_32F), Values(1, 3, 4))); - - -#endif // HAVE_OPENCL \ No newline at end of file diff --git a/modules/ocl/test/utility.cpp b/modules/ocl/test/utility.cpp index 4b21081a8..27f9cec07 100644 --- a/modules/ocl/test/utility.cpp +++ b/modules/ocl/test/utility.cpp @@ -100,12 +100,6 @@ Mat randomMat(Size size, int type, double minVal, double maxVal) return randomMat(TS::ptr()->get_rng(), size, type, minVal, maxVal, false); } - - - - - - /* void showDiff(InputArray gold_, InputArray actual_, double eps) { @@ -137,58 +131,7 @@ void showDiff(InputArray gold_, InputArray actual_, double eps) } */ -/* -bool supportFeature(const DeviceInfo& info, FeatureSet feature) -{ - return TargetArchs::builtWith(feature) && info.supports(feature); -} -const vector& devices() -{ - static vector devs; - static bool first = true; - - if (first) - { - int deviceCount = getCudaEnabledDeviceCount(); - - devs.reserve(deviceCount); - - for (int i = 0; i < deviceCount; ++i) - { - DeviceInfo info(i); - if (info.isCompatible()) - devs.push_back(info); - } - - first = false; - } - - return devs; -} - -vector devices(FeatureSet feature) -{ - const vector& d = devices(); - - vector devs_filtered; - - if (TargetArchs::builtWith(feature)) - { - devs_filtered.reserve(d.size()); - - for (size_t i = 0, size = d.size(); i < size; ++i) - { - const DeviceInfo& info = d[i]; - - if (info.supports(feature)) - devs_filtered.push_back(info); - } - } - - return devs_filtered; -} -*/ vector types(int depth_start, int depth_end, int cn_start, int cn_end) { @@ -264,3 +207,48 @@ void PrintTo(const Inverse &inverse, std::ostream *os) (*os) << "direct"; } +double checkRectSimilarity(Size sz, std::vector& ob1, std::vector& ob2) +{ + double final_test_result = 0.0; + size_t sz1 = ob1.size(); + size_t sz2 = ob2.size(); + + if(sz1 != sz2) + { + return sz1 > sz2 ? (double)(sz1 - sz2) : (double)(sz2 - sz1); + } + else + { + if(sz1==0 && sz2==0) + return 0; + cv::Mat cpu_result(sz, CV_8UC1); + cpu_result.setTo(0); + + for(vector::const_iterator r = ob1.begin(); r != ob1.end(); r++) + { + cv::Mat cpu_result_roi(cpu_result, *r); + cpu_result_roi.setTo(1); + cpu_result.copyTo(cpu_result); + } + int cpu_area = cv::countNonZero(cpu_result > 0); + + cv::Mat gpu_result(sz, CV_8UC1); + gpu_result.setTo(0); + for(vector::const_iterator r2 = ob2.begin(); r2 != ob2.end(); r2++) + { + cv::Mat gpu_result_roi(gpu_result, *r2); + gpu_result_roi.setTo(1); + gpu_result.copyTo(gpu_result); + } + + cv::Mat result_; + multiply(cpu_result, gpu_result, result_); + int result = cv::countNonZero(result_ > 0); + if(cpu_area!=0 && result!=0) + final_test_result = 1.0 - (double)result/(double)cpu_area; + else if(cpu_area==0 && result!=0) + final_test_result = -1; + } + return final_test_result; +} + diff --git a/modules/ocl/test/utility.hpp b/modules/ocl/test/utility.hpp index 42fa69384..0b101ec50 100644 --- a/modules/ocl/test/utility.hpp +++ b/modules/ocl/test/utility.hpp @@ -55,13 +55,12 @@ cv::Mat randomMat(cv::Size size, int type, double minVal = 0.0, double maxVal = void showDiff(cv::InputArray gold, cv::InputArray actual, double eps); -//! return true if device supports specified feature and gpu module was built with support the feature. -//bool supportFeature(const cv::gpu::DeviceInfo& info, cv::gpu::FeatureSet feature); +// This function test if gpu_rst matches cpu_rst. +// If the two vectors are not equal, it will return the difference in vector size +// Else it will return (total diff of each cpu and gpu rects covered pixels)/(total cpu rects covered pixels) +// The smaller, the better matched +double checkRectSimilarity(cv::Size sz, std::vector& ob1, std::vector& ob2); -//! return all devices compatible with current gpu module build. -//const std::vector& devices(); -//! return all devices compatible with current gpu module build which support specified feature. -//std::vector devices(cv::gpu::FeatureSet feature); //! read image from testdata folder. cv::Mat readImage(const std::string &fileName, int flags = cv::IMREAD_COLOR);