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