NCVHaarObjectDetection.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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. //
  44. // NVIDIA CUDA implementation of Viola-Jones Object Detection Framework
  45. //
  46. // The algorithm and code are explained in the upcoming GPU Computing Gems
  47. // chapter in detail:
  48. //
  49. // Anton Obukhov, "Haar Classifiers for Object Detection with CUDA"
  50. // PDF URL placeholder
  51. // email: aobukhov@nvidia.com, devsupport@nvidia.com
  52. //
  53. // Credits for help with the code to:
  54. // Alexey Mendelenko, Cyril Crassin, and Mikhail Smirnov.
  55. //
  56. ////////////////////////////////////////////////////////////////////////////////
  57. #ifndef _ncvhaarobjectdetection_hpp_
  58. #define _ncvhaarobjectdetection_hpp_
  59. #include "opencv2/cudalegacy/NCV.hpp"
  60. //! @addtogroup cudalegacy
  61. //! @{
  62. //==============================================================================
  63. //
  64. // Guaranteed size cross-platform classifier structures
  65. //
  66. //==============================================================================
  67. #if defined __GNUC__ && (__GNUC__*100 + __GNUC_MINOR__ > 204)
  68. typedef Ncv32f __attribute__((__may_alias__)) Ncv32f_a;
  69. #else
  70. typedef Ncv32f Ncv32f_a;
  71. #endif
  72. struct HaarFeature64
  73. {
  74. uint2 _ui2;
  75. #define HaarFeature64_CreateCheck_MaxRectField 0xFF
  76. __host__ NCVStatus setRect(Ncv32u rectX, Ncv32u rectY, Ncv32u rectWidth, Ncv32u rectHeight, Ncv32u /*clsWidth*/, Ncv32u /*clsHeight*/)
  77. {
  78. ncvAssertReturn(rectWidth <= HaarFeature64_CreateCheck_MaxRectField && rectHeight <= HaarFeature64_CreateCheck_MaxRectField, NCV_HAAR_TOO_LARGE_FEATURES);
  79. ((NcvRect8u*)&(this->_ui2.x))->x = (Ncv8u)rectX;
  80. ((NcvRect8u*)&(this->_ui2.x))->y = (Ncv8u)rectY;
  81. ((NcvRect8u*)&(this->_ui2.x))->width = (Ncv8u)rectWidth;
  82. ((NcvRect8u*)&(this->_ui2.x))->height = (Ncv8u)rectHeight;
  83. return NCV_SUCCESS;
  84. }
  85. __host__ NCVStatus setWeight(Ncv32f weight)
  86. {
  87. ((Ncv32f_a*)&(this->_ui2.y))[0] = weight;
  88. return NCV_SUCCESS;
  89. }
  90. __device__ __host__ void getRect(Ncv32u *rectX, Ncv32u *rectY, Ncv32u *rectWidth, Ncv32u *rectHeight)
  91. {
  92. NcvRect8u tmpRect = *(NcvRect8u*)(&this->_ui2.x);
  93. *rectX = tmpRect.x;
  94. *rectY = tmpRect.y;
  95. *rectWidth = tmpRect.width;
  96. *rectHeight = tmpRect.height;
  97. }
  98. __device__ __host__ Ncv32f getWeight(void)
  99. {
  100. return *(Ncv32f_a*)(&this->_ui2.y);
  101. }
  102. };
  103. struct HaarFeatureDescriptor32
  104. {
  105. private:
  106. #define HaarFeatureDescriptor32_Interpret_MaskFlagTilted 0x80000000
  107. #define HaarFeatureDescriptor32_Interpret_MaskFlagLeftNodeLeaf 0x40000000
  108. #define HaarFeatureDescriptor32_Interpret_MaskFlagRightNodeLeaf 0x20000000
  109. #define HaarFeatureDescriptor32_CreateCheck_MaxNumFeatures 0x1F
  110. #define HaarFeatureDescriptor32_NumFeatures_Shift 24
  111. #define HaarFeatureDescriptor32_CreateCheck_MaxFeatureOffset 0x00FFFFFF
  112. Ncv32u desc;
  113. public:
  114. __host__ NCVStatus create(NcvBool bTilted, NcvBool bLeftLeaf, NcvBool bRightLeaf,
  115. Ncv32u numFeatures, Ncv32u offsetFeatures)
  116. {
  117. if (numFeatures > HaarFeatureDescriptor32_CreateCheck_MaxNumFeatures)
  118. {
  119. return NCV_HAAR_TOO_MANY_FEATURES_IN_CLASSIFIER;
  120. }
  121. if (offsetFeatures > HaarFeatureDescriptor32_CreateCheck_MaxFeatureOffset)
  122. {
  123. return NCV_HAAR_TOO_MANY_FEATURES_IN_CASCADE;
  124. }
  125. this->desc = 0;
  126. this->desc |= (bTilted ? HaarFeatureDescriptor32_Interpret_MaskFlagTilted : 0);
  127. this->desc |= (bLeftLeaf ? HaarFeatureDescriptor32_Interpret_MaskFlagLeftNodeLeaf : 0);
  128. this->desc |= (bRightLeaf ? HaarFeatureDescriptor32_Interpret_MaskFlagRightNodeLeaf : 0);
  129. this->desc |= (numFeatures << HaarFeatureDescriptor32_NumFeatures_Shift);
  130. this->desc |= offsetFeatures;
  131. return NCV_SUCCESS;
  132. }
  133. __device__ __host__ NcvBool isTilted(void)
  134. {
  135. return (this->desc & HaarFeatureDescriptor32_Interpret_MaskFlagTilted) != 0;
  136. }
  137. __device__ __host__ NcvBool isLeftNodeLeaf(void)
  138. {
  139. return (this->desc & HaarFeatureDescriptor32_Interpret_MaskFlagLeftNodeLeaf) != 0;
  140. }
  141. __device__ __host__ NcvBool isRightNodeLeaf(void)
  142. {
  143. return (this->desc & HaarFeatureDescriptor32_Interpret_MaskFlagRightNodeLeaf) != 0;
  144. }
  145. __device__ __host__ Ncv32u getNumFeatures(void)
  146. {
  147. return (this->desc >> HaarFeatureDescriptor32_NumFeatures_Shift) & HaarFeatureDescriptor32_CreateCheck_MaxNumFeatures;
  148. }
  149. __device__ __host__ Ncv32u getFeaturesOffset(void)
  150. {
  151. return this->desc & HaarFeatureDescriptor32_CreateCheck_MaxFeatureOffset;
  152. }
  153. };
  154. struct HaarClassifierNodeDescriptor32
  155. {
  156. uint1 _ui1;
  157. __host__ NCVStatus create(Ncv32f leafValue)
  158. {
  159. *(Ncv32f_a *)&this->_ui1 = leafValue;
  160. return NCV_SUCCESS;
  161. }
  162. __host__ NCVStatus create(Ncv32u offsetHaarClassifierNode)
  163. {
  164. this->_ui1.x = offsetHaarClassifierNode;
  165. return NCV_SUCCESS;
  166. }
  167. __host__ Ncv32f getLeafValueHost(void)
  168. {
  169. return *(Ncv32f_a *)&this->_ui1.x;
  170. }
  171. #ifdef __CUDACC__
  172. __device__ Ncv32f getLeafValue(void)
  173. {
  174. return __int_as_float(this->_ui1.x);
  175. }
  176. #endif
  177. __device__ __host__ Ncv32u getNextNodeOffset(void)
  178. {
  179. return this->_ui1.x;
  180. }
  181. };
  182. #if defined __GNUC__ && (__GNUC__*100 + __GNUC_MINOR__ > 204)
  183. typedef Ncv32u __attribute__((__may_alias__)) Ncv32u_a;
  184. #else
  185. typedef Ncv32u Ncv32u_a;
  186. #endif
  187. struct HaarClassifierNode128
  188. {
  189. uint4 _ui4;
  190. __host__ NCVStatus setFeatureDesc(HaarFeatureDescriptor32 f)
  191. {
  192. this->_ui4.x = *(Ncv32u *)&f;
  193. return NCV_SUCCESS;
  194. }
  195. __host__ NCVStatus setThreshold(Ncv32f t)
  196. {
  197. this->_ui4.y = *(Ncv32u_a *)&t;
  198. return NCV_SUCCESS;
  199. }
  200. __host__ NCVStatus setLeftNodeDesc(HaarClassifierNodeDescriptor32 nl)
  201. {
  202. this->_ui4.z = *(Ncv32u_a *)&nl;
  203. return NCV_SUCCESS;
  204. }
  205. __host__ NCVStatus setRightNodeDesc(HaarClassifierNodeDescriptor32 nr)
  206. {
  207. this->_ui4.w = *(Ncv32u_a *)&nr;
  208. return NCV_SUCCESS;
  209. }
  210. __host__ __device__ HaarFeatureDescriptor32 getFeatureDesc(void)
  211. {
  212. return *(HaarFeatureDescriptor32 *)&this->_ui4.x;
  213. }
  214. __host__ __device__ Ncv32f getThreshold(void)
  215. {
  216. return *(Ncv32f_a*)&this->_ui4.y;
  217. }
  218. __host__ __device__ HaarClassifierNodeDescriptor32 getLeftNodeDesc(void)
  219. {
  220. return *(HaarClassifierNodeDescriptor32 *)&this->_ui4.z;
  221. }
  222. __host__ __device__ HaarClassifierNodeDescriptor32 getRightNodeDesc(void)
  223. {
  224. return *(HaarClassifierNodeDescriptor32 *)&this->_ui4.w;
  225. }
  226. };
  227. struct HaarStage64
  228. {
  229. #define HaarStage64_Interpret_MaskRootNodes 0x0000FFFF
  230. #define HaarStage64_Interpret_MaskRootNodeOffset 0xFFFF0000
  231. #define HaarStage64_Interpret_ShiftRootNodeOffset 16
  232. uint2 _ui2;
  233. __host__ NCVStatus setStageThreshold(Ncv32f t)
  234. {
  235. this->_ui2.x = *(Ncv32u_a *)&t;
  236. return NCV_SUCCESS;
  237. }
  238. __host__ NCVStatus setStartClassifierRootNodeOffset(Ncv32u val)
  239. {
  240. if (val > (HaarStage64_Interpret_MaskRootNodeOffset >> HaarStage64_Interpret_ShiftRootNodeOffset))
  241. {
  242. return NCV_HAAR_XML_LOADING_EXCEPTION;
  243. }
  244. this->_ui2.y = (val << HaarStage64_Interpret_ShiftRootNodeOffset) | (this->_ui2.y & HaarStage64_Interpret_MaskRootNodes);
  245. return NCV_SUCCESS;
  246. }
  247. __host__ NCVStatus setNumClassifierRootNodes(Ncv32u val)
  248. {
  249. if (val > HaarStage64_Interpret_MaskRootNodes)
  250. {
  251. return NCV_HAAR_XML_LOADING_EXCEPTION;
  252. }
  253. this->_ui2.y = val | (this->_ui2.y & HaarStage64_Interpret_MaskRootNodeOffset);
  254. return NCV_SUCCESS;
  255. }
  256. __host__ __device__ Ncv32f getStageThreshold(void)
  257. {
  258. return *(Ncv32f_a*)&this->_ui2.x;
  259. }
  260. __host__ __device__ Ncv32u getStartClassifierRootNodeOffset(void)
  261. {
  262. return (this->_ui2.y >> HaarStage64_Interpret_ShiftRootNodeOffset);
  263. }
  264. __host__ __device__ Ncv32u getNumClassifierRootNodes(void)
  265. {
  266. return (this->_ui2.y & HaarStage64_Interpret_MaskRootNodes);
  267. }
  268. };
  269. NCV_CT_ASSERT(sizeof(HaarFeature64) == 8);
  270. NCV_CT_ASSERT(sizeof(HaarFeatureDescriptor32) == 4);
  271. NCV_CT_ASSERT(sizeof(HaarClassifierNodeDescriptor32) == 4);
  272. NCV_CT_ASSERT(sizeof(HaarClassifierNode128) == 16);
  273. NCV_CT_ASSERT(sizeof(HaarStage64) == 8);
  274. //==============================================================================
  275. //
  276. // Classifier cascade descriptor
  277. //
  278. //==============================================================================
  279. struct HaarClassifierCascadeDescriptor
  280. {
  281. Ncv32u NumStages;
  282. Ncv32u NumClassifierRootNodes;
  283. Ncv32u NumClassifierTotalNodes;
  284. Ncv32u NumFeatures;
  285. NcvSize32u ClassifierSize;
  286. NcvBool bNeedsTiltedII;
  287. NcvBool bHasStumpsOnly;
  288. };
  289. //==============================================================================
  290. //
  291. // Functional interface
  292. //
  293. //==============================================================================
  294. enum
  295. {
  296. NCVPipeObjDet_Default = 0x000,
  297. NCVPipeObjDet_UseFairImageScaling = 0x001,
  298. NCVPipeObjDet_FindLargestObject = 0x002,
  299. NCVPipeObjDet_VisualizeInPlace = 0x004,
  300. };
  301. CV_EXPORTS NCVStatus ncvDetectObjectsMultiScale_device(NCVMatrix<Ncv8u> &d_srcImg,
  302. NcvSize32u srcRoi,
  303. NCVVector<NcvRect32u> &d_dstRects,
  304. Ncv32u &dstNumRects,
  305. HaarClassifierCascadeDescriptor &haar,
  306. NCVVector<HaarStage64> &h_HaarStages,
  307. NCVVector<HaarStage64> &d_HaarStages,
  308. NCVVector<HaarClassifierNode128> &d_HaarNodes,
  309. NCVVector<HaarFeature64> &d_HaarFeatures,
  310. NcvSize32u minObjSize,
  311. Ncv32u minNeighbors, //default 4
  312. Ncv32f scaleStep, //default 1.2f
  313. Ncv32u pixelStep, //default 1
  314. Ncv32u flags, //default NCVPipeObjDet_Default
  315. INCVMemAllocator &gpuAllocator,
  316. INCVMemAllocator &cpuAllocator,
  317. cudaDeviceProp &devProp,
  318. cudaStream_t cuStream);
  319. #define OBJDET_MASK_ELEMENT_INVALID_32U 0xFFFFFFFF
  320. #define HAAR_STDDEV_BORDER 1
  321. CV_EXPORTS NCVStatus ncvApplyHaarClassifierCascade_device(NCVMatrix<Ncv32u> &d_integralImage,
  322. NCVMatrix<Ncv32f> &d_weights,
  323. NCVMatrixAlloc<Ncv32u> &d_pixelMask,
  324. Ncv32u &numDetections,
  325. HaarClassifierCascadeDescriptor &haar,
  326. NCVVector<HaarStage64> &h_HaarStages,
  327. NCVVector<HaarStage64> &d_HaarStages,
  328. NCVVector<HaarClassifierNode128> &d_HaarNodes,
  329. NCVVector<HaarFeature64> &d_HaarFeatures,
  330. NcvBool bMaskElements,
  331. NcvSize32u anchorsRoi,
  332. Ncv32u pixelStep,
  333. Ncv32f scaleArea,
  334. INCVMemAllocator &gpuAllocator,
  335. INCVMemAllocator &cpuAllocator,
  336. cudaDeviceProp &devProp,
  337. cudaStream_t cuStream);
  338. CV_EXPORTS NCVStatus ncvApplyHaarClassifierCascade_host(NCVMatrix<Ncv32u> &h_integralImage,
  339. NCVMatrix<Ncv32f> &h_weights,
  340. NCVMatrixAlloc<Ncv32u> &h_pixelMask,
  341. Ncv32u &numDetections,
  342. HaarClassifierCascadeDescriptor &haar,
  343. NCVVector<HaarStage64> &h_HaarStages,
  344. NCVVector<HaarClassifierNode128> &h_HaarNodes,
  345. NCVVector<HaarFeature64> &h_HaarFeatures,
  346. NcvBool bMaskElements,
  347. NcvSize32u anchorsRoi,
  348. Ncv32u pixelStep,
  349. Ncv32f scaleArea);
  350. #define RECT_SIMILARITY_PROPORTION 0.2f
  351. CV_EXPORTS NCVStatus ncvGrowDetectionsVector_device(NCVVector<Ncv32u> &pixelMask,
  352. Ncv32u numPixelMaskDetections,
  353. NCVVector<NcvRect32u> &hypotheses,
  354. Ncv32u &totalDetections,
  355. Ncv32u totalMaxDetections,
  356. Ncv32u rectWidth,
  357. Ncv32u rectHeight,
  358. Ncv32f curScale,
  359. cudaStream_t cuStream);
  360. CV_EXPORTS NCVStatus ncvGrowDetectionsVector_host(NCVVector<Ncv32u> &pixelMask,
  361. Ncv32u numPixelMaskDetections,
  362. NCVVector<NcvRect32u> &hypotheses,
  363. Ncv32u &totalDetections,
  364. Ncv32u totalMaxDetections,
  365. Ncv32u rectWidth,
  366. Ncv32u rectHeight,
  367. Ncv32f curScale);
  368. CV_EXPORTS NCVStatus ncvHaarGetClassifierSize(const cv::String &filename, Ncv32u &numStages,
  369. Ncv32u &numNodes, Ncv32u &numFeatures);
  370. CV_EXPORTS NCVStatus ncvHaarLoadFromFile_host(const cv::String &filename,
  371. HaarClassifierCascadeDescriptor &haar,
  372. NCVVector<HaarStage64> &h_HaarStages,
  373. NCVVector<HaarClassifierNode128> &h_HaarNodes,
  374. NCVVector<HaarFeature64> &h_HaarFeatures);
  375. CV_EXPORTS NCVStatus ncvHaarStoreNVBIN_host(const cv::String &filename,
  376. HaarClassifierCascadeDescriptor haar,
  377. NCVVector<HaarStage64> &h_HaarStages,
  378. NCVVector<HaarClassifierNode128> &h_HaarNodes,
  379. NCVVector<HaarFeature64> &h_HaarFeatures);
  380. //! @}
  381. #endif // _ncvhaarobjectdetection_hpp_