1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                           License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 //   * Redistribution's of source code must retain the above copyright notice,
21 //     this list of conditions and the following disclaimer.
22 //
23 //   * Redistribution's in binary form must reproduce the above copyright notice,
24 //     this list of conditions and the following disclaimer in the documentation
25 //     and/or other materials provided with the distribution.
26 //
27 //   * The name of the copyright holders may not be used to endorse or promote products
28 //     derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 
43 #include "test_precomp.hpp"
44 
45 #ifdef HAVE_CUDA
46 
47 namespace opencv_test { namespace {
48 
49 //#define DUMP
50 
51 struct HOG : testing::TestWithParam<cv::cuda::DeviceInfo>
52 {
53     cv::cuda::DeviceInfo devInfo;
54     cv::Ptr<cv::cuda::HOG> hog;
55 
56 #ifdef DUMP
57     std::ofstream f;
58 #else
59     std::ifstream f;
60 #endif
61 
62     int wins_per_img_x;
63     int wins_per_img_y;
64     int blocks_per_win_x;
65     int blocks_per_win_y;
66     int block_hist_size;
67 
SetUpopencv_test::__anon830c35de0111::HOG68     virtual void SetUp()
69     {
70         devInfo = GetParam();
71 
72         cv::cuda::setDevice(devInfo.deviceID());
73 
74         hog = cv::cuda::HOG::create();
75     }
76 
77 #ifdef DUMP
dumpopencv_test::__anon830c35de0111::HOG78     void dump(const std::vector<cv::Point>& locations)
79     {
80         int nlocations = locations.size();
81         f.write((char*)&nlocations, sizeof(nlocations));
82 
83         for (int i = 0; i < locations.size(); ++i)
84             f.write((char*)&locations[i], sizeof(locations[i]));
85     }
86 #else
compareopencv_test::__anon830c35de0111::HOG87     void compare(const std::vector<cv::Point>& locations)
88     {
89         // skip block_hists check
90         int rows, cols;
91         f.read((char*)&rows, sizeof(rows));
92         f.read((char*)&cols, sizeof(cols));
93         for (int i = 0; i < rows; ++i)
94         {
95             for (int j = 0; j < cols; ++j)
96             {
97                 float val;
98                 f.read((char*)&val, sizeof(val));
99             }
100         }
101 
102         int nlocations;
103         f.read((char*)&nlocations, sizeof(nlocations));
104         ASSERT_EQ(nlocations, static_cast<int>(locations.size()));
105 
106         for (int i = 0; i < nlocations; ++i)
107         {
108             cv::Point location;
109             f.read((char*)&location, sizeof(location));
110             ASSERT_EQ(location, locations[i]);
111         }
112     }
113 #endif
114 
testDetectopencv_test::__anon830c35de0111::HOG115     void testDetect(const cv::Mat& img)
116     {
117         hog->setGammaCorrection(false);
118         hog->setSVMDetector(hog->getDefaultPeopleDetector());
119 
120         std::vector<cv::Point> locations;
121 
122         // Test detect
123         hog->detect(loadMat(img), locations);
124 
125 #ifdef DUMP
126         dump(locations);
127 #else
128         compare(locations);
129 #endif
130 
131         // Test detect on smaller image
132         cv::Mat img2;
133         cv::resize(img, img2, cv::Size(img.cols / 2, img.rows / 2));
134         hog->detect(loadMat(img2), locations);
135 
136 #ifdef DUMP
137         dump(locations);
138 #else
139         compare(locations);
140 #endif
141 
142         // Test detect on greater image
143         cv::resize(img, img2, cv::Size(img.cols * 2, img.rows * 2));
144         hog->detect(loadMat(img2), locations);
145 
146 #ifdef DUMP
147         dump(locations);
148 #else
149         compare(locations);
150 #endif
151     }
152 };
153 
154 // desabled while resize does not fixed
CUDA_TEST_P(HOG,detect)155 CUDA_TEST_P(HOG, detect)
156 {
157     cv::Mat img_rgb = readImage("hog/road.png");
158     ASSERT_FALSE(img_rgb.empty());
159 
160     f.open((std::string(cvtest::TS::ptr()->get_data_path()) + "hog/expected_output.bin").c_str(), std::ios_base::binary);
161     ASSERT_TRUE(f.is_open());
162 
163     // Test on color image
164     cv::Mat img;
165     cv::cvtColor(img_rgb, img, cv::COLOR_BGR2BGRA);
166     testDetect(img);
167 
168     // Test on gray image
169     cv::cvtColor(img_rgb, img, cv::COLOR_BGR2GRAY);
170     testDetect(img);
171 }
172 
CUDA_TEST_P(HOG,GetDescriptors)173 CUDA_TEST_P(HOG, GetDescriptors)
174 {
175     // Load image (e.g. train data, composed from windows)
176     cv::Mat img_rgb = readImage("hog/train_data.png");
177     ASSERT_FALSE(img_rgb.empty());
178 
179     // Convert to C4
180     cv::Mat img;
181     cv::cvtColor(img_rgb, img, cv::COLOR_BGR2BGRA);
182 
183     cv::cuda::GpuMat d_img(img);
184 
185     // Convert train images into feature vectors (train table)
186     cv::cuda::GpuMat descriptors, descriptors_by_cols;
187 
188     hog->setWinStride(Size(64, 128));
189 
190     hog->setDescriptorFormat(HOGDescriptor::DESCR_FORMAT_ROW_BY_ROW);
191     hog->compute(d_img, descriptors);
192 
193     hog->setDescriptorFormat(HOGDescriptor::DESCR_FORMAT_COL_BY_COL);
194     hog->compute(d_img, descriptors_by_cols);
195 
196     // Check size of the result train table
197     wins_per_img_x = 3;
198     wins_per_img_y = 2;
199     blocks_per_win_x = 7;
200     blocks_per_win_y = 15;
201     block_hist_size = 36;
202     cv::Size descr_size_expected = cv::Size(blocks_per_win_x * blocks_per_win_y * block_hist_size,
203                                             wins_per_img_x * wins_per_img_y);
204     ASSERT_EQ(descr_size_expected, descriptors.size());
205 
206     // Check both formats of output descriptors are handled correctly
207     cv::Mat dr(descriptors);
208     cv::Mat dc(descriptors_by_cols);
209     for (int i = 0; i < wins_per_img_x * wins_per_img_y; ++i)
210     {
211         const float* l = dr.rowRange(i, i + 1).ptr<float>();
212         const float* r = dc.rowRange(i, i + 1).ptr<float>();
213         for (int y = 0; y < blocks_per_win_y; ++y)
214             for (int x = 0; x < blocks_per_win_x; ++x)
215                 for (int k = 0; k < block_hist_size; ++k)
216                     ASSERT_EQ(l[(y * blocks_per_win_x + x) * block_hist_size + k],
217                               r[(x * blocks_per_win_y + y) * block_hist_size + k]);
218     }
219 }
220 /*
221 INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, HOG, ALL_DEVICES);
222 */
223 //============== caltech hog tests =====================//
224 
225 struct CalTech : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
226 {
227     cv::cuda::DeviceInfo devInfo;
228     cv::Mat img;
229 
SetUpopencv_test::__anon830c35de0111::CalTech230     virtual void SetUp()
231     {
232         devInfo = GET_PARAM(0);
233         cv::cuda::setDevice(devInfo.deviceID());
234 
235         img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
236         ASSERT_FALSE(img.empty());
237     }
238 };
239 
CUDA_TEST_P(CalTech,HOG)240 CUDA_TEST_P(CalTech, HOG)
241 {
242     cv::cuda::GpuMat d_img(img);
243     cv::Mat markedImage(img.clone());
244 
245     cv::Ptr<cv::cuda::HOG> d_hog = cv::cuda::HOG::create();
246     d_hog->setSVMDetector(d_hog->getDefaultPeopleDetector());
247     d_hog->setNumLevels(d_hog->getNumLevels() + 32);
248 
249     std::vector<cv::Rect> found_locations;
250     d_hog->detectMultiScale(d_img, found_locations);
251 
252 #if defined (LOG_CASCADE_STATISTIC)
253     for (int i = 0; i < (int)found_locations.size(); i++)
254     {
255         cv::Rect r = found_locations[i];
256 
257         std::cout << r.x << " " << r.y  << " " << r.width << " " << r.height << std::endl;
258         cv::rectangle(markedImage, r , CV_RGB(255, 0, 0));
259     }
260 
261     cv::imshow("Res", markedImage);
262     cv::waitKey();
263 #endif
264 }
265 
266 INSTANTIATE_TEST_CASE_P(detect, CalTech, testing::Combine(ALL_DEVICES,
267     ::testing::Values<std::string>("caltech/image_00000009_0.png", "caltech/image_00000032_0.png",
268         "caltech/image_00000165_0.png", "caltech/image_00000261_0.png", "caltech/image_00000469_0.png",
269         "caltech/image_00000527_0.png", "caltech/image_00000574_0.png")));
270 
271 
272 //------------------------variable GPU HOG Tests------------------------//
273 struct Hog_var : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
274 {
275     cv::cuda::DeviceInfo devInfo;
276     cv::Mat img, c_img;
277 
SetUpopencv_test::__anon830c35de0111::Hog_var278     virtual void SetUp()
279     {
280         devInfo = GET_PARAM(0);
281         cv::cuda::setDevice(devInfo.deviceID());
282 
283         cv::Rect roi(0, 0, 16, 32);
284         img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
285         ASSERT_FALSE(img.empty());
286         c_img = img(roi);
287     }
288 };
289 
CUDA_TEST_P(Hog_var,HOG)290 CUDA_TEST_P(Hog_var, HOG)
291 {
292     cv::cuda::GpuMat _img(c_img);
293     cv::cuda::GpuMat d_img;
294 
295     int win_stride_width = 8;int win_stride_height = 8;
296     int win_width = 16;
297     int block_width = 8;
298     int block_stride_width = 4;int block_stride_height = 4;
299     int cell_width = 4;
300     int nbins = 9;
301 
302     Size win_stride(win_stride_width, win_stride_height);
303     Size win_size(win_width, win_width * 2);
304     Size block_size(block_width, block_width);
305     Size block_stride(block_stride_width, block_stride_height);
306     Size cell_size(cell_width, cell_width);
307 
308     cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, nbins);
309 
310     gpu_hog->setNumLevels(13);
311     gpu_hog->setHitThreshold(0);
312     gpu_hog->setWinStride(win_stride);
313     gpu_hog->setScaleFactor(1.05);
314     gpu_hog->setGroupThreshold(8);
315     gpu_hog->compute(_img, d_img);
316 
317     vector<float> gpu_desc_vec;
318     ASSERT_TRUE(gpu_desc_vec.empty());
319     cv::Mat R(d_img);
320 
321     cv::HOGDescriptor cpu_hog(win_size, block_size, block_stride, cell_size, nbins);
322     cpu_hog.nlevels = 13;
323     vector<float> cpu_desc_vec;
324     ASSERT_TRUE(cpu_desc_vec.empty());
325     cpu_hog.compute(c_img, cpu_desc_vec, win_stride, Size(0,0));
326 }
327 
328 INSTANTIATE_TEST_CASE_P(detect, Hog_var, testing::Combine(ALL_DEVICES,
329     ::testing::Values<std::string>("/hog/road.png")));
330 
331 struct Hog_var_cell : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
332 {
333     cv::cuda::DeviceInfo devInfo;
334     cv::Mat img, c_img, c_img2, c_img3, c_img4;
335 
SetUpopencv_test::__anon830c35de0111::Hog_var_cell336     virtual void SetUp()
337     {
338         devInfo = GET_PARAM(0);
339         cv::cuda::setDevice(devInfo.deviceID());
340 
341         cv::Rect roi(0, 0, 48, 96);
342         img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
343         ASSERT_FALSE(img.empty());
344         c_img = img(roi);
345 
346         cv::Rect roi2(0, 0, 54, 108);
347         c_img2 = img(roi2);
348 
349         cv::Rect roi3(0, 0, 64, 128);
350         c_img3 = img(roi3);
351 
352         cv::Rect roi4(0, 0, 32, 64);
353         c_img4 = img(roi4);
354     }
355 };
356 
CUDA_TEST_P(Hog_var_cell,HOG)357 CUDA_TEST_P(Hog_var_cell, HOG)
358 {
359     cv::cuda::GpuMat _img(c_img);
360     cv::cuda::GpuMat _img2(c_img2);
361     cv::cuda::GpuMat _img3(c_img3);
362     cv::cuda::GpuMat _img4(c_img4);
363     cv::cuda::GpuMat d_img;
364 
365     ASSERT_FALSE(_img.empty());
366     ASSERT_TRUE(d_img.empty());
367 
368     int win_stride_width = 8;int win_stride_height = 8;
369     int win_width = 48;
370     int block_width = 16;
371     int block_stride_width = 8;int block_stride_height = 8;
372     int cell_width = 8;
373     int nbins = 9;
374 
375     Size win_stride(win_stride_width, win_stride_height);
376     Size win_size(win_width, win_width * 2);
377     Size block_size(block_width, block_width);
378     Size block_stride(block_stride_width, block_stride_height);
379     Size cell_size(cell_width, cell_width);
380 
381     cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, nbins);
382 
383     gpu_hog->setNumLevels(13);
384     gpu_hog->setHitThreshold(0);
385     gpu_hog->setWinStride(win_stride);
386     gpu_hog->setScaleFactor(1.05);
387     gpu_hog->setGroupThreshold(8);
388     gpu_hog->compute(_img, d_img);
389 //------------------------------------------------------------------------------
390     cv::cuda::GpuMat d_img2;
391     ASSERT_TRUE(d_img2.empty());
392 
393     int win_stride_width2 = 8;int win_stride_height2 = 8;
394     int win_width2 = 48;
395     int block_width2 = 16;
396     int block_stride_width2 = 8;int block_stride_height2 = 8;
397     int cell_width2 = 4;
398 
399     Size win_stride2(win_stride_width2, win_stride_height2);
400     Size win_size2(win_width2, win_width2 * 2);
401     Size block_size2(block_width2, block_width2);
402     Size block_stride2(block_stride_width2, block_stride_height2);
403     Size cell_size2(cell_width2, cell_width2);
404 
405     cv::Ptr<cv::cuda::HOG> gpu_hog2 = cv::cuda::HOG::create(win_size2, block_size2, block_stride2, cell_size2, nbins);
406     gpu_hog2->setWinStride(win_stride2);
407     gpu_hog2->compute(_img, d_img2);
408 //------------------------------------------------------------------------------
409     cv::cuda::GpuMat d_img3;
410     ASSERT_TRUE(d_img3.empty());
411 
412     int win_stride_width3 = 9;int win_stride_height3 = 9;
413     int win_width3 = 54;
414     int block_width3 = 18;
415     int block_stride_width3 = 9;int block_stride_height3 = 9;
416     int cell_width3 = 6;
417 
418     Size win_stride3(win_stride_width3, win_stride_height3);
419     Size win_size3(win_width3, win_width3 * 2);
420     Size block_size3(block_width3, block_width3);
421     Size block_stride3(block_stride_width3, block_stride_height3);
422     Size cell_size3(cell_width3, cell_width3);
423 
424     cv::Ptr<cv::cuda::HOG> gpu_hog3 = cv::cuda::HOG::create(win_size3, block_size3, block_stride3, cell_size3, nbins);
425     gpu_hog3->setWinStride(win_stride3);
426     gpu_hog3->compute(_img2, d_img3);
427 //------------------------------------------------------------------------------
428     cv::cuda::GpuMat d_img4;
429     ASSERT_TRUE(d_img4.empty());
430 
431     int win_stride_width4 = 16;int win_stride_height4 = 16;
432     int win_width4 = 64;
433     int block_width4 = 32;
434     int block_stride_width4 = 16;int block_stride_height4 = 16;
435     int cell_width4 = 8;
436 
437     Size win_stride4(win_stride_width4, win_stride_height4);
438     Size win_size4(win_width4, win_width4 * 2);
439     Size block_size4(block_width4, block_width4);
440     Size block_stride4(block_stride_width4, block_stride_height4);
441     Size cell_size4(cell_width4, cell_width4);
442 
443     cv::Ptr<cv::cuda::HOG> gpu_hog4 = cv::cuda::HOG::create(win_size4, block_size4, block_stride4, cell_size4, nbins);
444     gpu_hog4->setWinStride(win_stride4);
445     gpu_hog4->compute(_img3, d_img4);
446 //------------------------------------------------------------------------------
447     cv::cuda::GpuMat d_img5;
448     ASSERT_TRUE(d_img5.empty());
449 
450     int win_stride_width5 = 16;int win_stride_height5 = 16;
451     int win_width5 = 64;
452     int block_width5 = 32;
453     int block_stride_width5 = 16;int block_stride_height5 = 16;
454     int cell_width5 = 16;
455 
456     Size win_stride5(win_stride_width5, win_stride_height5);
457     Size win_size5(win_width5, win_width5 * 2);
458     Size block_size5(block_width5, block_width5);
459     Size block_stride5(block_stride_width5, block_stride_height5);
460     Size cell_size5(cell_width5, cell_width5);
461 
462     cv::Ptr<cv::cuda::HOG> gpu_hog5 = cv::cuda::HOG::create(win_size5, block_size5, block_stride5, cell_size5, nbins);
463     gpu_hog5->setWinStride(win_stride5);
464     gpu_hog5->compute(_img3, d_img5);
465 //------------------------------------------------------------------------------
466 }
467 
468 INSTANTIATE_TEST_CASE_P(detect, Hog_var_cell, testing::Combine(ALL_DEVICES,
469     ::testing::Values<std::string>("/hog/road.png")));
470 //////////////////////////////////////////////////////////////////////////////////////////
471 /// LBP classifier
472 
PARAM_TEST_CASE(LBP_Read_classifier,cv::cuda::DeviceInfo,int)473 PARAM_TEST_CASE(LBP_Read_classifier, cv::cuda::DeviceInfo, int)
474 {
475     cv::cuda::DeviceInfo devInfo;
476 
477     virtual void SetUp()
478     {
479         devInfo = GET_PARAM(0);
480         cv::cuda::setDevice(devInfo.deviceID());
481     }
482 };
483 
CUDA_TEST_P(LBP_Read_classifier,Accuracy)484 CUDA_TEST_P(LBP_Read_classifier, Accuracy)
485 {
486     std::string classifierXmlPath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml";
487 
488     cv::Ptr<cv::cuda::CascadeClassifier> d_cascade;
489 
490     ASSERT_NO_THROW(
491         d_cascade = cv::cuda::CascadeClassifier::create(classifierXmlPath);
492     );
493 
494     ASSERT_FALSE(d_cascade.empty());
495 }
496 
497 INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, LBP_Read_classifier,
498                         testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
499 
500 
PARAM_TEST_CASE(LBP_classify,cv::cuda::DeviceInfo,int)501 PARAM_TEST_CASE(LBP_classify, cv::cuda::DeviceInfo, int)
502 {
503     cv::cuda::DeviceInfo devInfo;
504 
505     virtual void SetUp()
506     {
507         devInfo = GET_PARAM(0);
508         cv::cuda::setDevice(devInfo.deviceID());
509     }
510 };
511 
CUDA_TEST_P(LBP_classify,Accuracy)512 CUDA_TEST_P(LBP_classify, Accuracy)
513 {
514     std::string classifierXmlPath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml";
515     std::string imagePath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/er.png";
516 
517     cv::CascadeClassifier cpuClassifier(classifierXmlPath);
518     ASSERT_FALSE(cpuClassifier.empty());
519 
520     cv::Mat image = cv::imread(imagePath);
521     image = image.colRange(0, image.cols/2);
522     cv::Mat grey;
523     cvtColor(image, grey, cv::COLOR_BGR2GRAY);
524     ASSERT_FALSE(image.empty());
525 
526     std::vector<cv::Rect> rects;
527     cpuClassifier.detectMultiScale(grey, rects);
528     cv::Mat markedImage = image.clone();
529 
530     std::vector<cv::Rect>::iterator it = rects.begin();
531     for (; it != rects.end(); ++it)
532         cv::rectangle(markedImage, *it, cv::Scalar(255, 0, 0));
533 
534     cv::Ptr<cv::cuda::CascadeClassifier> gpuClassifier =
535             cv::cuda::CascadeClassifier::create(classifierXmlPath);
536 
537     cv::cuda::GpuMat tested(grey);
538     cv::cuda::GpuMat gpu_rects_buf;
539     gpuClassifier->detectMultiScale(tested, gpu_rects_buf);
540 
541     std::vector<cv::Rect> gpu_rects;
542     gpuClassifier->convert(gpu_rects_buf, gpu_rects);
543 
544 #if defined (LOG_CASCADE_STATISTIC)
545     for (size_t i = 0; i < gpu_rects.size(); i++)
546     {
547         cv::Rect r = gpu_rects[i];
548 
549         std::cout << r.x << " " << r.y  << " " << r.width << " " << r.height << std::endl;
550         cv::rectangle(markedImage, r , CV_RGB(255, 0, 0));
551     }
552 
553     cv::imshow("Res", markedImage);
554     cv::waitKey();
555 #endif
556 }
557 
558 INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, LBP_classify,
559                         testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
560 
561 
562 }} // namespace
563 #endif // HAVE_CUDA
564