matching.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  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 methods for computing the matching between the left and right images *
  44. * *
  45. \******************************************************************************************************************/
  46. #ifndef _OPENCV_MATCHING_HPP_
  47. #define _OPENCV_MATCHING_HPP_
  48. #include <stdint.h>
  49. #include "opencv2/core.hpp"
  50. namespace cv
  51. {
  52. namespace stereo
  53. {
  54. class Matching
  55. {
  56. private:
  57. //!The maximum disparity
  58. int maxDisparity;
  59. //!the factor by which we are multiplying the disparity
  60. int scallingFactor;
  61. //!the confidence to which a min disparity found is good or not
  62. double confidenceCheck;
  63. //!the LUT used in case SSE is not available
  64. int hamLut[65537];
  65. //!function used for getting the minimum disparity from the cost volume"
  66. static int minim(short *c, int iwpj, int widthDisp,const double confidence, const int search_region)
  67. {
  68. double mini, mini2, mini3;
  69. mini = mini2 = mini3 = DBL_MAX;
  70. int index = 0;
  71. int iw = iwpj;
  72. int widthDisp2;
  73. widthDisp2 = widthDisp;
  74. widthDisp -= 1;
  75. for (int i = 0; i <= widthDisp; i++)
  76. {
  77. if (c[(iw + i * search_region) * widthDisp2 + i] < mini)
  78. {
  79. mini3 = mini2;
  80. mini2 = mini;
  81. mini = c[(iw + i * search_region) * widthDisp2 + i];
  82. index = i;
  83. }
  84. else if (c[(iw + i * search_region) * widthDisp2 + i] < mini2)
  85. {
  86. mini3 = mini2;
  87. mini2 = c[(iw + i * search_region) * widthDisp2 + i];
  88. }
  89. else if (c[(iw + i * search_region) * widthDisp2 + i] < mini3)
  90. {
  91. mini3 = c[(iw + i * search_region) * widthDisp2 + i];
  92. }
  93. }
  94. if(mini != 0)
  95. {
  96. if (mini3 / mini <= confidence)
  97. return index;
  98. }
  99. return -1;
  100. }
  101. //!Interpolate in order to obtain better results
  102. //!function for refining the disparity at sub pixel using simetric v
  103. static double symetricVInterpolation(short *c, int iwjp, int widthDisp, int winDisp,const int search_region)
  104. {
  105. if (winDisp == 0 || winDisp == widthDisp - 1)
  106. return winDisp;
  107. double m2m1, m3m1, m3, m2, m1;
  108. m2 = c[(iwjp + (winDisp - 1) * search_region) * widthDisp + winDisp - 1];
  109. m3 = c[(iwjp + (winDisp + 1) * search_region)* widthDisp + winDisp + 1];
  110. m1 = c[(iwjp + winDisp * search_region) * widthDisp + winDisp];
  111. m2m1 = m2 - m1;
  112. m3m1 = m3 - m1;
  113. if (m2m1 == 0 || m3m1 == 0) return winDisp;
  114. double p;
  115. p = 0;
  116. if (m2 > m3)
  117. {
  118. p = (0.5 - 0.25 * ((m3m1 * m3m1) / (m2m1 * m2m1) + (m3m1 / m2m1)));
  119. }
  120. else
  121. {
  122. p = -1 * (0.5 - 0.25 * ((m2m1 * m2m1) / (m3m1 * m3m1) + (m2m1 / m3m1)));
  123. }
  124. if (p >= -0.5 && p <= 0.5)
  125. p = winDisp + p;
  126. return p;
  127. }
  128. //!a pre processing function that generates the Hamming LUT in case the algorithm will ever be used on platform where SSE is not available
  129. void hammingLut()
  130. {
  131. for (int i = 0; i <= 65536; i++)
  132. {
  133. int dist = 0;
  134. int j = i;
  135. //we number the bits from our number
  136. while (j)
  137. {
  138. dist = dist + 1;
  139. j = j & (j - 1);
  140. }
  141. hamLut[i] = dist;
  142. }
  143. }
  144. //!the class used in computing the hamming distance
  145. class hammingDistance : public ParallelLoopBody
  146. {
  147. private:
  148. int *left, *right;
  149. short *c;
  150. int v,kernelSize, width;
  151. int MASK;
  152. int *hammLut;
  153. public :
  154. hammingDistance(const Mat &leftImage, const Mat &rightImage, short *cost, int maxDisp, int kerSize, int *hammingLUT):
  155. left((int *)leftImage.data), right((int *)rightImage.data), c(cost), v(maxDisp),kernelSize(kerSize),width(leftImage.cols), MASK(65535), hammLut(hammingLUT){}
  156. void operator()(const cv::Range &r) const {
  157. for (int i = r.start; i <= r.end ; i++)
  158. {
  159. int iw = i * width;
  160. for (int j = kernelSize; j < width - kernelSize; j++)
  161. {
  162. int j2;
  163. int xorul;
  164. int iwj;
  165. iwj = iw + j;
  166. for (int d = 0; d <= v; d++)
  167. {
  168. j2 = (0 > j - d) ? (0) : (j - d);
  169. xorul = left[(iwj)] ^ right[(iw + j2)];
  170. #if CV_POPCNT
  171. if (checkHardwareSupport(CV_CPU_POPCNT))
  172. {
  173. c[(iwj)* (v + 1) + d] = (short)_mm_popcnt_u32(xorul);
  174. }
  175. else
  176. #endif
  177. {
  178. c[(iwj)* (v + 1) + d] = (short)(hammLut[xorul & MASK] + hammLut[(xorul >> 16) & MASK]);
  179. }
  180. }
  181. }
  182. }
  183. }
  184. };
  185. //!cost aggregation
  186. class agregateCost:public ParallelLoopBody
  187. {
  188. private:
  189. int win;
  190. short *c, *parSum;
  191. int maxDisp,width, height;
  192. public:
  193. agregateCost(const Mat &partialSums, int windowSize, int maxDispa, Mat &cost)
  194. {
  195. win = windowSize / 2;
  196. c = (short *)cost.data;
  197. maxDisp = maxDispa;
  198. width = cost.cols / ( maxDisp + 1) - 1;
  199. height = cost.rows - 1;
  200. parSum = (short *)partialSums.data;
  201. }
  202. void operator()(const cv::Range &r) const {
  203. for (int i = r.start; i <= r.end; i++)
  204. {
  205. int iwi = (i - 1) * width;
  206. for (int j = win + 1; j <= width - win - 1; j++)
  207. {
  208. int w1 = ((i + win + 1) * width + j + win) * (maxDisp + 1);
  209. int w2 = ((i - win) * width + j - win - 1) * (maxDisp + 1);
  210. int w3 = ((i + win + 1) * width + j - win - 1) * (maxDisp + 1);
  211. int w4 = ((i - win) * width + j + win) * (maxDisp + 1);
  212. int w = (iwi + j - 1) * (maxDisp + 1);
  213. for (int d = 0; d <= maxDisp; d++)
  214. {
  215. c[w + d] = parSum[w1 + d] + parSum[w2 + d]
  216. - parSum[w3 + d] - parSum[w4 + d];
  217. }
  218. }
  219. }
  220. }
  221. };
  222. //!class that is responsable for generating the disparity map
  223. class makeMap:public ParallelLoopBody
  224. {
  225. private:
  226. //enum used to notify wether we are searching on the vertical ie (lr) or diagonal (rl)
  227. enum {CV_VERTICAL_SEARCH, CV_DIAGONAL_SEARCH};
  228. int width,disparity,scallingFact,th;
  229. double confCheck;
  230. uint8_t *map;
  231. short *c;
  232. public:
  233. makeMap(const Mat &costVolume, int threshold, int maxDisp, double confidence,int scale, Mat &mapFinal)
  234. {
  235. c = (short *)costVolume.data;
  236. map = mapFinal.data;
  237. disparity = maxDisp;
  238. width = costVolume.cols / ( disparity + 1) - 1;
  239. th = threshold;
  240. scallingFact = scale;
  241. confCheck = confidence;
  242. }
  243. void operator()(const cv::Range &r) const {
  244. for (int i = r.start; i <= r.end ; i++)
  245. {
  246. int lr;
  247. int v = -1;
  248. double p1, p2;
  249. int iw = i * width;
  250. for (int j = 0; j < width; j++)
  251. {
  252. lr = Matching:: minim(c, iw + j, disparity + 1, confCheck,CV_VERTICAL_SEARCH);
  253. if (lr != -1)
  254. {
  255. v = Matching::minim(c, iw + j - lr, disparity + 1, confCheck,CV_DIAGONAL_SEARCH);
  256. if (v != -1)
  257. {
  258. p1 = Matching::symetricVInterpolation(c, iw + j - lr, disparity + 1, v,CV_DIAGONAL_SEARCH);
  259. p2 = Matching::symetricVInterpolation(c, iw + j, disparity + 1, lr,CV_VERTICAL_SEARCH);
  260. if (abs(p1 - p2) <= th)
  261. map[iw + j] = (uint8_t)((p2)* scallingFact);
  262. else
  263. {
  264. map[iw + j] = 0;
  265. }
  266. }
  267. else
  268. {
  269. if (width - j <= disparity)
  270. {
  271. p2 = Matching::symetricVInterpolation(c, iw + j, disparity + 1, lr,CV_VERTICAL_SEARCH);
  272. map[iw + j] = (uint8_t)(p2* scallingFact);
  273. }
  274. }
  275. }
  276. else
  277. {
  278. map[iw + j] = 0;
  279. }
  280. }
  281. }
  282. }
  283. };
  284. //!median 1x9 paralelized filter
  285. template <typename T>
  286. class Median1x9:public ParallelLoopBody
  287. {
  288. private:
  289. T *original;
  290. T *filtered;
  291. int height, width;
  292. public:
  293. Median1x9(const Mat &originalImage, Mat &filteredImage)
  294. {
  295. original = (T *)originalImage.data;
  296. filtered = (T *)filteredImage.data;
  297. height = originalImage.rows;
  298. width = originalImage.cols;
  299. }
  300. void operator()(const cv::Range &r) const{
  301. for (int m = r.start; m <= r.end; m++)
  302. {
  303. for (int n = 4; n < width - 4; ++n)
  304. {
  305. int k = 0;
  306. T window[9];
  307. for (int i = n - 4; i <= n + 4; ++i)
  308. window[k++] = original[m * width + i];
  309. for (int j = 0; j < 5; ++j)
  310. {
  311. int min = j;
  312. for (int l = j + 1; l < 9; ++l)
  313. if (window[l] < window[min])
  314. min = l;
  315. const T temp = window[j];
  316. window[j] = window[min];
  317. window[min] = temp;
  318. }
  319. filtered[m * width + n] = window[4];
  320. }
  321. }
  322. }
  323. };
  324. //!median 9x1 paralelized filter
  325. template <typename T>
  326. class Median9x1:public ParallelLoopBody
  327. {
  328. private:
  329. T *original;
  330. T *filtered;
  331. int height, width;
  332. public:
  333. Median9x1(const Mat &originalImage, Mat &filteredImage)
  334. {
  335. original = (T *)originalImage.data;
  336. filtered = (T *)filteredImage.data;
  337. height = originalImage.rows;
  338. width = originalImage.cols;
  339. }
  340. void operator()(const Range &r) const{
  341. for (int n = r.start; n <= r.end; ++n)
  342. {
  343. for (int m = 4; m < height - 4; ++m)
  344. {
  345. int k = 0;
  346. T window[9];
  347. for (int i = m - 4; i <= m + 4; ++i)
  348. window[k++] = original[i * width + n];
  349. for (int j = 0; j < 5; j++)
  350. {
  351. int min = j;
  352. for (int l = j + 1; l < 9; ++l)
  353. if (window[l] < window[min])
  354. min = l;
  355. const T temp = window[j];
  356. window[j] = window[min];
  357. window[min] = temp;
  358. }
  359. filtered[m * width + n] = window[4];
  360. }
  361. }
  362. }
  363. };
  364. protected:
  365. //arrays used in the region removal
  366. Mat speckleY;
  367. Mat speckleX;
  368. Mat puss;
  369. //int *specklePointX;
  370. //int *specklePointY;
  371. //long long *pus;
  372. int previous_size;
  373. //!method for setting the maximum disparity
  374. void setMaxDisparity(int val)
  375. {
  376. CV_Assert(val > 10);
  377. this->maxDisparity = val;
  378. }
  379. //!method for getting the disparity
  380. int getMaxDisparity()
  381. {
  382. return this->maxDisparity;
  383. }
  384. //! a number by which the disparity will be multiplied for better display
  385. void setScallingFactor(int val)
  386. {
  387. CV_Assert(val > 0);
  388. this->scallingFactor = val;
  389. }
  390. //!method for getting the scalling factor
  391. int getScallingFactor()
  392. {
  393. return scallingFactor;
  394. }
  395. //!setter for the confidence check
  396. void setConfidence(double val)
  397. {
  398. CV_Assert(val >= 1);
  399. this->confidenceCheck = val;
  400. }
  401. //getter for confidence check
  402. double getConfidence()
  403. {
  404. return confidenceCheck;
  405. }
  406. //! Hamming distance computation method
  407. //! leftImage and rightImage are the two transformed images
  408. //! the cost is the resulted cost volume and kernel Size is the size of the matching window
  409. void hammingDistanceBlockMatching(const Mat &leftImage, const Mat &rightImage, Mat &cost, const int kernelSize= 9)
  410. {
  411. CV_Assert(leftImage.cols == rightImage.cols);
  412. CV_Assert(leftImage.rows == rightImage.rows);
  413. CV_Assert(kernelSize % 2 != 0);
  414. CV_Assert(cost.rows == leftImage.rows);
  415. CV_Assert(cost.cols / (maxDisparity + 1) == leftImage.cols);
  416. short *c = (short *)cost.data;
  417. memset(c, 0, sizeof(c[0]) * leftImage.cols * leftImage.rows * (maxDisparity + 1));
  418. parallel_for_(cv::Range(kernelSize / 2,leftImage.rows - kernelSize / 2), hammingDistance(leftImage,rightImage,(short *)cost.data,maxDisparity,kernelSize / 2,hamLut));
  419. }
  420. //preprocessing the cost volume in order to get it ready for aggregation
  421. void costGathering(const Mat &hammingDistanceCost, Mat &cost)
  422. {
  423. CV_Assert(hammingDistanceCost.type() == CV_16S);
  424. CV_Assert(cost.type() == CV_16S);
  425. int maxDisp = maxDisparity;
  426. int width = cost.cols / ( maxDisp + 1) - 1;
  427. int height = cost.rows - 1;
  428. short *c = (short *)cost.data;
  429. short *ham = (short *)hammingDistanceCost.data;
  430. memset(c, 0, sizeof(c[0]) * (width + 1) * (height + 1) * (maxDisp + 1));
  431. for (int i = 1; i <= height; i++)
  432. {
  433. int iw = i * width;
  434. int iwi = (i - 1) * width;
  435. for (int j = 1; j <= width; j++)
  436. {
  437. int iwj = (iw + j) * (maxDisp + 1);
  438. int iwjmu = (iw + j - 1) * (maxDisp + 1);
  439. int iwijmu = (iwi + j - 1) * (maxDisp + 1);
  440. for (int d = 0; d <= maxDisp; d++)
  441. {
  442. c[iwj + d] = ham[iwijmu + d] + c[iwjmu + d];
  443. }
  444. }
  445. }
  446. for (int i = 1; i <= height; i++)
  447. {
  448. for (int j = 1; j <= width; j++)
  449. {
  450. int iwj = (i * width + j) * (maxDisp + 1);
  451. int iwjmu = ((i - 1) * width + j) * (maxDisp + 1);
  452. for (int d = 0; d <= maxDisp; d++)
  453. {
  454. c[iwj + d] += c[iwjmu + d];
  455. }
  456. }
  457. }
  458. }
  459. //!The aggregation on the cost volume
  460. void blockAgregation(const Mat &partialSums, int windowSize, Mat &cost)
  461. {
  462. CV_Assert(windowSize % 2 != 0);
  463. CV_Assert(partialSums.rows == cost.rows);
  464. CV_Assert(partialSums.cols == cost.cols);
  465. int win = windowSize / 2;
  466. short *c = (short *)cost.data;
  467. int maxDisp = maxDisparity;
  468. int width = cost.cols / ( maxDisp + 1) - 1;
  469. int height = cost.rows - 1;
  470. memset(c, 0, sizeof(c[0]) * width * height * (maxDisp + 1));
  471. parallel_for_(cv::Range(win + 1,height - win - 1), agregateCost(partialSums,windowSize,maxDisp,cost));
  472. }
  473. //!remove small regions that have an area smaller than t, we fill the region with the average of the good pixels around it
  474. template <typename T>
  475. void smallRegionRemoval(const Mat &currentMap, int t, Mat &out)
  476. {
  477. CV_Assert(currentMap.cols == out.cols);
  478. CV_Assert(currentMap.rows == out.rows);
  479. CV_Assert(t >= 0);
  480. int *pus = (int *)puss.data;
  481. int *specklePointX = (int *)speckleX.data;
  482. int *specklePointY = (int *)speckleY.data;
  483. memset(pus, 0, previous_size * sizeof(pus[0]));
  484. T *map = (T *)currentMap.data;
  485. T *outputMap = (T *)out.data;
  486. int height = currentMap.rows;
  487. int width = currentMap.cols;
  488. T k = 1;
  489. int st, dr;
  490. int di[] = { -1, -1, -1, 0, 1, 1, 1, 0 },
  491. dj[] = { -1, 0, 1, 1, 1, 0, -1, -1 };
  492. int speckle_size = 0;
  493. st = 0;
  494. dr = 0;
  495. for (int i = 1; i < height - 1; i++)
  496. {
  497. int iw = i * width;
  498. for (int j = 1; j < width - 1; j++)
  499. {
  500. if (map[iw + j] != 0)
  501. {
  502. outputMap[iw + j] = map[iw + j];
  503. }
  504. else if (map[iw + j] == 0)
  505. {
  506. T nr = 1;
  507. T avg = 0;
  508. speckle_size = dr;
  509. specklePointX[dr] = i;
  510. specklePointY[dr] = j;
  511. pus[i * width + j] = 1;
  512. dr++;
  513. map[iw + j] = k;
  514. while (st < dr)
  515. {
  516. int ii = specklePointX[st];
  517. int jj = specklePointY[st];
  518. //going on 8 directions
  519. for (int d = 0; d < 8; d++)
  520. {//if insisde
  521. if (ii + di[d] >= 0 && ii + di[d] < height && jj + dj[d] >= 0 && jj + dj[d] < width &&
  522. pus[(ii + di[d]) * width + jj + dj[d]] == 0)
  523. {
  524. T val = map[(ii + di[d]) * width + jj + dj[d]];
  525. if (val == 0)
  526. {
  527. map[(ii + di[d]) * width + jj + dj[d]] = k;
  528. specklePointX[dr] = (ii + di[d]);
  529. specklePointY[dr] = (jj + dj[d]);
  530. dr++;
  531. pus[(ii + di[d]) * width + jj + dj[d]] = 1;
  532. }//this means that my point is a good point to be used in computing the final filling value
  533. else if (val >= 1 && val < 250)
  534. {
  535. avg += val;
  536. nr++;
  537. }
  538. }
  539. }
  540. st++;
  541. }//if hole size is smaller than a specified threshold we fill the respective hole with the average of the good neighbours
  542. if (st - speckle_size <= t)
  543. {
  544. T fillValue = (T)(avg / nr);
  545. while (speckle_size < st)
  546. {
  547. int ii = specklePointX[speckle_size];
  548. int jj = specklePointY[speckle_size];
  549. outputMap[ii * width + jj] = fillValue;
  550. speckle_size++;
  551. }
  552. }
  553. }
  554. }
  555. }
  556. }
  557. //!Method responsible for generating the disparity map
  558. //!function for generating disparity maps at sub pixel level
  559. /* costVolume - represents the cost volume
  560. * width, height - represent the width and height of the iage
  561. *disparity - represents the maximum disparity
  562. *map - is the disparity map that will result
  563. *th - is the LR threshold
  564. */
  565. void dispartyMapFormation(const Mat &costVolume, Mat &mapFinal, int th)
  566. {
  567. uint8_t *map = mapFinal.data;
  568. int disparity = maxDisparity;
  569. int width = costVolume.cols / ( disparity + 1) - 1;
  570. int height = costVolume.rows - 1;
  571. memset(map, 0, sizeof(map[0]) * width * height);
  572. parallel_for_(Range(0,height - 1), makeMap(costVolume,th,disparity,confidenceCheck,scallingFactor,mapFinal));
  573. }
  574. public:
  575. //!a median filter of 1x9 and 9x1
  576. //!1x9 median filter
  577. template<typename T>
  578. void Median1x9Filter(const Mat &originalImage, Mat &filteredImage)
  579. {
  580. CV_Assert(originalImage.rows == filteredImage.rows);
  581. CV_Assert(originalImage.cols == filteredImage.cols);
  582. parallel_for_(Range(1,originalImage.rows - 2), Median1x9<T>(originalImage,filteredImage));
  583. }
  584. //!9x1 median filter
  585. template<typename T>
  586. void Median9x1Filter(const Mat &originalImage, Mat &filteredImage)
  587. {
  588. CV_Assert(originalImage.cols == filteredImage.cols);
  589. CV_Assert(originalImage.cols == filteredImage.cols);
  590. parallel_for_(Range(1,originalImage.cols - 2), Median9x1<T>(originalImage,filteredImage));
  591. }
  592. //!constructor for the matching class
  593. //!maxDisp - represents the maximum disparity
  594. Matching(void)
  595. {
  596. hammingLut();
  597. }
  598. ~Matching(void)
  599. {
  600. }
  601. //constructor for the matching class
  602. //maxDisp - represents the maximum disparity
  603. //confidence - represents the confidence check
  604. Matching(int maxDisp, int scalling = 4, int confidence = 6)
  605. {
  606. //set the maximum disparity
  607. setMaxDisparity(maxDisp);
  608. //set scalling factor
  609. setScallingFactor(scalling);
  610. //set the value for the confidence
  611. setConfidence(confidence);
  612. //generate the hamming lut in case SSE is not available
  613. hammingLut();
  614. }
  615. };
  616. }
  617. }
  618. #endif
  619. /*End of file*/