MSERCalculation.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "MSERCalculation.h"
26
27
28// IVT
29#include <Calibration/Calibration.h>
30#include <Calibration/StereoCalibration.h>
31#include <Image/ByteImage.h>
32#include <Image/ImageProcessor.h>
33#include <Image/IplImageAdaptor.h>
34
35// system
36#include <cmath>
37#include <ctime>
38#include <opencv2/core/version.hpp>
39
40//#include <ArmarXCore/core/logging/Logging.h>
41
42
46
50
51void
52CMSERCalculation::FindMSERs2D(const CByteImage* pRGBImage,
53 const CByteImage* pHSVImage,
54 std::vector<CMSERDescriptor*>& aMSERDescriptors)
55{
56#if (CV_MAJOR_VERSION == 2)
57#if (CV_MINOR_VERSION < 4)
58 //timeval tStart, tEnd;
59 //long tTimeDiff;
60 //gettimeofday(&tStart, 0);
61
62 // int delta; //! delta, in the code, it compares (size_{i}-size_{i-delta})/size_{i-delta}
63 // int maxArea; //! prune the area which bigger than maxArea
64 // int minArea; //! prune the area which smaller than minArea
65 // float maxVariation; //! prune the area have simliar size to its children
66 // float minDiversity; //! trace back to cut off mser with diversity < min_diversity
67 // The next few params for MSER of color image:
68 // int maxEvolution; //! for color image, the evolution steps
69 // double areaThreshold; //! the area threshold to cause re-initialize
70 // double minMargin; //! ignore too small margin
71 // int edgeBlurSize; //! the aperture size for edge blur
72
73 cv::MSER pMSERDetector = cv::MSER();
74
75 // ARMARX_VERBOSE_S << "delta: %d maxArea: %d minArea: %d maxVariation: %.3f minDiversity: %.3f maxEvolution: %d areaThreshold: %.4f minMargin: %.4f edgeBlurSize: %d\n",
76 // pMSERDetector.delta, pMSERDetector.maxArea, pMSERDetector.minArea, pMSERDetector.maxVariation, pMSERDetector.minDiversity,
77 // pMSERDetector.maxEvolution, pMSERDetector.areaThreshold, pMSERDetector.minMargin, pMSERDetector.edgeBlurSize);
78
79 pMSERDetector.maxArea *= 10;
80 pMSERDetector.maxVariation *= 3;
81 pMSERDetector.maxEvolution *= 3;
82 pMSERDetector.minMargin *= 0.33;
83
84 // convert image
85 IplImage* pIplImage;
86 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
87
88 std::vector<std::vector<cv::Point>> aContoursCVLeft;
89 std::vector<std::vector<Vec2d>> aContoursLeft;
90
91 //pMSERDetector(pIplImageLeft, aContoursCV, cv::Mat());
92
93 cv::Seq<CvSeq*> contoursLeft;
94 cv::MemStorage storageLeft(cvCreateMemStorage(0));
95 cvExtractMSER(pIplImage, NULL, &contoursLeft.seq, storageLeft, pMSERDetector);
96
97 cv::SeqIterator<CvSeq*> itLeft = contoursLeft.begin();
98 size_t i, ncontours = contoursLeft.size();
99 aContoursCVLeft.resize(ncontours);
100
101 for (i = 0; i < ncontours; i++, ++itLeft)
102 {
103 while (cv::Seq<cv::Point>(*itLeft).size() > 0)
104 {
105 aContoursCVLeft[i].push_back(cv::Seq<cv::Point>(*itLeft).front());
106 cv::Seq<cv::Point>(*itLeft).pop_front();
107 }
108 }
109
110 //storage.release();
111
112 //std::vector<CMSERDescriptor*> aMSERDescriptorsLeft;
113 for (int i = 0; i < (int)aContoursCVLeft.size(); i++)
114 {
115 std::vector<Vec2d> aPoints;
116 aContoursLeft.push_back(aPoints);
117
118 for (int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
119 {
120 Vec2d vTemp = {(float)aContoursCVLeft.at(i).at(j).x,
121 (float)aContoursCVLeft.at(i).at(j).y};
122 aContoursLeft.at(i).push_back(vTemp);
123 }
124 }
125
126 //gettimeofday(&tEnd, 0);
127 //tTimeDiff = (1000*tEnd.tv_sec+tEnd.tv_usec/1000) - (1000*tStart.tv_sec+tStart.tv_usec/1000);
128 //ARMARX_VERBOSE_S << "\nTime for 2D MSER detection: %d ms\n\n", tTimeDiff);
129 //
130 //gettimeofday(&tStart, 0);
131
132 for (int i = 0; i < (int)aContoursLeft.size(); i++)
133 {
134 CMSERDescriptor* pDescriptor = CreateMSERDescriptor(&aContoursLeft.at(i), pHSVImage);
135 aMSERDescriptors.push_back(pDescriptor);
136 //ARMARX_VERBOSE_S << "\nCenter: (%.1f,%.1f) \nEW1: %.1f EV1: (%.3f, %.3f) \nEW2: %.1f EV2: (%.3f, %.3f) \n\n",
137 // pDescriptor->vMean.x, pDescriptor->vMean.y,
138 // sqrtf(pDescriptor->fEigenvalue1), pDescriptor->vEigenvector1.x, pDescriptor->vEigenvector1.y,
139 // sqrtf(pDescriptor->fEigenvalue2), pDescriptor->vEigenvector2.x, pDescriptor->vEigenvector2.y);
140 }
141
142 //gettimeofday(&tEnd, 0);
143 //tTimeDiff = (1000*tEnd.tv_sec+tEnd.tv_usec/1000) - (1000*tStart.tv_sec+tStart.tv_usec/1000);
144 //ARMARX_VERBOSE_S << "\nTime for MSER descriptor creation: %d ms\n\n", tTimeDiff);
145
146 cvReleaseImageHeader(&pIplImage);
147 storageLeft.release();
148
149#elif (CV_MINOR_VERSION == 4)
150 cv::MSER pMSERDetector = cv::MSER();
151 IplImage* pIplImage;
152 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
153 std::vector<std::vector<cv::Point>> aContoursCVLeft;
154
155 pMSERDetector(pIplImage, aContoursCVLeft, cv::Mat());
156
157 std::vector<std::vector<Vec2d>> aContoursLeft;
158
159 for (int i = 0; i < (int)aContoursCVLeft.size(); i++)
160 {
161 std::vector<Vec2d> aPoints;
162 aContoursLeft.push_back(aPoints);
163
164 for (int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
165 {
166 Vec2d vTemp = {(float)aContoursCVLeft.at(i).at(j).x,
167 (float)aContoursCVLeft.at(i).at(j).y};
168 aContoursLeft.at(i).push_back(vTemp);
169 }
170 }
171
172 for (int i = 0; i < (int)aContoursLeft.size(); i++)
173 {
174 CMSERDescriptor* pDescriptor = CreateMSERDescriptor(&aContoursLeft.at(i), pHSVImage);
175 aMSERDescriptors.push_back(pDescriptor);
176 }
177
178 cvReleaseImageHeader(&pIplImage);
179#else
180 ARMARX_WARNING_S << "This code is not implemented for OpenCV Version " << CV_VERSION
181 << " (CV_MINOR_VERSION = " << CV_MINOR_VERSION << ")";
182#endif
183#else
184 ARMARX_WARNING_S << "This code is not implemented for OpenCV Version " << CV_VERSION
185 << " (CV_MAJOR_VERSION = " << CV_MAJOR_VERSION << ")";
186#endif
187}
188
189void
190CMSERCalculation::StereoMatchMSERs(const std::vector<CMSERDescriptor*>& aMSERDescriptorsLeft,
191 const std::vector<CMSERDescriptor*>& aMSERDescriptorsRight,
192 CStereoCalibration* pStereoCalibration,
193 const float fToleranceFactor,
194 std::vector<CMSERDescriptor3D*>& aRegions3D)
195{
196 // find stereo correspondences
197 const float fRatioThresholdHigh = 1.0f + fToleranceFactor * 0.25f; // 1.25
198 const float fRatioThresholdLow = 1.0f / fRatioThresholdHigh;
199 const float fRatioThresholdHigh2 = fRatioThresholdHigh * fRatioThresholdHigh;
200 const float fRatioThresholdLow2 = fRatioThresholdLow * fRatioThresholdLow;
201
202 for (int i = 0; i < (int)aMSERDescriptorsLeft.size(); i++)
203 {
204 float fMinEpipolarDistance = fToleranceFactor * 2.0f; // 2
205 int nCorrespondenceIndex = -1;
206 const float fOwnEVRatio =
207 aMSERDescriptorsLeft.at(i)->fEigenvalue2 / aMSERDescriptorsLeft.at(i)->fEigenvalue1;
208
209 for (int j = 0; j < (int)aMSERDescriptorsRight.size(); j++)
210 {
211 const float fSizeRatio = (float)aMSERDescriptorsLeft.at(i)->nSize /
212 (float)aMSERDescriptorsRight.at(j)->nSize;
213
214 if ((fRatioThresholdLow < fSizeRatio) && (fSizeRatio < fRatioThresholdHigh))
215 {
216 const float fEV1Ratio = aMSERDescriptorsLeft.at(i)->fEigenvalue1 /
217 aMSERDescriptorsRight.at(j)->fEigenvalue1;
218 const float fEV2Ratio = aMSERDescriptorsLeft.at(i)->fEigenvalue2 /
219 aMSERDescriptorsRight.at(j)->fEigenvalue2;
220 const float fRatioRatio = (aMSERDescriptorsRight.at(j)->fEigenvalue2 /
221 aMSERDescriptorsRight.at(j)->fEigenvalue1) /
222 fOwnEVRatio;
223
224 if ((fRatioThresholdLow2 < fEV1Ratio) && (fEV1Ratio < fRatioThresholdHigh2) &&
225 (fRatioThresholdLow2 < fEV2Ratio) && (fEV2Ratio < fRatioThresholdHigh2) &&
226 (fRatioThresholdLow2 < fRatioRatio) && (fRatioRatio < fRatioThresholdHigh2))
227 {
228 const float fEpipolarDistance =
229 fabsf(pStereoCalibration->CalculateEpipolarLineInLeftImageDistance(
230 aMSERDescriptorsLeft.at(i)->vMean, aMSERDescriptorsRight.at(j)->vMean));
231
232 if (fEpipolarDistance < fMinEpipolarDistance)
233 {
234 Vec3d vPoint3D;
235 pStereoCalibration->Calculate3DPoint(aMSERDescriptorsLeft.at(i)->vMean,
236 aMSERDescriptorsRight.at(j)->vMean,
237 vPoint3D,
238 false,
239 false);
240
241 if (vPoint3D.z < OLP_MAX_OBJECT_DISTANCE)
242 {
243 fMinEpipolarDistance = fEpipolarDistance;
244 nCorrespondenceIndex = j;
245 }
246 }
247 }
248 }
249 }
250
251 if (nCorrespondenceIndex != -1)
252 {
253 CMSERDescriptor3D* pDescr3D =
254 CreateMSERDescriptor3D(aMSERDescriptorsLeft.at(i),
255 aMSERDescriptorsRight.at(nCorrespondenceIndex),
256 pStereoCalibration);
257 aRegions3D.push_back(pDescr3D);
258 }
259 }
260}
261
262void
263CMSERCalculation::FindMSERs3D(const CByteImage* pByteImageLeft,
264 const CByteImage* pByteImageRight,
265 CStereoCalibration* pStereoCalibration,
266 const float fToleranceFactor,
267 std::vector<CMSERDescriptor3D*>& aRegions3D)
268{
269 //CByteImage* pByteImageLeftGrey = new CByteImage(pByteImageLeft->width, pByteImageLeft->height, CByteImage::eGrayScale);
270 //ImageProcessor::ConvertImage(pByteImageLeft, pByteImageLeftGrey);
271
272 // create HSV images
273 CByteImage* pHSVImageLeft = new CByteImage(OLP_IMG_WIDTH, OLP_IMG_HEIGHT, CByteImage::eRGB24);
274 CByteImage* pHSVImageRight = new CByteImage(OLP_IMG_WIDTH, OLP_IMG_HEIGHT, CByteImage::eRGB24);
275 ImageProcessor::CalculateHSVImage(pByteImageLeft, pHSVImageLeft);
276 ImageProcessor::CalculateHSVImage(pByteImageRight, pHSVImageRight);
277
278 //timeval tStart, tEnd;
279 //long tTimeDiff;
280 //gettimeofday(&tStart, 0);
281
282 // find MSERs in left and right image
283 std::vector<CMSERDescriptor*> aMSERDescriptorsLeft;
284 std::vector<CMSERDescriptor*> aMSERDescriptorsRight;
285 FindMSERs2D(pByteImageLeft, pHSVImageLeft, aMSERDescriptorsLeft);
286 FindMSERs2D(pByteImageRight, pHSVImageRight, aMSERDescriptorsRight);
287
288
289 // find stereo correspondences
290 StereoMatchMSERs(aMSERDescriptorsLeft,
291 aMSERDescriptorsRight,
292 pStereoCalibration,
293 fToleranceFactor,
294 aRegions3D);
295
296
297 //// debug
298 //for (int i=0; i<(int)aRegions3D.size() && i<5; i++)
299 //{
300 // ARMARX_VERBOSE_S << "Region %d: histogram distance left-right %.4f\n", i, HistogramDistanceL2(aRegions3D.at(i)->pRegionLeft, aRegions3D.at(i)->pRegionRight));
301 // ARMARX_VERBOSE_S << "\nHistogram region %d inner points:\n", i);
302 // for (int j=0; j<OLP_SIZE_MSER_HISTOGRAM; j++)
303 // {
304 // ARMARX_VERBOSE_S << "%d\t", (int)(aRegions3D.at(i)->pRegionLeft->pHueHistogramInnerPoints[j] * 1000));
305 // }
306 // ARMARX_VERBOSE_S << "\nHistogram region %d surrounding region:\n", i);
307 // for (int j=0; j<OLP_SIZE_MSER_HISTOGRAM; j++)
308 // {
309 // ARMARX_VERBOSE_S << "%d\t", (int)(aRegions3D.at(i)->pRegionLeft->pHueHistogramSurroundingRegion[j] * 1000));
310 // }
311 // ARMARX_VERBOSE_S << "\n\n");
312 //}
313
314
315 //gettimeofday(&tEnd, 0);
316 //tTimeDiff = (1000*tEnd.tv_sec+tEnd.tv_usec/1000) - (1000*tStart.tv_sec+tStart.tv_usec/1000);
317 //ARMARX_VERBOSE_S << "\nTime for MSER detection and stereo matching: %d ms\n\n", tTimeDiff);
318
319 for (size_t i = 0; i < aMSERDescriptorsLeft.size(); i++)
320 {
321 aMSERDescriptorsLeft.at(i)->pPoints2D->clear();
322 delete aMSERDescriptorsLeft.at(i)->pPoints2D;
323 delete aMSERDescriptorsLeft.at(i);
324 }
325
326 for (size_t i = 0; i < aMSERDescriptorsRight.size(); i++)
327 {
328 aMSERDescriptorsRight.at(i)->pPoints2D->clear();
329 delete aMSERDescriptorsRight.at(i)->pPoints2D;
330 delete aMSERDescriptorsRight.at(i);
331 }
332
333
334 delete pHSVImageLeft;
335 delete pHSVImageRight;
336
337 //ARMARX_VERBOSE_S << "\n%d 3D-MSERs found.\n\n", aRegions3D.size());
338}
339
340void
341CMSERCalculation::GetMeanAndCovariance2D(std::vector<Vec2d>& aPoints2D,
342 Vec2d& vMean,
343 Mat2d& mCovariance)
344{
345 mCovariance.r1 = 0;
346 mCovariance.r2 = 0;
347 mCovariance.r3 = 0;
348 mCovariance.r4 = 0;
349
350 if (aPoints2D.size() < 2)
351 {
352 return;
353 }
354
355 vMean.x = 0;
356 vMean.y = 0;
357
358 for (int i = 0; i < (int)aPoints2D.size(); i++)
359 {
360 vMean.x += (float)aPoints2D.at(i).x;
361 vMean.y += (float)aPoints2D.at(i).y;
362 }
363
364 vMean.x /= aPoints2D.size();
365 vMean.y /= aPoints2D.size();
366
367 for (int i = 0; i < (int)aPoints2D.size(); i++)
368 {
369 mCovariance.r1 +=
370 (vMean.x - (float)aPoints2D.at(i).x) * (vMean.x - (float)aPoints2D.at(i).x);
371 mCovariance.r2 +=
372 (vMean.x - (float)aPoints2D.at(i).x) * (vMean.y - (float)aPoints2D.at(i).y);
373 mCovariance.r4 +=
374 (vMean.y - (float)aPoints2D.at(i).y) * (vMean.y - (float)aPoints2D.at(i).y);
375 }
376
377 mCovariance.r1 /= aPoints2D.size() - 1;
378 mCovariance.r2 /= aPoints2D.size() - 1;
379 mCovariance.r3 = mCovariance.r2;
380 mCovariance.r4 /= aPoints2D.size() - 1;
381}
382
383void
385 float& fLambda1,
386 float& fLambda2,
387 Vec2d& vE1,
388 Vec2d& vE2)
389{
390 float fTemp1 = 0.5f * (mMatrix2D.r1 + mMatrix2D.r4);
391 float fTemp2 =
392 sqrtf(fTemp1 * fTemp1 - mMatrix2D.r1 * mMatrix2D.r4 + mMatrix2D.r2 * mMatrix2D.r3);
393
394 fLambda1 = fTemp1 + fTemp2;
395 fLambda2 = fTemp1 - fTemp2;
396
397 vE1.x = fLambda1 - mMatrix2D.r4;
398 vE1.y = mMatrix2D.r3;
399 Math2d::NormalizeVec(vE1);
400
401 vE2.x = fLambda2 - mMatrix2D.r4;
402 vE2.y = mMatrix2D.r3;
403 Math2d::NormalizeVec(vE2);
404}
405
407CMSERCalculation::CreateMSERDescriptor(std::vector<Vec2d>* aPoints2D, const CByteImage* pHSVImage)
408{
409 if (aPoints2D->size() < 2)
410 {
411 return NULL;
412 }
413
414 CMSERDescriptor* pDescr = new CMSERDescriptor();
415
416 pDescr->nSize = (int)aPoints2D->size();
417
418 pDescr->pPoints2D = new std::vector<Vec2d>;
419
420 for (int i = 0; i < (int)aPoints2D->size(); i++)
421 {
422 pDescr->pPoints2D->push_back(aPoints2D->at(i));
423 }
424
425
426 Mat2d mCovariance;
427 GetMeanAndCovariance2D(*aPoints2D, pDescr->vMean, mCovariance);
428
430 pDescr->fEigenvalue1,
431 pDescr->fEigenvalue2,
432 pDescr->vEigenvector1,
433 pDescr->vEigenvector2);
434
435 CreateHSVHistograms(pDescr, pHSVImage);
436
437 return pDescr;
438}
439
442 CMSERDescriptor* pMSERRight,
443 CStereoCalibration* pStereoCalibration)
444{
445 CMSERDescriptor3D* pDescr3D = new CMSERDescriptor3D();
446
447
448 pDescr3D->pRegionLeft = pMSERLeft->GetCopy();
449 //pDescr3D->pRegionLeft = new CMSERDescriptor();
450 //*(pDescr3D->pRegionLeft) = *pMSERLeft;
451 //std::vector<Vec2d>* pPoints2D = new std::vector<Vec2d>();
452 //for (int k=0; k<(int)pMSERLeft->pPoints2D->size(); k++)
453 //{
454 // pPoints2D->push_back(pMSERLeft->pPoints2D->at(k));
455 //}
456 //pDescr3D->pRegionLeft->pPoints2D = pPoints2D;
457
458 pDescr3D->pRegionRight = pMSERRight->GetCopy();
459 //pDescr3D->pRegionRight = new CMSERDescriptor();
460 //*(pDescr3D->pRegionRight)= *pMSERRight;
461 //pPoints2D = new std::vector<Vec2d>();
462 //for (int k=0; k<(int)pMSERRight->pPoints2D->size(); k++)
463 //{
464 // pPoints2D->push_back(pMSERRight->pPoints2D->at(k));
465 //}
466 //pDescr3D->pRegionRight->pPoints2D = pPoints2D;
467
468
469 pStereoCalibration->Calculate3DPoint(
470 pMSERLeft->vMean, pMSERRight->vMean, pDescr3D->vPosition, false, false);
471
472
473 Vec2d vSigmaPointLeft, vSigmaPointRight, vTemp;
474
475 const float fSigmaPointFactor = 1.0f;
476
477 Math2d::MulVecScalar(
478 pMSERLeft->vEigenvector1, -fSigmaPointFactor * sqrtf(pMSERLeft->fEigenvalue1), vTemp);
479 Math2d::AddVecVec(pMSERLeft->vMean, vTemp, vSigmaPointLeft);
480 Math2d::MulVecScalar(
481 pMSERRight->vEigenvector1, -fSigmaPointFactor * sqrtf(pMSERRight->fEigenvalue1), vTemp);
482 Math2d::AddVecVec(pMSERRight->vMean, vTemp, vSigmaPointRight);
483 pStereoCalibration->Calculate3DPoint(
484 vSigmaPointLeft, vSigmaPointRight, pDescr3D->vSigmaPoint1a, false, false);
485
486 Math2d::MulVecScalar(
487 pMSERLeft->vEigenvector1, fSigmaPointFactor * sqrtf(pMSERLeft->fEigenvalue1), vTemp);
488 Math2d::AddVecVec(pMSERLeft->vMean, vTemp, vSigmaPointLeft);
489 Math2d::MulVecScalar(
490 pMSERRight->vEigenvector1, fSigmaPointFactor * sqrtf(pMSERRight->fEigenvalue1), vTemp);
491 Math2d::AddVecVec(pMSERRight->vMean, vTemp, vSigmaPointRight);
492 pStereoCalibration->Calculate3DPoint(
493 vSigmaPointLeft, vSigmaPointRight, pDescr3D->vSigmaPoint1b, false, false);
494
495 Math2d::MulVecScalar(
496 pMSERLeft->vEigenvector2, -fSigmaPointFactor * sqrtf(pMSERLeft->fEigenvalue2), vTemp);
497 Math2d::AddVecVec(pMSERLeft->vMean, vTemp, vSigmaPointLeft);
498 Math2d::MulVecScalar(
499 pMSERRight->vEigenvector2, -fSigmaPointFactor * sqrtf(pMSERRight->fEigenvalue2), vTemp);
500 Math2d::AddVecVec(pMSERRight->vMean, vTemp, vSigmaPointRight);
501 pStereoCalibration->Calculate3DPoint(
502 vSigmaPointLeft, vSigmaPointRight, pDescr3D->vSigmaPoint2a, false, false);
503
504 Math2d::MulVecScalar(
505 pMSERLeft->vEigenvector2, fSigmaPointFactor * sqrtf(pMSERLeft->fEigenvalue2), vTemp);
506 Math2d::AddVecVec(pMSERLeft->vMean, vTemp, vSigmaPointLeft);
507 Math2d::MulVecScalar(
508 pMSERRight->vEigenvector2, fSigmaPointFactor * sqrtf(pMSERRight->fEigenvalue2), vTemp);
509 Math2d::AddVecVec(pMSERRight->vMean, vTemp, vSigmaPointRight);
510 pStereoCalibration->Calculate3DPoint(
511 vSigmaPointLeft, vSigmaPointRight, pDescr3D->vSigmaPoint2b, false, false);
512
513
514 return pDescr3D;
515}
516
517inline void
518CMSERCalculation::CreateHSVHistograms(CMSERDescriptor* pDescriptor, const CByteImage* pHSVImage)
519{
520 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
521 {
522 pDescriptor->pHueHistogramInnerPoints[i] = 0;
523 pDescriptor->pHueHistogramSurroundingRegion[i] = 0;
524 }
525
526 //**************************************************************************************************************
527 // histogram of the inner points of the region
528 //**************************************************************************************************************
529
530 const int nBucketSize = (int)(ceil(256.0f / (float)OLP_SIZE_MSER_HISTOGRAM));
531 int nPixelIndex, nSaturationValue, nHistogramIndex;
532 float fWeight;
533 int nSaturationSum = 0;
534
535 for (int i = 0; i < (int)pDescriptor->pPoints2D->size(); i++)
536 {
537 nPixelIndex = 3 * (int)(pDescriptor->pPoints2D->at(i).y * OLP_IMG_WIDTH +
538 pDescriptor->pPoints2D->at(i).x);
539 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
540 nSaturationSum += nSaturationValue;
541 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
542 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
543 pDescriptor->pHueHistogramInnerPoints[nHistogramIndex] += 0.4f * fWeight;
544 pDescriptor->pHueHistogramInnerPoints[(nHistogramIndex + OLP_SIZE_MSER_HISTOGRAM + 1) %
545 OLP_SIZE_MSER_HISTOGRAM] += 0.2f * fWeight;
546 pDescriptor->pHueHistogramInnerPoints[(nHistogramIndex + OLP_SIZE_MSER_HISTOGRAM - 1) %
547 OLP_SIZE_MSER_HISTOGRAM] += 0.2f * fWeight;
548 pDescriptor->pHueHistogramInnerPoints[(nHistogramIndex + OLP_SIZE_MSER_HISTOGRAM + 2) %
549 OLP_SIZE_MSER_HISTOGRAM] += 0.1f * fWeight;
550 pDescriptor->pHueHistogramInnerPoints[(nHistogramIndex + OLP_SIZE_MSER_HISTOGRAM - 2) %
551 OLP_SIZE_MSER_HISTOGRAM] += 0.1f * fWeight;
552 }
553
554 // normalize
555 float fSum = 0;
556
557 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
558 {
559 fSum += pDescriptor->pHueHistogramInnerPoints[i];
560 }
561
562 if (fSum != 0)
563 {
564 const float fOneBySum = 1.0f / fSum;
565
566 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
567 {
568 pDescriptor->pHueHistogramInnerPoints[i] *= fOneBySum;
569 }
570 }
571 else // set to equally distributed values
572 {
573 const float fDummy = 1.0f / (float)OLP_SIZE_MSER_HISTOGRAM;
574
575 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
576 {
577 pDescriptor->pHueHistogramInnerPoints[i] = fDummy;
578 }
579 }
580
581 pDescriptor->fAverageSaturationInnerPoints =
582 ((float)nSaturationSum) / ((float)(255 * pDescriptor->pPoints2D->size()));
583
584
585 //**************************************************************************************************************
586 // histogram of the rectangular region spanned by the eigenvectors of the MSER
587 //**************************************************************************************************************
588
589 Vec2d pCorners[4];
590 Vec2d vTemp1, vTemp2;
591 const float fStdDevFactor = 2.5f;
592 const float fAdditionalPixels = 2.0f;
593 const float fRegionSize =
594 (fStdDevFactor * sqrtf(pDescriptor->fEigenvalue1) + fAdditionalPixels) *
595 (fStdDevFactor * sqrtf(pDescriptor->fEigenvalue2) + fAdditionalPixels);
596
597 //// rhombus / Raute
598 //Math2d::MulVecScalar(pDescriptor->vEigenvector1, (fStdDevFactor*sqrtf(pDescriptor->fEigenvalue1)+fAdditionalPixels), vTemp);
599 //Math2d::SubtractVecVec(pDescriptor->vMean, vTemp, pCorners[0]);
600 //Math2d::AddVecVec(pDescriptor->vMean, vTemp, pCorners[1]);
601 //Math2d::MulVecScalar(pDescriptor->vEigenvector2, (fStdDevFactor*sqrtf(pDescriptor->fEigenvalue2)+fAdditionalPixels), vTemp);
602 //Math2d::SubtractVecVec(pDescriptor->vMean, vTemp, pCorners[2]);
603 //Math2d::AddVecVec(pDescriptor->vMean, vTemp, pCorners[3]);
604
605 // parallelogramm
606 Math2d::MulVecScalar(pDescriptor->vEigenvector1,
607 (fStdDevFactor * sqrtf(pDescriptor->fEigenvalue1) + fAdditionalPixels),
608 vTemp1);
609 Math2d::MulVecScalar(pDescriptor->vEigenvector2,
610 (fStdDevFactor * sqrtf(pDescriptor->fEigenvalue2) + fAdditionalPixels),
611 vTemp2);
612 Math2d::SubtractVecVec(pDescriptor->vMean, vTemp1, pCorners[0]);
613 Math2d::SubtractVecVec(pCorners[0], vTemp2, pCorners[0]);
614 Math2d::AddVecVec(pDescriptor->vMean, vTemp1, pCorners[1]);
615 Math2d::SubtractVecVec(pCorners[1], vTemp2, pCorners[1]);
616 Math2d::SubtractVecVec(pDescriptor->vMean, vTemp1, pCorners[2]);
617 Math2d::AddVecVec(pCorners[2], vTemp2, pCorners[2]);
618 Math2d::AddVecVec(pDescriptor->vMean, vTemp1, pCorners[3]);
619 Math2d::AddVecVec(pCorners[3], vTemp2, pCorners[3]);
620
621
622 // determine which corner is up, low, left, right
623 Vec2d vUp, vLow, vLeft, vRight;
624 SortQuadrangleCorners(pCorners, vUp, vLow, vLeft, vRight);
625
627 vLow,
628 vLeft,
629 vRight,
630 pHSVImage,
633 nSaturationSum);
634
635 pDescriptor->fAverageSaturationSurroundingRegion = ((float)nSaturationSum) / fRegionSize;
636}
637
638float
640{
641 float fSum = 0;
642
643 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
644 {
645 fSum += (pDescriptor1->pHueHistogramInnerPoints[i] -
646 pDescriptor2->pHueHistogramInnerPoints[i]) *
647 (pDescriptor1->pHueHistogramInnerPoints[i] -
648 pDescriptor2->pHueHistogramInnerPoints[i]) +
649 (pDescriptor1->pHueHistogramSurroundingRegion[i] -
650 pDescriptor2->pHueHistogramSurroundingRegion[i]) *
651 (pDescriptor1->pHueHistogramSurroundingRegion[i] -
652 pDescriptor2->pHueHistogramSurroundingRegion[i]);
653 }
654
655 float fRet = sqrtf(fSum / (float)(2 * OLP_SIZE_MSER_HISTOGRAM));
656
657 //if ( (fRet!=fRet) || _isnan(fRet) || (fRet>100) )
658 //{
659 // for (int i=0; i<OLP_SIZE_MSER_HISTOGRAM; i++)
660 // {
661 // ARMARX_VERBOSE_S << "%.2f\t%.2f\n", pDescriptor1->pHueHistogramInnerPoints[i], pDescriptor2->pHueHistogramInnerPoints[i]);
662 // }
663 //}
664
665 return fRet;
666}
667
668float
670 CMSERDescriptor* pDescriptor2)
671{
672 float fSum = 0;
673
674 for (int i = 0; i < OLP_SIZE_MSER_HISTOGRAM; i++)
675 {
676 fSum += (pDescriptor1->pHueHistogramInnerPoints[i] -
677 pDescriptor2->pHueHistogramInnerPoints[i]) *
678 (pDescriptor1->pHueHistogramInnerPoints[i] -
679 pDescriptor2->pHueHistogramInnerPoints[i]) /
680 (pDescriptor1->pHueHistogramInnerPoints[i] +
681 pDescriptor2->pHueHistogramInnerPoints[i] + 0.00001f) +
682 (pDescriptor1->pHueHistogramSurroundingRegion[i] -
683 pDescriptor2->pHueHistogramSurroundingRegion[i]) *
684 (pDescriptor1->pHueHistogramSurroundingRegion[i] -
685 pDescriptor2->pHueHistogramSurroundingRegion[i]) /
686 (pDescriptor1->pHueHistogramSurroundingRegion[i] +
687 pDescriptor2->pHueHistogramSurroundingRegion[i] + 0.00001f);
688 }
689
690 float fRet = sqrtf(fSum / (float)(2 * OLP_SIZE_MSER_HISTOGRAM));
691
692 return fRet;
693}
694
695// determine upper, lower, left and right corner. up = min y value
696void
698 Vec2d& vUp,
699 Vec2d& vLow,
700 Vec2d& vLeft,
701 Vec2d& vRight)
702{
703 int nUp1, nUp2, nLow1, nLow2, nTemp;
704
705 if (pCorners[0].y < pCorners[1].y)
706 {
707 nUp1 = 0;
708 nLow1 = 1;
709 }
710 else
711 {
712 nUp1 = 1;
713 nLow1 = 0;
714 }
715
716 if (pCorners[2].y < pCorners[3].y)
717 {
718 nUp2 = 2;
719 nLow2 = 3;
720 }
721 else
722 {
723 nUp2 = 3;
724 nLow2 = 2;
725 }
726
727 if (pCorners[nUp1].y > pCorners[nUp2].y)
728 {
729 nTemp = nUp1;
730 nUp1 = nUp2;
731 nUp2 = nTemp;
732 }
733
734 if (pCorners[nLow1].y < pCorners[nLow2].y)
735 {
736 nTemp = nLow1;
737 nLow1 = nLow2;
738 nLow2 = nTemp;
739 }
740
741 Math2d::SetVec(vUp, pCorners[nUp1]);
742 Math2d::SetVec(vLow, pCorners[nLow1]);
743
744 if (pCorners[nUp2].x < pCorners[nLow2].x)
745 {
746 Math2d::SetVec(vLeft, pCorners[nUp2]);
747 Math2d::SetVec(vRight, pCorners[nLow2]);
748 }
749 else
750 {
751 Math2d::SetVec(vLeft, pCorners[nLow2]);
752 Math2d::SetVec(vRight, pCorners[nUp2]);
753 }
754}
755
756inline void
758 Vec2d vLow,
759 Vec2d vLeft,
760 Vec2d vRight,
761 const CByteImage* pHSVImage,
762 float* pHistogram,
763 const int nHistogramSize,
764 int& nSaturationSum)
765{
766
767 const int nBucketSize = (int)(ceil(256.0f / (float)nHistogramSize));
768 int nPixelIndex, nSaturationValue, nHistogramIndex;
769 float fWeight;
770
771 // stay within the image
772 if (vUp.x < 0)
773 {
774 vUp.x = 0;
775 }
776 else if (vUp.x >= OLP_IMG_WIDTH)
777 {
778 vUp.x = OLP_IMG_WIDTH - 1;
779 }
780
781 if (vUp.y < 0)
782 {
783 vUp.y = 0;
784 }
785 else if (vUp.y >= OLP_IMG_HEIGHT)
786 {
787 vUp.y = OLP_IMG_HEIGHT - 1;
788 }
789
790 if (vLow.x < 0)
791 {
792 vLow.x = 0;
793 }
794 else if (vLow.x >= OLP_IMG_WIDTH)
795 {
796 vLow.x = OLP_IMG_WIDTH - 1;
797 }
798
799 if (vLow.y < 0)
800 {
801 vLow.y = 0;
802 }
803 else if (vLow.y >= OLP_IMG_HEIGHT)
804 {
805 vLow.y = OLP_IMG_HEIGHT - 1;
806 }
807
808 if (vLeft.x < 0)
809 {
810 vLeft.x = 0;
811 }
812 else if (vLeft.x >= OLP_IMG_WIDTH)
813 {
814 vLeft.x = OLP_IMG_WIDTH - 1;
815 }
816
817 if (vLeft.y < 0)
818 {
819 vLeft.y = 0;
820 }
821 else if (vLeft.y >= OLP_IMG_HEIGHT)
822 {
823 vLeft.y = OLP_IMG_HEIGHT - 1;
824 }
825
826 if (vRight.x < 0)
827 {
828 vRight.x = 0;
829 }
830 else if (vRight.x >= OLP_IMG_WIDTH)
831 {
832 vRight.x = OLP_IMG_WIDTH - 1;
833 }
834
835 if (vRight.y < 0)
836 {
837 vRight.y = 0;
838 }
839 else if (vRight.y >= OLP_IMG_HEIGHT)
840 {
841 vRight.y = OLP_IMG_HEIGHT - 1;
842 }
843
844
845 nSaturationSum = 0;
846 float fDeltaLeft, fDeltaRight;
847 int nLeft, nRight;
848 const int nUp = (int)vUp.y;
849 const int nLow = (int)vLow.y;
850
851 if (vLeft.y < vRight.y)
852 {
853 const int nMiddle1 = (int)vLeft.y;
854 const int nMiddle2 = (int)vRight.y;
855 fDeltaLeft = (vLeft.x - vUp.x) / (vLeft.y - vUp.y);
856 fDeltaRight = (vRight.x - vUp.x) / (vRight.y - vUp.y);
857
858 for (int i = nUp; i < nMiddle1; i++)
859 {
860 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
861 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
862
863 for (int j = nLeft; j <= nRight; j++)
864 {
865 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
866 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
867 nSaturationSum += nSaturationValue;
868 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
869 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
870 pHistogram[nHistogramIndex] += 0.4f * fWeight;
871 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
872 0.2f * fWeight;
873 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
874 0.2f * fWeight;
875 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
876 0.1f * fWeight;
877 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
878 0.1f * fWeight;
879 }
880 }
881
882 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
883
884 for (int i = nMiddle1; i < nMiddle2; i++)
885 {
886 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
887 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
888
889 for (int j = nLeft; j <= nRight; j++)
890 {
891 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
892 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
893 nSaturationSum += nSaturationValue;
894 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
895 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
896 pHistogram[nHistogramIndex] += 0.4f * fWeight;
897 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
898 0.2f * fWeight;
899 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
900 0.2f * fWeight;
901 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
902 0.1f * fWeight;
903 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
904 0.1f * fWeight;
905 }
906 }
907
908 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
909
910 for (int i = nMiddle2; i < nLow; i++)
911 {
912 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
913 nRight = (int)(vRight.x + (i - nMiddle2) * fDeltaRight);
914
915 for (int j = nLeft; j <= nRight; j++)
916 {
917 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
918 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
919 nSaturationSum += nSaturationValue;
920 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
921 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
922 pHistogram[nHistogramIndex] += 0.4f * fWeight;
923 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
924 0.2f * fWeight;
925 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
926 0.2f * fWeight;
927 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
928 0.1f * fWeight;
929 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
930 0.1f * fWeight;
931 }
932 }
933 }
934 else
935 {
936 const int nMiddle1 = (int)vRight.y;
937 const int nMiddle2 = (int)vLeft.y;
938 fDeltaLeft = (vLeft.x - vUp.x) / (vLeft.y - vUp.y);
939 fDeltaRight = (vRight.x - vUp.x) / (vRight.y - vUp.y);
940
941 for (int i = nUp; i < nMiddle1; i++)
942 {
943 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
944 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
945
946 for (int j = nLeft; j <= nRight; j++)
947 {
948 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
949 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
950 nSaturationSum += nSaturationValue;
951 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
952 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
953 pHistogram[nHistogramIndex] += 0.4f * fWeight;
954 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
955 0.2f * fWeight;
956 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
957 0.2f * fWeight;
958 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
959 0.1f * fWeight;
960 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
961 0.1f * fWeight;
962 }
963 }
964
965 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
966
967 for (int i = nMiddle1; i < nMiddle2; i++)
968 {
969 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
970 nRight = (int)(vRight.x + (i - nMiddle1) * fDeltaRight);
971
972 for (int j = nLeft; j <= nRight; j++)
973 {
974 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
975 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
976 nSaturationSum += nSaturationValue;
977 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
978 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
979 pHistogram[nHistogramIndex] += 0.4f * fWeight;
980 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
981 0.2f * fWeight;
982 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
983 0.2f * fWeight;
984 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
985 0.1f * fWeight;
986 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
987 0.1f * fWeight;
988 }
989 }
990
991 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
992
993 for (int i = nMiddle2; i < nLow; i++)
994 {
995 nLeft = (int)(vLeft.x + (i - nMiddle2) * fDeltaLeft);
996 nRight = (int)(vRight.x + (i - nMiddle1) * fDeltaRight);
997
998 for (int j = nLeft; j <= nRight; j++)
999 {
1000 nPixelIndex = 3 * (i * OLP_IMG_WIDTH + j);
1001 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
1002 nSaturationSum += nSaturationValue;
1003 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
1004 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
1005 pHistogram[nHistogramIndex] += 0.4f * fWeight;
1006 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] +=
1007 0.2f * fWeight;
1008 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
1009 0.2f * fWeight;
1010 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
1011 0.1f * fWeight;
1012 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
1013 0.1f * fWeight;
1014 }
1015 }
1016 }
1017
1018
1019 // normalize
1020 float fSum = 0;
1021
1022 for (int i = 0; i < nHistogramSize; i++)
1023 {
1024 fSum += pHistogram[i];
1025 }
1026
1027 if (fSum != 0)
1028 {
1029 const float fOneBySum = 1.0f / fSum;
1030
1031 for (int i = 0; i < nHistogramSize; i++)
1032 {
1033 pHistogram[i] *= fOneBySum;
1034 }
1035 }
1036 else // set to equally distributed values
1037 {
1038 const float fDummy = 1.0f / (float)nHistogramSize;
1039
1040 for (int i = 0; i < nHistogramSize; i++)
1041 {
1042 pHistogram[i] = fDummy;
1043 }
1044 }
1045}
#define float
Definition 16_Level.h:22
#define OLP_MAX_OBJECT_DISTANCE
#define OLP_SIZE_MSER_HISTOGRAM
static float HistogramDistanceChi2(CMSERDescriptor *pDescriptor1, CMSERDescriptor *pDescriptor2)
static void GetEigenvaluesAndEigenvectors2D(Mat2d mMatrix2D, float &fLambda1, float &fLambda2, Vec2d &vE1, Vec2d &vE2)
static CMSERDescriptor3D * CreateMSERDescriptor3D(CMSERDescriptor *pMSERLeft, CMSERDescriptor *pMSERRight, CStereoCalibration *pStereoCalibration)
static void SortQuadrangleCorners(Vec2d *pCorners, Vec2d &vUp, Vec2d &vLow, Vec2d &vLeft, Vec2d &vRight)
static float HistogramDistanceL2(CMSERDescriptor *pDescriptor1, CMSERDescriptor *pDescriptor2)
static void StereoMatchMSERs(const std::vector< CMSERDescriptor * > &aMSERDescriptorsLeft, const std::vector< CMSERDescriptor * > &aMSERDescriptorsRight, CStereoCalibration *pStereoCalibration, const float fToleranceFactor, std::vector< CMSERDescriptor3D * > &aRegions3D)
static void CreateWeightedHueHistogramWithinQuadrangle(Vec2d vUp, Vec2d vLow, Vec2d vLeft, Vec2d vRight, const CByteImage *pHSVImage, float *pHistogram, const int nHistogramSize, int &nSaturationSum)
static void GetMeanAndCovariance2D(std::vector< Vec2d > &aPoints2D, Vec2d &vMean, Mat2d &mCovariance)
static void CreateHSVHistograms(CMSERDescriptor *pDescriptor, const CByteImage *pHSVImage)
static CMSERDescriptor * CreateMSERDescriptor(std::vector< Vec2d > *aPoints2D, const CByteImage *pHSVImage)
static void FindMSERs3D(const CByteImage *pByteImageLeft, const CByteImage *pByteImageRight, CStereoCalibration *pStereoCalibration, const float fToleranceFactor, std::vector< CMSERDescriptor3D * > &aRegions3D)
static void FindMSERs2D(const CByteImage *pRGBImage, const CByteImage *pHSVImage, std::vector< CMSERDescriptor * > &aMSERDescriptors)
CMSERDescriptor * pRegionLeft
CMSERDescriptor * pRegionRight
float pHueHistogramSurroundingRegion[OLP_SIZE_MSER_HISTOGRAM]
std::vector< Vec2d > * pPoints2D
CMSERDescriptor * GetCopy()
float fAverageSaturationSurroundingRegion
float pHueHistogramInnerPoints[OLP_SIZE_MSER_HISTOGRAM]
float fAverageSaturationInnerPoints
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
This file offers overloads of toIce() and fromIce() functions for STL container types.