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