descriptor.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. //By downloading, copying, installing or using the software you agree to this license.
  2. //If you do not agree to this license, do not download, install,
  3. //copy or use the software.
  4. //
  5. //
  6. // License Agreement
  7. // For Open Source Computer Vision Library
  8. // (3-clause BSD License)
  9. //
  10. //Copyright (C) 2000-2015, Intel Corporation, all rights reserved.
  11. //Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
  12. //Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved.
  13. //Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
  14. //Copyright (C) 2015, OpenCV Foundation, all rights reserved.
  15. //Copyright (C) 2015, Itseez Inc., all rights reserved.
  16. //Third party copyrights are property of their respective owners.
  17. //
  18. //Redistribution and use in source and binary forms, with or without modification,
  19. //are permitted provided that the following conditions are met:
  20. //
  21. // * Redistributions of source code must retain the above copyright notice,
  22. // this list of conditions and the following disclaimer.
  23. //
  24. // * Redistributions in binary form must reproduce the above copyright notice,
  25. // this list of conditions and the following disclaimer in the documentation
  26. // and/or other materials provided with the distribution.
  27. //
  28. // * Neither the names of the copyright holders nor the names of the contributors
  29. // may be used to endorse or promote products derived from this software
  30. // without specific prior written permission.
  31. //
  32. //This software is provided by the copyright holders and contributors "as is" and
  33. //any express or implied warranties, including, but not limited to, the implied
  34. //warranties of merchantability and fitness for a particular purpose are disclaimed.
  35. //In no event shall copyright holders or contributors be liable for any direct,
  36. //indirect, incidental, special, exemplary, or consequential damages
  37. //(including, but not limited to, procurement of substitute goods or services;
  38. //loss of use, data, or profits; or business interruption) however caused
  39. //and on any theory of liability, whether in contract, strict liability,
  40. //or tort (including negligence or otherwise) arising in any way out of
  41. //the use of this software, even if advised of the possibility of such damage.
  42. /*****************************************************************************************************************\
  43. * The interface contains the main descriptors that will be implemented in the descriptor class *
  44. \*****************************************************************************************************************/
  45. #include <stdint.h>
  46. #ifndef _OPENCV_DESCRIPTOR_HPP_
  47. #define _OPENCV_DESCRIPTOR_HPP_
  48. #ifdef __cplusplus
  49. namespace cv
  50. {
  51. namespace stereo
  52. {
  53. //types of supported kernels
  54. enum {
  55. CV_DENSE_CENSUS, CV_SPARSE_CENSUS,
  56. CV_CS_CENSUS, CV_MODIFIED_CS_CENSUS, CV_MODIFIED_CENSUS_TRANSFORM,
  57. CV_MEAN_VARIATION, CV_STAR_KERNEL
  58. };
  59. //!Mean Variation is a robust kernel that compares a pixel
  60. //!not just with the center but also with the mean of the window
  61. template<int num_images>
  62. struct MVKernel
  63. {
  64. uint8_t *image[num_images];
  65. int *integralImage[num_images];
  66. int stop;
  67. MVKernel(){}
  68. MVKernel(uint8_t **images, int **integral)
  69. {
  70. for(int i = 0; i < num_images; i++)
  71. {
  72. image[i] = images[i];
  73. integralImage[i] = integral[i];
  74. }
  75. stop = num_images;
  76. }
  77. void operator()(int rrWidth,int w2, int rWidth, int jj, int j, int c[num_images]) const
  78. {
  79. (void)w2;
  80. for (int i = 0; i < stop; i++)
  81. {
  82. if (image[i][rrWidth + jj] > image[i][rWidth + j])
  83. {
  84. c[i] = c[i] + 1;
  85. }
  86. c[i] = c[i] << 1;
  87. if (integralImage[i][rrWidth + jj] > image[i][rWidth + j])
  88. {
  89. c[i] = c[i] + 1;
  90. }
  91. c[i] = c[i] << 1;
  92. }
  93. }
  94. };
  95. //!Compares pixels from a patch giving high weights to pixels in which
  96. //!the intensity is higher. The other pixels receive a lower weight
  97. template <int num_images>
  98. struct MCTKernel
  99. {
  100. uint8_t *image[num_images];
  101. int t,imageStop;
  102. MCTKernel(){}
  103. MCTKernel(uint8_t ** images, int threshold)
  104. {
  105. for(int i = 0; i < num_images; i++)
  106. {
  107. image[i] = images[i];
  108. }
  109. imageStop = num_images;
  110. t = threshold;
  111. }
  112. void operator()(int rrWidth,int w2, int rWidth, int jj, int j, int c[num_images]) const
  113. {
  114. (void)w2;
  115. for(int i = 0; i < imageStop; i++)
  116. {
  117. if (image[i][rrWidth + jj] > image[i][rWidth + j] - t)
  118. {
  119. c[i] = c[i] << 1;
  120. c[i] = c[i] + 1;
  121. c[i] = c[i] << 1;
  122. c[i] = c[i] + 1;
  123. }
  124. else if (image[i][rWidth + j] - t < image[i][rrWidth + jj] && image[i][rWidth + j] + t >= image[i][rrWidth + jj])
  125. {
  126. c[i] = c[i] << 2;
  127. c[i] = c[i] + 1;
  128. }
  129. else
  130. {
  131. c[i] <<= 2;
  132. }
  133. }
  134. }
  135. };
  136. //!A madified cs census that compares a pixel with the imediat neightbour starting
  137. //!from the center
  138. template<int num_images>
  139. struct ModifiedCsCensus
  140. {
  141. uint8_t *image[num_images];
  142. int n2;
  143. int imageStop;
  144. ModifiedCsCensus(){}
  145. ModifiedCsCensus(uint8_t **images, int ker)
  146. {
  147. for(int i = 0; i < num_images; i++)
  148. image[i] = images[i];
  149. imageStop = num_images;
  150. n2 = ker;
  151. }
  152. void operator()(int rrWidth,int w2, int rWidth, int jj, int j, int c[num_images]) const
  153. {
  154. (void)j;
  155. (void)rWidth;
  156. for(int i = 0; i < imageStop; i++)
  157. {
  158. if (image[i][(rrWidth + jj)] > image[i][(w2 + (jj + n2))])
  159. {
  160. c[i] = c[i] + 1;
  161. }
  162. c[i] = c[i] * 2;
  163. }
  164. }
  165. };
  166. //!A kernel in which a pixel is compared with the center of the window
  167. template<int num_images>
  168. struct CensusKernel
  169. {
  170. uint8_t *image[num_images];
  171. int imageStop;
  172. CensusKernel(){}
  173. CensusKernel(uint8_t **images)
  174. {
  175. for(int i = 0; i < num_images; i++)
  176. image[i] = images[i];
  177. imageStop = num_images;
  178. }
  179. void operator()(int rrWidth,int w2, int rWidth, int jj, int j, int c[num_images]) const
  180. {
  181. (void)w2;
  182. for(int i = 0; i < imageStop; i++)
  183. {
  184. ////compare a pixel with the center from the kernel
  185. if (image[i][rrWidth + jj] > image[i][rWidth + j])
  186. {
  187. c[i] += 1;
  188. }
  189. c[i] <<= 1;
  190. }
  191. }
  192. };
  193. //template clas which efficiently combines the descriptors
  194. template <int step_start, int step_end, int step_inc,int nr_img, typename Kernel>
  195. class CombinedDescriptor:public ParallelLoopBody
  196. {
  197. private:
  198. int width, height,n2;
  199. int stride_;
  200. int *dst[nr_img];
  201. Kernel kernel_;
  202. int n2_stop;
  203. public:
  204. CombinedDescriptor(int w, int h,int stride, int k2, int **distance, Kernel kernel,int k2Stop)
  205. {
  206. width = w;
  207. height = h;
  208. n2 = k2;
  209. stride_ = stride;
  210. for(int i = 0; i < nr_img; i++)
  211. dst[i] = distance[i];
  212. kernel_ = kernel;
  213. n2_stop = k2Stop;
  214. }
  215. void operator()(const cv::Range &r) const {
  216. for (int i = r.start; i <= r.end ; i++)
  217. {
  218. int rWidth = i * stride_;
  219. for (int j = n2 + 2; j <= width - n2 - 2; j++)
  220. {
  221. int c[nr_img];
  222. memset(c,0,nr_img);
  223. for(int step = step_start; step <= step_end; step += step_inc)
  224. {
  225. for (int ii = - n2; ii <= + n2_stop; ii += step)
  226. {
  227. int rrWidth = (ii + i) * stride_;
  228. int rrWidthC = (ii + i + n2) * stride_;
  229. for (int jj = j - n2; jj <= j + n2; jj += step)
  230. {
  231. if (ii != i || jj != j)
  232. {
  233. kernel_(rrWidth,rrWidthC, rWidth, jj, j,c);
  234. }
  235. }
  236. }
  237. }
  238. for(int l = 0; l < nr_img; l++)
  239. dst[l][rWidth + j] = c[l];
  240. }
  241. }
  242. }
  243. };
  244. //!calculate the mean of every windowSizexWindwoSize block from the integral Image
  245. //!this is a preprocessing for MV kernel
  246. class MeanKernelIntegralImage : public ParallelLoopBody
  247. {
  248. private:
  249. int *img;
  250. int windowSize,width;
  251. float scalling;
  252. int *c;
  253. public:
  254. MeanKernelIntegralImage(const cv::Mat &image, int window,float scale, int *cost):
  255. img((int *)image.data),windowSize(window) ,width(image.cols) ,scalling(scale) , c(cost){};
  256. void operator()(const cv::Range &r) const{
  257. for (int i = r.start; i <= r.end; i++)
  258. {
  259. int iw = i * width;
  260. for (int j = windowSize + 1; j <= width - windowSize - 1; j++)
  261. {
  262. c[iw + j] = (int)((img[(i + windowSize - 1) * width + j + windowSize - 1] + img[(i - windowSize - 1) * width + j - windowSize - 1]
  263. - img[(i + windowSize) * width + j - windowSize] - img[(i - windowSize) * width + j + windowSize]) * scalling);
  264. }
  265. }
  266. }
  267. };
  268. //!implementation for the star kernel descriptor
  269. template<int num_images>
  270. class StarKernelCensus:public ParallelLoopBody
  271. {
  272. private:
  273. uint8_t *image[num_images];
  274. int *dst[num_images];
  275. int n2, width, height, im_num,stride_;
  276. public:
  277. StarKernelCensus(const cv::Mat *img, int k2, int **distance)
  278. {
  279. for(int i = 0; i < num_images; i++)
  280. {
  281. image[i] = img[i].data;
  282. dst[i] = distance[i];
  283. }
  284. n2 = k2;
  285. width = img[0].cols;
  286. height = img[0].rows;
  287. im_num = num_images;
  288. stride_ = (int)img[0].step;
  289. }
  290. void operator()(const cv::Range &r) const {
  291. for (int i = r.start; i <= r.end ; i++)
  292. {
  293. int rWidth = i * stride_;
  294. for (int j = n2; j <= width - n2; j++)
  295. {
  296. for(int d = 0 ; d < im_num; d++)
  297. {
  298. int c = 0;
  299. for(int step = 4; step > 0; step--)
  300. {
  301. for (int ii = i - step; ii <= i + step; ii += step)
  302. {
  303. int rrWidth = ii * stride_;
  304. for (int jj = j - step; jj <= j + step; jj += step)
  305. {
  306. if (image[d][rrWidth + jj] > image[d][rWidth + j])
  307. {
  308. c = c + 1;
  309. }
  310. c = c * 2;
  311. }
  312. }
  313. }
  314. for (int ii = -1; ii <= +1; ii++)
  315. {
  316. int rrWidth = (ii + i) * stride_;
  317. if (i == -1)
  318. {
  319. if (ii + i != i)
  320. {
  321. if (image[d][rrWidth + j] > image[d][rWidth + j])
  322. {
  323. c = c + 1;
  324. }
  325. c = c * 2;
  326. }
  327. }
  328. else if (i == 0)
  329. {
  330. for (int j2 = -1; j2 <= 1; j2 += 2)
  331. {
  332. if (ii + i != i)
  333. {
  334. if (image[d][rrWidth + j + j2] > image[d][rWidth + j])
  335. {
  336. c = c + 1;
  337. }
  338. c = c * 2;
  339. }
  340. }
  341. }
  342. else
  343. {
  344. if (ii + i != i)
  345. {
  346. if (image[d][rrWidth + j] > image[d][rWidth + j])
  347. {
  348. c = c + 1;
  349. }
  350. c = c * 2;
  351. }
  352. }
  353. }
  354. dst[d][rWidth + j] = c;
  355. }
  356. }
  357. }
  358. }
  359. };
  360. //!paralel implementation of the center symetric census
  361. template <int num_images>
  362. class SymetricCensus:public ParallelLoopBody
  363. {
  364. private:
  365. uint8_t *image[num_images];
  366. int *dst[num_images];
  367. int n2, width, height, im_num,stride_;
  368. public:
  369. SymetricCensus(const cv::Mat *img, int k2, int **distance)
  370. {
  371. for(int i = 0; i < num_images; i++)
  372. {
  373. image[i] = img[i].data;
  374. dst[i] = distance[i];
  375. }
  376. n2 = k2;
  377. width = img[0].cols;
  378. height = img[0].rows;
  379. im_num = num_images;
  380. stride_ = (int)img[0].step;
  381. }
  382. void operator()(const cv::Range &r) const {
  383. for (int i = r.start; i <= r.end ; i++)
  384. {
  385. int distV = i*stride_;
  386. for (int j = n2; j <= width - n2; j++)
  387. {
  388. for(int d = 0; d < im_num; d++)
  389. {
  390. int c = 0;
  391. //the classic center symetric census which compares the curent pixel with its symetric not its center.
  392. for (int ii = -n2; ii <= 0; ii++)
  393. {
  394. int rrWidth = (ii + i) * stride_;
  395. for (int jj = -n2; jj <= +n2; jj++)
  396. {
  397. if (image[d][(rrWidth + (jj + j))] > image[d][((ii * (-1) + i) * width + (-1 * jj) + j)])
  398. {
  399. c = c + 1;
  400. }
  401. c = c * 2;
  402. if(ii == 0 && jj < 0)
  403. {
  404. if (image[d][(i * width + (jj + j))] > image[d][(i * width + (-1 * jj) + j)])
  405. {
  406. c = c + 1;
  407. }
  408. c = c * 2;
  409. }
  410. }
  411. }
  412. dst[d][(distV + j)] = c;
  413. }
  414. }
  415. }
  416. }
  417. };
  418. /**
  419. Two variations of census applied on input images
  420. Implementation of a census transform which is taking into account just the some pixels from the census kernel thus allowing for larger block sizes
  421. **/
  422. //void applyCensusOnImages(const cv::Mat &im1,const cv::Mat &im2, int kernelSize, cv::Mat &dist, cv::Mat &dist2, const int type);
  423. CV_EXPORTS void censusTransform(const cv::Mat &image1, const cv::Mat &image2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
  424. //single image census transform
  425. CV_EXPORTS void censusTransform(const cv::Mat &image1, int kernelSize, cv::Mat &dist1, const int type);
  426. /**
  427. STANDARD_MCT - Modified census which is memorizing for each pixel 2 bits and includes a tolerance to the pixel comparison
  428. MCT_MEAN_VARIATION - Implementation of a modified census transform which is also taking into account the variation to the mean of the window not just the center pixel
  429. **/
  430. CV_EXPORTS void modifiedCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2, const int type, int t = 0 , const cv::Mat &IntegralImage1 = cv::Mat::zeros(100,100,CV_8UC1), const cv::Mat &IntegralImage2 = cv::Mat::zeros(100,100,CV_8UC1));
  431. //single version of modified census transform descriptor
  432. CV_EXPORTS void modifiedCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist, const int type, int t = 0 ,const cv::Mat &IntegralImage = cv::Mat::zeros(100,100,CV_8UC1));
  433. /**The classical center symetric census
  434. A modified version of cs census which is comparing a pixel with its correspondent after the center
  435. **/
  436. CV_EXPORTS void symetricCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1, cv::Mat &dist2, const int type);
  437. //single version of census transform
  438. CV_EXPORTS void symetricCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist1, const int type);
  439. //in a 9x9 kernel only certain positions are choosen
  440. CV_EXPORTS void starCensusTransform(const cv::Mat &img1, const cv::Mat &img2, int kernelSize, cv::Mat &dist1,cv::Mat &dist2);
  441. //single image version of star kernel
  442. CV_EXPORTS void starCensusTransform(const cv::Mat &img1, int kernelSize, cv::Mat &dist);
  443. //integral image computation used in the Mean Variation Census Transform
  444. void imageMeanKernelSize(const cv::Mat &img, int windowSize, cv::Mat &c);
  445. }
  446. }
  447. #endif
  448. #endif
  449. /*End of file*/