53 const CByteImage* pHSVImage,
54 std::vector<CMSERDescriptor*>& aMSERDescriptors)
56#if (CV_MAJOR_VERSION == 2)
57#if (CV_MINOR_VERSION < 4)
73 cv::MSER pMSERDetector = cv::MSER();
79 pMSERDetector.maxArea *= 10;
80 pMSERDetector.maxVariation *= 3;
81 pMSERDetector.maxEvolution *= 3;
82 pMSERDetector.minMargin *= 0.33;
86 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
88 std::vector<std::vector<cv::Point>> aContoursCVLeft;
89 std::vector<std::vector<Vec2d>> aContoursLeft;
93 cv::Seq<CvSeq*> contoursLeft;
94 cv::MemStorage storageLeft(cvCreateMemStorage(0));
95 cvExtractMSER(pIplImage, NULL, &contoursLeft.seq, storageLeft, pMSERDetector);
97 cv::SeqIterator<CvSeq*> itLeft = contoursLeft.begin();
98 size_t i, ncontours = contoursLeft.size();
99 aContoursCVLeft.resize(ncontours);
101 for (i = 0; i < ncontours; i++, ++itLeft)
103 while (cv::Seq<cv::Point>(*itLeft).size() > 0)
105 aContoursCVLeft[i].push_back(cv::Seq<cv::Point>(*itLeft).front());
106 cv::Seq<cv::Point>(*itLeft).pop_front();
113 for (
int i = 0; i < (int)aContoursCVLeft.size(); i++)
115 std::vector<Vec2d> aPoints;
116 aContoursLeft.push_back(aPoints);
118 for (
int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
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);
132 for (
int i = 0; i < (int)aContoursLeft.size(); i++)
135 aMSERDescriptors.push_back(pDescriptor);
146 cvReleaseImageHeader(&pIplImage);
147 storageLeft.release();
149#elif (CV_MINOR_VERSION == 4)
150 cv::MSER pMSERDetector = cv::MSER();
152 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
153 std::vector<std::vector<cv::Point>> aContoursCVLeft;
155 pMSERDetector(pIplImage, aContoursCVLeft, cv::Mat());
157 std::vector<std::vector<Vec2d>> aContoursLeft;
159 for (
int i = 0; i < (int)aContoursCVLeft.size(); i++)
161 std::vector<Vec2d> aPoints;
162 aContoursLeft.push_back(aPoints);
164 for (
int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
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);
172 for (
int i = 0; i < (int)aContoursLeft.size(); i++)
175 aMSERDescriptors.push_back(pDescriptor);
178 cvReleaseImageHeader(&pIplImage);
180 ARMARX_WARNING_S <<
"This code is not implemented for OpenCV Version " << CV_VERSION
181 <<
" (CV_MINOR_VERSION = " << CV_MINOR_VERSION <<
")";
184 ARMARX_WARNING_S <<
"This code is not implemented for OpenCV Version " << CV_VERSION
185 <<
" (CV_MAJOR_VERSION = " << CV_MAJOR_VERSION <<
")";
191 const std::vector<CMSERDescriptor*>& aMSERDescriptorsRight,
192 CStereoCalibration* pStereoCalibration,
193 const float fToleranceFactor,
194 std::vector<CMSERDescriptor3D*>& aRegions3D)
197 const float fRatioThresholdHigh = 1.0f + fToleranceFactor * 0.25f;
198 const float fRatioThresholdLow = 1.0f / fRatioThresholdHigh;
199 const float fRatioThresholdHigh2 = fRatioThresholdHigh * fRatioThresholdHigh;
200 const float fRatioThresholdLow2 = fRatioThresholdLow * fRatioThresholdLow;
202 for (
int i = 0; i < (int)aMSERDescriptorsLeft.size(); i++)
204 float fMinEpipolarDistance = fToleranceFactor * 2.0f;
205 int nCorrespondenceIndex = -1;
206 const float fOwnEVRatio =
207 aMSERDescriptorsLeft.at(i)->fEigenvalue2 / aMSERDescriptorsLeft.at(i)->fEigenvalue1;
209 for (
int j = 0; j < (int)aMSERDescriptorsRight.size(); j++)
211 const float fSizeRatio = (
float)aMSERDescriptorsLeft.at(i)->nSize /
212 (
float)aMSERDescriptorsRight.at(j)->nSize;
214 if ((fRatioThresholdLow < fSizeRatio) && (fSizeRatio < fRatioThresholdHigh))
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) /
224 if ((fRatioThresholdLow2 < fEV1Ratio) && (fEV1Ratio < fRatioThresholdHigh2) &&
225 (fRatioThresholdLow2 < fEV2Ratio) && (fEV2Ratio < fRatioThresholdHigh2) &&
226 (fRatioThresholdLow2 < fRatioRatio) && (fRatioRatio < fRatioThresholdHigh2))
228 const float fEpipolarDistance =
229 fabsf(pStereoCalibration->CalculateEpipolarLineInLeftImageDistance(
230 aMSERDescriptorsLeft.at(i)->vMean, aMSERDescriptorsRight.at(j)->vMean));
232 if (fEpipolarDistance < fMinEpipolarDistance)
235 pStereoCalibration->Calculate3DPoint(aMSERDescriptorsLeft.at(i)->vMean,
236 aMSERDescriptorsRight.at(j)->vMean,
243 fMinEpipolarDistance = fEpipolarDistance;
244 nCorrespondenceIndex = j;
251 if (nCorrespondenceIndex != -1)
255 aMSERDescriptorsRight.at(nCorrespondenceIndex),
257 aRegions3D.push_back(pDescr3D);
264 const CByteImage* pByteImageRight,
265 CStereoCalibration* pStereoCalibration,
266 const float fToleranceFactor,
267 std::vector<CMSERDescriptor3D*>& aRegions3D)
275 ImageProcessor::CalculateHSVImage(pByteImageLeft, pHSVImageLeft);
276 ImageProcessor::CalculateHSVImage(pByteImageRight, pHSVImageRight);
283 std::vector<CMSERDescriptor*> aMSERDescriptorsLeft;
284 std::vector<CMSERDescriptor*> aMSERDescriptorsRight;
285 FindMSERs2D(pByteImageLeft, pHSVImageLeft, aMSERDescriptorsLeft);
286 FindMSERs2D(pByteImageRight, pHSVImageRight, aMSERDescriptorsRight);
291 aMSERDescriptorsRight,
319 for (
size_t i = 0; i < aMSERDescriptorsLeft.size(); i++)
321 aMSERDescriptorsLeft.at(i)->pPoints2D->clear();
322 delete aMSERDescriptorsLeft.at(i)->pPoints2D;
323 delete aMSERDescriptorsLeft.at(i);
326 for (
size_t i = 0; i < aMSERDescriptorsRight.size(); i++)
328 aMSERDescriptorsRight.at(i)->pPoints2D->clear();
329 delete aMSERDescriptorsRight.at(i)->pPoints2D;
330 delete aMSERDescriptorsRight.at(i);
334 delete pHSVImageLeft;
335 delete pHSVImageRight;
443 CStereoCalibration* pStereoCalibration)
469 pStereoCalibration->Calculate3DPoint(
473 Vec2d vSigmaPointLeft, vSigmaPointRight, vTemp;
475 const float fSigmaPointFactor = 1.0f;
477 Math2d::MulVecScalar(
479 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
480 Math2d::MulVecScalar(
482 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
483 pStereoCalibration->Calculate3DPoint(
484 vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint1a,
false,
false);
486 Math2d::MulVecScalar(
488 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
489 Math2d::MulVecScalar(
491 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
492 pStereoCalibration->Calculate3DPoint(
493 vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint1b,
false,
false);
495 Math2d::MulVecScalar(
497 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
498 Math2d::MulVecScalar(
500 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
501 pStereoCalibration->Calculate3DPoint(
502 vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint2a,
false,
false);
504 Math2d::MulVecScalar(
506 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
507 Math2d::MulVecScalar(
509 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
510 pStereoCalibration->Calculate3DPoint(
511 vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint2b,
false,
false);
531 int nPixelIndex, nSaturationValue, nHistogramIndex;
533 int nSaturationSum = 0;
535 for (
int i = 0; i < (int)pDescriptor->
pPoints2D->size(); i++)
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));
564 const float fOneBySum = 1.0f / fSum;
582 ((
float)nSaturationSum) / ((
float)(255 * pDescriptor->
pPoints2D->size()));
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);
607 (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue1) + fAdditionalPixels),
610 (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue2) + fAdditionalPixels),
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]);
623 Vec2d vUp, vLow, vLeft, vRight;
761 const CByteImage* pHSVImage,
763 const int nHistogramSize,
767 const int nBucketSize = (int)(ceil(256.0f / (
float)nHistogramSize));
768 int nPixelIndex, nSaturationValue, nHistogramIndex;
846 float fDeltaLeft, fDeltaRight;
848 const int nUp = (int)vUp.y;
849 const int nLow = (int)vLow.y;
851 if (vLeft.y < vRight.y)
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);
858 for (
int i = nUp; i < nMiddle1; i++)
860 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
861 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
863 for (
int j = nLeft; j <= nRight; 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] +=
873 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
875 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
877 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
882 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
884 for (
int i = nMiddle1; i < nMiddle2; i++)
886 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
887 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
889 for (
int j = nLeft; j <= nRight; 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] +=
899 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
901 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
903 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
908 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
910 for (
int i = nMiddle2; i < nLow; i++)
912 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
913 nRight = (int)(vRight.x + (i - nMiddle2) * fDeltaRight);
915 for (
int j = nLeft; j <= nRight; 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] +=
925 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
927 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
929 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
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);
941 for (
int i = nUp; i < nMiddle1; i++)
943 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
944 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
946 for (
int j = nLeft; j <= nRight; 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] +=
956 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
958 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
960 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
965 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
967 for (
int i = nMiddle1; i < nMiddle2; i++)
969 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
970 nRight = (int)(vRight.x + (i - nMiddle1) * fDeltaRight);
972 for (
int j = nLeft; j <= nRight; 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] +=
982 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
984 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
986 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
991 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
993 for (
int i = nMiddle2; i < nLow; i++)
995 nLeft = (int)(vLeft.x + (i - nMiddle2) * fDeltaLeft);
996 nRight = (int)(vRight.x + (i - nMiddle1) * fDeltaRight);
998 for (
int j = nLeft; j <= nRight; 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] +=
1008 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] +=
1010 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] +=
1012 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] +=
1022 for (
int i = 0; i < nHistogramSize; i++)
1024 fSum += pHistogram[i];
1029 const float fOneBySum = 1.0f / fSum;
1031 for (
int i = 0; i < nHistogramSize; i++)
1033 pHistogram[i] *= fOneBySum;
1038 const float fDummy = 1.0f / (
float)nHistogramSize;
1040 for (
int i = 0; i < nHistogramSize; i++)
1042 pHistogram[i] = fDummy;