test_objdetect.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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. #include "test_precomp.hpp"
  43. #ifdef HAVE_CUDA
  44. namespace opencv_test { namespace {
  45. //#define DUMP
  46. struct HOG : testing::TestWithParam<cv::cuda::DeviceInfo>
  47. {
  48. cv::cuda::DeviceInfo devInfo;
  49. cv::Ptr<cv::cuda::HOG> hog;
  50. #ifdef DUMP
  51. std::ofstream f;
  52. #else
  53. std::ifstream f;
  54. #endif
  55. int wins_per_img_x;
  56. int wins_per_img_y;
  57. int blocks_per_win_x;
  58. int blocks_per_win_y;
  59. int block_hist_size;
  60. virtual void SetUp()
  61. {
  62. devInfo = GetParam();
  63. cv::cuda::setDevice(devInfo.deviceID());
  64. hog = cv::cuda::HOG::create();
  65. }
  66. #ifdef DUMP
  67. void dump(const std::vector<cv::Point>& locations)
  68. {
  69. int nlocations = locations.size();
  70. f.write((char*)&nlocations, sizeof(nlocations));
  71. for (int i = 0; i < locations.size(); ++i)
  72. f.write((char*)&locations[i], sizeof(locations[i]));
  73. }
  74. #else
  75. void compare(const std::vector<cv::Point>& locations)
  76. {
  77. // skip block_hists check
  78. int rows, cols;
  79. f.read((char*)&rows, sizeof(rows));
  80. f.read((char*)&cols, sizeof(cols));
  81. for (int i = 0; i < rows; ++i)
  82. {
  83. for (int j = 0; j < cols; ++j)
  84. {
  85. float val;
  86. f.read((char*)&val, sizeof(val));
  87. }
  88. }
  89. int nlocations;
  90. f.read((char*)&nlocations, sizeof(nlocations));
  91. ASSERT_EQ(nlocations, static_cast<int>(locations.size()));
  92. for (int i = 0; i < nlocations; ++i)
  93. {
  94. cv::Point location;
  95. f.read((char*)&location, sizeof(location));
  96. ASSERT_EQ(location, locations[i]);
  97. }
  98. }
  99. #endif
  100. void testDetect(const cv::Mat& img)
  101. {
  102. hog->setGammaCorrection(false);
  103. hog->setSVMDetector(hog->getDefaultPeopleDetector());
  104. std::vector<cv::Point> locations;
  105. // Test detect
  106. hog->detect(loadMat(img), locations);
  107. #ifdef DUMP
  108. dump(locations);
  109. #else
  110. compare(locations);
  111. #endif
  112. // Test detect on smaller image
  113. cv::Mat img2;
  114. cv::resize(img, img2, cv::Size(img.cols / 2, img.rows / 2));
  115. hog->detect(loadMat(img2), locations);
  116. #ifdef DUMP
  117. dump(locations);
  118. #else
  119. compare(locations);
  120. #endif
  121. // Test detect on greater image
  122. cv::resize(img, img2, cv::Size(img.cols * 2, img.rows * 2));
  123. hog->detect(loadMat(img2), locations);
  124. #ifdef DUMP
  125. dump(locations);
  126. #else
  127. compare(locations);
  128. #endif
  129. }
  130. };
  131. // desabled while resize does not fixed
  132. CUDA_TEST_P(HOG, detect)
  133. {
  134. cv::Mat img_rgb = readImage("hog/road.png");
  135. ASSERT_FALSE(img_rgb.empty());
  136. f.open((std::string(cvtest::TS::ptr()->get_data_path()) + "hog/expected_output.bin").c_str(), std::ios_base::binary);
  137. ASSERT_TRUE(f.is_open());
  138. // Test on color image
  139. cv::Mat img;
  140. cv::cvtColor(img_rgb, img, cv::COLOR_BGR2BGRA);
  141. testDetect(img);
  142. // Test on gray image
  143. cv::cvtColor(img_rgb, img, cv::COLOR_BGR2GRAY);
  144. testDetect(img);
  145. }
  146. CUDA_TEST_P(HOG, GetDescriptors)
  147. {
  148. // Load image (e.g. train data, composed from windows)
  149. cv::Mat img_rgb = readImage("hog/train_data.png");
  150. ASSERT_FALSE(img_rgb.empty());
  151. // Convert to C4
  152. cv::Mat img;
  153. cv::cvtColor(img_rgb, img, cv::COLOR_BGR2BGRA);
  154. cv::cuda::GpuMat d_img(img);
  155. // Convert train images into feature vectors (train table)
  156. cv::cuda::GpuMat descriptors, descriptors_by_cols;
  157. hog->setWinStride(Size(64, 128));
  158. hog->setDescriptorFormat(HOGDescriptor::DESCR_FORMAT_ROW_BY_ROW);
  159. hog->compute(d_img, descriptors);
  160. hog->setDescriptorFormat(HOGDescriptor::DESCR_FORMAT_COL_BY_COL);
  161. hog->compute(d_img, descriptors_by_cols);
  162. // Check size of the result train table
  163. wins_per_img_x = 3;
  164. wins_per_img_y = 2;
  165. blocks_per_win_x = 7;
  166. blocks_per_win_y = 15;
  167. block_hist_size = 36;
  168. cv::Size descr_size_expected = cv::Size(blocks_per_win_x * blocks_per_win_y * block_hist_size,
  169. wins_per_img_x * wins_per_img_y);
  170. ASSERT_EQ(descr_size_expected, descriptors.size());
  171. // Check both formats of output descriptors are handled correctly
  172. cv::Mat dr(descriptors);
  173. cv::Mat dc(descriptors_by_cols);
  174. for (int i = 0; i < wins_per_img_x * wins_per_img_y; ++i)
  175. {
  176. const float* l = dr.rowRange(i, i + 1).ptr<float>();
  177. const float* r = dc.rowRange(i, i + 1).ptr<float>();
  178. for (int y = 0; y < blocks_per_win_y; ++y)
  179. for (int x = 0; x < blocks_per_win_x; ++x)
  180. for (int k = 0; k < block_hist_size; ++k)
  181. ASSERT_EQ(l[(y * blocks_per_win_x + x) * block_hist_size + k],
  182. r[(x * blocks_per_win_y + y) * block_hist_size + k]);
  183. }
  184. }
  185. /*
  186. INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, HOG, ALL_DEVICES);
  187. */
  188. //============== caltech hog tests =====================//
  189. struct CalTech : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
  190. {
  191. cv::cuda::DeviceInfo devInfo;
  192. cv::Mat img;
  193. virtual void SetUp()
  194. {
  195. devInfo = GET_PARAM(0);
  196. cv::cuda::setDevice(devInfo.deviceID());
  197. img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
  198. ASSERT_FALSE(img.empty());
  199. }
  200. };
  201. CUDA_TEST_P(CalTech, HOG)
  202. {
  203. cv::cuda::GpuMat d_img(img);
  204. cv::Mat markedImage(img.clone());
  205. cv::Ptr<cv::cuda::HOG> d_hog = cv::cuda::HOG::create();
  206. d_hog->setSVMDetector(d_hog->getDefaultPeopleDetector());
  207. d_hog->setNumLevels(d_hog->getNumLevels() + 32);
  208. std::vector<cv::Rect> found_locations;
  209. d_hog->detectMultiScale(d_img, found_locations);
  210. #if defined (LOG_CASCADE_STATISTIC)
  211. for (int i = 0; i < (int)found_locations.size(); i++)
  212. {
  213. cv::Rect r = found_locations[i];
  214. std::cout << r.x << " " << r.y << " " << r.width << " " << r.height << std::endl;
  215. cv::rectangle(markedImage, r , CV_RGB(255, 0, 0));
  216. }
  217. cv::imshow("Res", markedImage);
  218. cv::waitKey();
  219. #endif
  220. }
  221. INSTANTIATE_TEST_CASE_P(detect, CalTech, testing::Combine(ALL_DEVICES,
  222. ::testing::Values<std::string>("caltech/image_00000009_0.png", "caltech/image_00000032_0.png",
  223. "caltech/image_00000165_0.png", "caltech/image_00000261_0.png", "caltech/image_00000469_0.png",
  224. "caltech/image_00000527_0.png", "caltech/image_00000574_0.png")));
  225. //------------------------variable GPU HOG Tests------------------------//
  226. struct Hog_var : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
  227. {
  228. cv::cuda::DeviceInfo devInfo;
  229. cv::Mat img, c_img;
  230. virtual void SetUp()
  231. {
  232. devInfo = GET_PARAM(0);
  233. cv::cuda::setDevice(devInfo.deviceID());
  234. cv::Rect roi(0, 0, 16, 32);
  235. img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
  236. ASSERT_FALSE(img.empty());
  237. c_img = img(roi);
  238. }
  239. };
  240. CUDA_TEST_P(Hog_var, HOG)
  241. {
  242. cv::cuda::GpuMat _img(c_img);
  243. cv::cuda::GpuMat d_img;
  244. int win_stride_width = 8;int win_stride_height = 8;
  245. int win_width = 16;
  246. int block_width = 8;
  247. int block_stride_width = 4;int block_stride_height = 4;
  248. int cell_width = 4;
  249. int nbins = 9;
  250. Size win_stride(win_stride_width, win_stride_height);
  251. Size win_size(win_width, win_width * 2);
  252. Size block_size(block_width, block_width);
  253. Size block_stride(block_stride_width, block_stride_height);
  254. Size cell_size(cell_width, cell_width);
  255. cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, nbins);
  256. gpu_hog->setNumLevels(13);
  257. gpu_hog->setHitThreshold(0);
  258. gpu_hog->setWinStride(win_stride);
  259. gpu_hog->setScaleFactor(1.05);
  260. gpu_hog->setGroupThreshold(8);
  261. gpu_hog->compute(_img, d_img);
  262. vector<float> gpu_desc_vec;
  263. ASSERT_TRUE(gpu_desc_vec.empty());
  264. cv::Mat R(d_img);
  265. cv::HOGDescriptor cpu_hog(win_size, block_size, block_stride, cell_size, nbins);
  266. cpu_hog.nlevels = 13;
  267. vector<float> cpu_desc_vec;
  268. ASSERT_TRUE(cpu_desc_vec.empty());
  269. cpu_hog.compute(c_img, cpu_desc_vec, win_stride, Size(0,0));
  270. }
  271. INSTANTIATE_TEST_CASE_P(detect, Hog_var, testing::Combine(ALL_DEVICES,
  272. ::testing::Values<std::string>("/hog/road.png")));
  273. struct Hog_var_cell : public ::testing::TestWithParam<tuple<cv::cuda::DeviceInfo, std::string> >
  274. {
  275. cv::cuda::DeviceInfo devInfo;
  276. cv::Mat img, c_img, c_img2, c_img3, c_img4;
  277. virtual void SetUp()
  278. {
  279. devInfo = GET_PARAM(0);
  280. cv::cuda::setDevice(devInfo.deviceID());
  281. cv::Rect roi(0, 0, 48, 96);
  282. img = readImage(GET_PARAM(1), cv::IMREAD_GRAYSCALE);
  283. ASSERT_FALSE(img.empty());
  284. c_img = img(roi);
  285. cv::Rect roi2(0, 0, 54, 108);
  286. c_img2 = img(roi2);
  287. cv::Rect roi3(0, 0, 64, 128);
  288. c_img3 = img(roi3);
  289. cv::Rect roi4(0, 0, 32, 64);
  290. c_img4 = img(roi4);
  291. }
  292. };
  293. CUDA_TEST_P(Hog_var_cell, HOG)
  294. {
  295. cv::cuda::GpuMat _img(c_img);
  296. cv::cuda::GpuMat _img2(c_img2);
  297. cv::cuda::GpuMat _img3(c_img3);
  298. cv::cuda::GpuMat _img4(c_img4);
  299. cv::cuda::GpuMat d_img;
  300. ASSERT_FALSE(_img.empty());
  301. ASSERT_TRUE(d_img.empty());
  302. int win_stride_width = 8;int win_stride_height = 8;
  303. int win_width = 48;
  304. int block_width = 16;
  305. int block_stride_width = 8;int block_stride_height = 8;
  306. int cell_width = 8;
  307. int nbins = 9;
  308. Size win_stride(win_stride_width, win_stride_height);
  309. Size win_size(win_width, win_width * 2);
  310. Size block_size(block_width, block_width);
  311. Size block_stride(block_stride_width, block_stride_height);
  312. Size cell_size(cell_width, cell_width);
  313. cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, nbins);
  314. gpu_hog->setNumLevels(13);
  315. gpu_hog->setHitThreshold(0);
  316. gpu_hog->setWinStride(win_stride);
  317. gpu_hog->setScaleFactor(1.05);
  318. gpu_hog->setGroupThreshold(8);
  319. gpu_hog->compute(_img, d_img);
  320. //------------------------------------------------------------------------------
  321. cv::cuda::GpuMat d_img2;
  322. ASSERT_TRUE(d_img2.empty());
  323. int win_stride_width2 = 8;int win_stride_height2 = 8;
  324. int win_width2 = 48;
  325. int block_width2 = 16;
  326. int block_stride_width2 = 8;int block_stride_height2 = 8;
  327. int cell_width2 = 4;
  328. Size win_stride2(win_stride_width2, win_stride_height2);
  329. Size win_size2(win_width2, win_width2 * 2);
  330. Size block_size2(block_width2, block_width2);
  331. Size block_stride2(block_stride_width2, block_stride_height2);
  332. Size cell_size2(cell_width2, cell_width2);
  333. cv::Ptr<cv::cuda::HOG> gpu_hog2 = cv::cuda::HOG::create(win_size2, block_size2, block_stride2, cell_size2, nbins);
  334. gpu_hog2->setWinStride(win_stride2);
  335. gpu_hog2->compute(_img, d_img2);
  336. //------------------------------------------------------------------------------
  337. cv::cuda::GpuMat d_img3;
  338. ASSERT_TRUE(d_img3.empty());
  339. int win_stride_width3 = 9;int win_stride_height3 = 9;
  340. int win_width3 = 54;
  341. int block_width3 = 18;
  342. int block_stride_width3 = 9;int block_stride_height3 = 9;
  343. int cell_width3 = 6;
  344. Size win_stride3(win_stride_width3, win_stride_height3);
  345. Size win_size3(win_width3, win_width3 * 2);
  346. Size block_size3(block_width3, block_width3);
  347. Size block_stride3(block_stride_width3, block_stride_height3);
  348. Size cell_size3(cell_width3, cell_width3);
  349. cv::Ptr<cv::cuda::HOG> gpu_hog3 = cv::cuda::HOG::create(win_size3, block_size3, block_stride3, cell_size3, nbins);
  350. gpu_hog3->setWinStride(win_stride3);
  351. gpu_hog3->compute(_img2, d_img3);
  352. //------------------------------------------------------------------------------
  353. cv::cuda::GpuMat d_img4;
  354. ASSERT_TRUE(d_img4.empty());
  355. int win_stride_width4 = 16;int win_stride_height4 = 16;
  356. int win_width4 = 64;
  357. int block_width4 = 32;
  358. int block_stride_width4 = 16;int block_stride_height4 = 16;
  359. int cell_width4 = 8;
  360. Size win_stride4(win_stride_width4, win_stride_height4);
  361. Size win_size4(win_width4, win_width4 * 2);
  362. Size block_size4(block_width4, block_width4);
  363. Size block_stride4(block_stride_width4, block_stride_height4);
  364. Size cell_size4(cell_width4, cell_width4);
  365. cv::Ptr<cv::cuda::HOG> gpu_hog4 = cv::cuda::HOG::create(win_size4, block_size4, block_stride4, cell_size4, nbins);
  366. gpu_hog4->setWinStride(win_stride4);
  367. gpu_hog4->compute(_img3, d_img4);
  368. //------------------------------------------------------------------------------
  369. cv::cuda::GpuMat d_img5;
  370. ASSERT_TRUE(d_img5.empty());
  371. int win_stride_width5 = 16;int win_stride_height5 = 16;
  372. int win_width5 = 64;
  373. int block_width5 = 32;
  374. int block_stride_width5 = 16;int block_stride_height5 = 16;
  375. int cell_width5 = 16;
  376. Size win_stride5(win_stride_width5, win_stride_height5);
  377. Size win_size5(win_width5, win_width5 * 2);
  378. Size block_size5(block_width5, block_width5);
  379. Size block_stride5(block_stride_width5, block_stride_height5);
  380. Size cell_size5(cell_width5, cell_width5);
  381. cv::Ptr<cv::cuda::HOG> gpu_hog5 = cv::cuda::HOG::create(win_size5, block_size5, block_stride5, cell_size5, nbins);
  382. gpu_hog5->setWinStride(win_stride5);
  383. gpu_hog5->compute(_img3, d_img5);
  384. //------------------------------------------------------------------------------
  385. }
  386. INSTANTIATE_TEST_CASE_P(detect, Hog_var_cell, testing::Combine(ALL_DEVICES,
  387. ::testing::Values<std::string>("/hog/road.png")));
  388. //////////////////////////////////////////////////////////////////////////////////////////
  389. /// LBP classifier
  390. PARAM_TEST_CASE(LBP_Read_classifier, cv::cuda::DeviceInfo, int)
  391. {
  392. cv::cuda::DeviceInfo devInfo;
  393. virtual void SetUp()
  394. {
  395. devInfo = GET_PARAM(0);
  396. cv::cuda::setDevice(devInfo.deviceID());
  397. }
  398. };
  399. CUDA_TEST_P(LBP_Read_classifier, Accuracy)
  400. {
  401. std::string classifierXmlPath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml";
  402. cv::Ptr<cv::cuda::CascadeClassifier> d_cascade;
  403. ASSERT_NO_THROW(
  404. d_cascade = cv::cuda::CascadeClassifier::create(classifierXmlPath);
  405. );
  406. ASSERT_FALSE(d_cascade.empty());
  407. }
  408. INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, LBP_Read_classifier,
  409. testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
  410. PARAM_TEST_CASE(LBP_classify, cv::cuda::DeviceInfo, int)
  411. {
  412. cv::cuda::DeviceInfo devInfo;
  413. virtual void SetUp()
  414. {
  415. devInfo = GET_PARAM(0);
  416. cv::cuda::setDevice(devInfo.deviceID());
  417. }
  418. };
  419. CUDA_TEST_P(LBP_classify, Accuracy)
  420. {
  421. std::string classifierXmlPath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/lbpcascade_frontalface.xml";
  422. std::string imagePath = std::string(cvtest::TS::ptr()->get_data_path()) + "lbpcascade/er.png";
  423. cv::CascadeClassifier cpuClassifier(classifierXmlPath);
  424. ASSERT_FALSE(cpuClassifier.empty());
  425. cv::Mat image = cv::imread(imagePath);
  426. image = image.colRange(0, image.cols/2);
  427. cv::Mat grey;
  428. cvtColor(image, grey, cv::COLOR_BGR2GRAY);
  429. ASSERT_FALSE(image.empty());
  430. std::vector<cv::Rect> rects;
  431. cpuClassifier.detectMultiScale(grey, rects);
  432. cv::Mat markedImage = image.clone();
  433. std::vector<cv::Rect>::iterator it = rects.begin();
  434. for (; it != rects.end(); ++it)
  435. cv::rectangle(markedImage, *it, cv::Scalar(255, 0, 0));
  436. cv::Ptr<cv::cuda::CascadeClassifier> gpuClassifier =
  437. cv::cuda::CascadeClassifier::create(classifierXmlPath);
  438. cv::cuda::GpuMat tested(grey);
  439. cv::cuda::GpuMat gpu_rects_buf;
  440. gpuClassifier->detectMultiScale(tested, gpu_rects_buf);
  441. std::vector<cv::Rect> gpu_rects;
  442. gpuClassifier->convert(gpu_rects_buf, gpu_rects);
  443. #if defined (LOG_CASCADE_STATISTIC)
  444. for (size_t i = 0; i < gpu_rects.size(); i++)
  445. {
  446. cv::Rect r = gpu_rects[i];
  447. std::cout << r.x << " " << r.y << " " << r.width << " " << r.height << std::endl;
  448. cv::rectangle(markedImage, r , CV_RGB(255, 0, 0));
  449. }
  450. cv::imshow("Res", markedImage);
  451. cv::waitKey();
  452. #endif
  453. }
  454. INSTANTIATE_TEST_CASE_P(CUDA_ObjDetect, LBP_classify,
  455. testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
  456. }} // namespace
  457. #endif // HAVE_CUDA