29 #include <Image/ByteImage.h>
30 #include <Image/ImageProcessor.h>
31 #include <Image/IplImageAdaptor.h>
32 #include <Calibration/StereoCalibration.h>
33 #include <Calibration/Calibration.h>
60 #if (CV_MAJOR_VERSION == 2)
61 #if (CV_MINOR_VERSION < 4)
77 cv::MSER pMSERDetector = cv::MSER();
83 pMSERDetector.maxArea *= 10;
84 pMSERDetector.maxVariation *= 3;
85 pMSERDetector.maxEvolution *= 3;
86 pMSERDetector.minMargin *= 0.33;
90 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
92 std::vector<std::vector<cv::Point> > aContoursCVLeft;
93 std::vector<std::vector<Vec2d> > aContoursLeft;
97 cv::Seq<CvSeq*> contoursLeft;
98 cv::MemStorage storageLeft(cvCreateMemStorage(0));
99 cvExtractMSER(pIplImage, NULL, &contoursLeft.seq, storageLeft, pMSERDetector);
101 cv::SeqIterator<CvSeq*> itLeft = contoursLeft.begin();
102 size_t i, ncontours = contoursLeft.size();
103 aContoursCVLeft.resize(ncontours);
105 for (i = 0; i < ncontours; i++, ++itLeft)
107 while (cv::Seq<cv::Point>(*itLeft).size() > 0)
109 aContoursCVLeft[i].push_back(cv::Seq<cv::Point>(*itLeft).front());
110 cv::Seq<cv::Point>(*itLeft).pop_front();
117 for (
int i = 0; i < (int)aContoursCVLeft.size(); i++)
119 std::vector<Vec2d> aPoints;
120 aContoursLeft.push_back(aPoints);
122 for (
int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
124 Vec2d vTemp = {(
float)aContoursCVLeft.at(i).at(j).x, (
float)aContoursCVLeft.at(i).at(j).y};
125 aContoursLeft.at(i).push_back(vTemp);
135 for (
int i = 0; i < (int)aContoursLeft.size(); i++)
138 aMSERDescriptors.push_back(pDescriptor);
149 cvReleaseImageHeader(&pIplImage);
150 storageLeft.release();
152 #elif (CV_MINOR_VERSION == 4)
153 cv::MSER pMSERDetector = cv::MSER();
155 pIplImage = IplImageAdaptor::Adapt(pRGBImage);
156 std::vector<std::vector<cv::Point> > aContoursCVLeft;
158 pMSERDetector(pIplImage, aContoursCVLeft, cv::Mat());
160 std::vector<std::vector<Vec2d> > aContoursLeft;
162 for (
int i = 0; i < (int)aContoursCVLeft.size(); i++)
164 std::vector<Vec2d> aPoints;
165 aContoursLeft.push_back(aPoints);
167 for (
int j = 0; j < (int)aContoursCVLeft.at(i).size(); j++)
169 Vec2d vTemp = {(
float)aContoursCVLeft.at(i).at(j).x, (
float)aContoursCVLeft.at(i).at(j).y};
170 aContoursLeft.at(i).push_back(vTemp);
174 for (
int i = 0; i < (int)aContoursLeft.size(); i++)
177 aMSERDescriptors.push_back(pDescriptor);
180 cvReleaseImageHeader(&pIplImage);
182 ARMARX_WARNING_S <<
"This code is not implemented for OpenCV Version " << CV_VERSION <<
" (CV_MINOR_VERSION = " << CV_MINOR_VERSION <<
")";
185 ARMARX_WARNING_S <<
"This code is not implemented for OpenCV Version " << CV_VERSION <<
" (CV_MAJOR_VERSION = " << CV_MAJOR_VERSION <<
")";
194 CStereoCalibration* pStereoCalibration,
const float fToleranceFactor, 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 = aMSERDescriptorsLeft.at(i)->fEigenvalue2 / aMSERDescriptorsLeft.at(i)->fEigenvalue1;
208 for (
int j = 0; j < (int)aMSERDescriptorsRight.size(); j++)
210 const float fSizeRatio = (
float)aMSERDescriptorsLeft.at(i)->nSize / (
float)aMSERDescriptorsRight.at(j)->nSize;
212 if ((fRatioThresholdLow < fSizeRatio) && (fSizeRatio < fRatioThresholdHigh))
214 const float fEV1Ratio = aMSERDescriptorsLeft.at(i)->fEigenvalue1 / aMSERDescriptorsRight.at(j)->fEigenvalue1;
215 const float fEV2Ratio = aMSERDescriptorsLeft.at(i)->fEigenvalue2 / aMSERDescriptorsRight.at(j)->fEigenvalue2;
216 const float fRatioRatio = (aMSERDescriptorsRight.at(j)->fEigenvalue2 / aMSERDescriptorsRight.at(j)->fEigenvalue1) / fOwnEVRatio;
218 if ((fRatioThresholdLow2 < fEV1Ratio) && (fEV1Ratio < fRatioThresholdHigh2) && (fRatioThresholdLow2 < fEV2Ratio)
219 && (fEV2Ratio < fRatioThresholdHigh2) && (fRatioThresholdLow2 < fRatioRatio) && (fRatioRatio < fRatioThresholdHigh2))
221 const float fEpipolarDistance = fabsf(pStereoCalibration->CalculateEpipolarLineInLeftImageDistance(aMSERDescriptorsLeft.at(i)->vMean, aMSERDescriptorsRight.at(j)->vMean));
223 if (fEpipolarDistance < fMinEpipolarDistance)
226 pStereoCalibration->Calculate3DPoint(aMSERDescriptorsLeft.at(i)->vMean, aMSERDescriptorsRight.at(j)->vMean, vPoint3D,
false,
false);
230 fMinEpipolarDistance = fEpipolarDistance;
231 nCorrespondenceIndex = j;
238 if (nCorrespondenceIndex != -1)
241 aRegions3D.push_back(pDescr3D);
254 const float fToleranceFactor, std::vector<CMSERDescriptor3D*>& aRegions3D)
262 ImageProcessor::CalculateHSVImage(pByteImageLeft, pHSVImageLeft);
263 ImageProcessor::CalculateHSVImage(pByteImageRight, pHSVImageRight);
270 std::vector<CMSERDescriptor*> aMSERDescriptorsLeft;
271 std::vector<CMSERDescriptor*> aMSERDescriptorsRight;
272 FindMSERs2D(pByteImageLeft, pHSVImageLeft, aMSERDescriptorsLeft);
273 FindMSERs2D(pByteImageRight, pHSVImageRight, aMSERDescriptorsRight);
277 StereoMatchMSERs(aMSERDescriptorsLeft, aMSERDescriptorsRight, pStereoCalibration, fToleranceFactor, aRegions3D);
302 for (
size_t i = 0; i < aMSERDescriptorsLeft.size(); i++)
304 aMSERDescriptorsLeft.at(i)->pPoints2D->clear();
305 delete aMSERDescriptorsLeft.at(i)->pPoints2D;
306 delete aMSERDescriptorsLeft.at(i);
309 for (
size_t i = 0; i < aMSERDescriptorsRight.size(); i++)
311 aMSERDescriptorsRight.at(i)->pPoints2D->clear();
312 delete aMSERDescriptorsRight.at(i)->pPoints2D;
313 delete aMSERDescriptorsRight.at(i);
317 delete pHSVImageLeft;
318 delete pHSVImageRight;
335 if (aPoints2D.size() < 2)
343 for (
int i = 0; i < (int)aPoints2D.size(); i++)
345 vMean.x += (
float)aPoints2D.at(i).x;
346 vMean.y += (
float)aPoints2D.at(i).y;
349 vMean.x /= aPoints2D.size();
350 vMean.y /= aPoints2D.size();
352 for (
int i = 0; i < (int)aPoints2D.size(); i++)
354 mCovariance.r1 += (vMean.x - (
float)aPoints2D.at(i).x) * (vMean.x - (
float)aPoints2D.at(i).x);
355 mCovariance.r2 += (vMean.x - (
float)aPoints2D.at(i).x) * (vMean.y - (
float)aPoints2D.at(i).y);
356 mCovariance.r4 += (vMean.y - (
float)aPoints2D.at(i).y) * (vMean.y - (
float)aPoints2D.at(i).y);
359 mCovariance.r1 /= aPoints2D.size() - 1;
360 mCovariance.r2 /= aPoints2D.size() - 1;
361 mCovariance.r3 = mCovariance.r2;
362 mCovariance.r4 /= aPoints2D.size() - 1;
369 float fTemp1 = 0.5f * (mMatrix2D.r1 + mMatrix2D.r4);
370 float fTemp2 = sqrtf(fTemp1 * fTemp1 - mMatrix2D.r1 * mMatrix2D.r4 + mMatrix2D.r2 * mMatrix2D.r3);
372 fLambda1 = fTemp1 + fTemp2;
373 fLambda2 = fTemp1 - fTemp2;
375 vE1.x = fLambda1 - mMatrix2D.r4;
376 vE1.y = mMatrix2D.r3;
377 Math2d::NormalizeVec(vE1);
379 vE2.x = fLambda2 - mMatrix2D.r4;
380 vE2.y = mMatrix2D.r3;
381 Math2d::NormalizeVec(vE2);
390 if (aPoints2D->size() < 2)
397 pDescr->
nSize = (int)aPoints2D->size();
399 pDescr->
pPoints2D =
new std::vector<Vec2d>;
401 for (
int i = 0; i < (int)aPoints2D->size(); i++)
403 pDescr->
pPoints2D->push_back(aPoints2D->at(i));
446 pStereoCalibration->Calculate3DPoint(pMSERLeft->
vMean, pMSERRight->
vMean, pDescr3D->
vPosition,
false,
false);
449 Vec2d vSigmaPointLeft, vSigmaPointRight, vTemp;
451 const float fSigmaPointFactor = 1.0f;
454 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
456 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
457 pStereoCalibration->Calculate3DPoint(vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint1a,
false,
false);
460 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
462 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
463 pStereoCalibration->Calculate3DPoint(vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint1b,
false,
false);
466 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
468 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
469 pStereoCalibration->Calculate3DPoint(vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint2a,
false,
false);
472 Math2d::AddVecVec(pMSERLeft->
vMean, vTemp, vSigmaPointLeft);
474 Math2d::AddVecVec(pMSERRight->
vMean, vTemp, vSigmaPointRight);
475 pStereoCalibration->Calculate3DPoint(vSigmaPointLeft, vSigmaPointRight, pDescr3D->
vSigmaPoint2b,
false,
false);
497 int nPixelIndex, nSaturationValue, nHistogramIndex;
499 int nSaturationSum = 0;
501 for (
int i = 0; i < (int)pDescriptor->
pPoints2D->size(); i++)
504 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
505 nSaturationSum += nSaturationValue;
506 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
507 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
525 const float fOneBySum = 1.0f / fSum;
550 Vec2d vTemp1, vTemp2;
551 const float fStdDevFactor = 2.5f;
552 const float fAdditionalPixels = 2.0f;
553 const float fRegionSize = (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue1) + fAdditionalPixels) * (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue2) + fAdditionalPixels);
564 Math2d::MulVecScalar(pDescriptor->
vEigenvector1, (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue1) + fAdditionalPixels), vTemp1);
565 Math2d::MulVecScalar(pDescriptor->
vEigenvector2, (fStdDevFactor * sqrtf(pDescriptor->
fEigenvalue2) + fAdditionalPixels), vTemp2);
566 Math2d::SubtractVecVec(pDescriptor->
vMean, vTemp1, pCorners[0]);
567 Math2d::SubtractVecVec(pCorners[0], vTemp2, pCorners[0]);
568 Math2d::AddVecVec(pDescriptor->
vMean, vTemp1, pCorners[1]);
569 Math2d::SubtractVecVec(pCorners[1], vTemp2, pCorners[1]);
570 Math2d::SubtractVecVec(pDescriptor->
vMean, vTemp1, pCorners[2]);
571 Math2d::AddVecVec(pCorners[2], vTemp2, pCorners[2]);
572 Math2d::AddVecVec(pDescriptor->
vMean, vTemp1, pCorners[3]);
573 Math2d::AddVecVec(pCorners[3], vTemp2, pCorners[3]);
577 Vec2d vUp, vLow, vLeft, vRight;
642 int nUp1, nUp2, nLow1, nLow2, nTemp;
644 if (pCorners[0].y < pCorners[1].y)
655 if (pCorners[2].y < pCorners[3].y)
666 if (pCorners[nUp1].y > pCorners[nUp2].y)
673 if (pCorners[nLow1].y < pCorners[nLow2].y)
680 Math2d::SetVec(vUp, pCorners[nUp1]);
681 Math2d::SetVec(vLow, pCorners[nLow1]);
683 if (pCorners[nUp2].x < pCorners[nLow2].x)
685 Math2d::SetVec(vLeft, pCorners[nUp2]);
686 Math2d::SetVec(vRight, pCorners[nLow2]);
690 Math2d::SetVec(vLeft, pCorners[nLow2]);
691 Math2d::SetVec(vRight, pCorners[nUp2]);
701 float* pHistogram,
const int nHistogramSize,
int& nSaturationSum)
704 const int nBucketSize = (int)(ceil(256.0f / (
float)nHistogramSize));
705 int nPixelIndex, nSaturationValue, nHistogramIndex;
783 float fDeltaLeft, fDeltaRight;
785 const int nUp = (int)vUp.y;
786 const int nLow = (
int)vLow.y;
788 if (vLeft.y < vRight.y)
790 const int nMiddle1 = (int)vLeft.y;
791 const int nMiddle2 = (
int)vRight.y;
792 fDeltaLeft = (vLeft.x - vUp.x) / (vLeft.y - vUp.y);
793 fDeltaRight = (vRight.x - vUp.x) / (vRight.y - vUp.y);
795 for (
int i = nUp; i < nMiddle1; i++)
797 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
798 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
800 for (
int j = nLeft; j <= nRight; j++)
803 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
804 nSaturationSum += nSaturationValue;
805 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
806 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
807 pHistogram[nHistogramIndex] += 0.4f * fWeight;
808 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] += 0.2f * fWeight;
809 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
810 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
811 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
815 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
817 for (
int i = nMiddle1; i < nMiddle2; i++)
819 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
820 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
822 for (
int j = nLeft; j <= nRight; j++)
825 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
826 nSaturationSum += nSaturationValue;
827 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
828 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
829 pHistogram[nHistogramIndex] += 0.4f * fWeight;
830 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] += 0.2f * fWeight;
831 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
832 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
833 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
837 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
839 for (
int i = nMiddle2; i < nLow; i++)
841 nLeft = (int)(vLeft.x + (i - nMiddle1) * fDeltaLeft);
842 nRight = (int)(vRight.x + (i - nMiddle2) * fDeltaRight);
844 for (
int j = nLeft; j <= nRight; j++)
847 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
848 nSaturationSum += nSaturationValue;
849 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
850 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
851 pHistogram[nHistogramIndex] += 0.4f * fWeight;
852 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] += 0.2f * fWeight;
853 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
854 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
855 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
861 const int nMiddle1 = (int)vRight.y;
862 const int nMiddle2 = (
int)vLeft.y;
863 fDeltaLeft = (vLeft.x - vUp.x) / (vLeft.y - vUp.y);
864 fDeltaRight = (vRight.x - vUp.x) / (vRight.y - vUp.y);
866 for (
int i = nUp; i < nMiddle1; i++)
868 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
869 nRight = (int)(vUp.x + (i - nUp) * fDeltaRight);
871 for (
int j = nLeft; j <= nRight; j++)
874 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
875 nSaturationSum += nSaturationValue;
876 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
877 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
878 pHistogram[nHistogramIndex] += 0.4f * fWeight;
879 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] += 0.2f * fWeight;
880 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
881 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
882 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
886 fDeltaRight = (vLow.x - vRight.x) / (vLow.y - vRight.y);
888 for (
int i = nMiddle1; i < nMiddle2; i++)
890 nLeft = (int)(vUp.x + (i - nUp) * fDeltaLeft);
891 nRight = (int)(vRight.x + (i - nMiddle1) * fDeltaRight);
893 for (
int j = nLeft; j <= nRight; j++)
896 nSaturationValue = pHSVImage->pixels[nPixelIndex + 1];
897 nSaturationSum += nSaturationValue;
898 nHistogramIndex = pHSVImage->pixels[nPixelIndex] / nBucketSize;
899 fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (nSaturationValue * nSaturationValue));
900 pHistogram[nHistogramIndex] += 0.4f * fWeight;
901 pHistogram[(nHistogramIndex + nHistogramSize + 1) % nHistogramSize] += 0.2f * fWeight;
902 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
903 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
904 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
908 fDeltaLeft = (vLow.x - vLeft.x) / (vLow.y - vLeft.y);
910 for (
int i = nMiddle2; i < nLow; i++)
912 nLeft = (int)(vLeft.x + (i - nMiddle2) * fDeltaLeft);
913 nRight = (int)(vRight.x + (i - nMiddle1) * 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] += 0.2f * fWeight;
924 pHistogram[(nHistogramIndex + nHistogramSize - 1) % nHistogramSize] += 0.2f * fWeight;
925 pHistogram[(nHistogramIndex + nHistogramSize + 2) % nHistogramSize] += 0.1f * fWeight;
926 pHistogram[(nHistogramIndex + nHistogramSize - 2) % nHistogramSize] += 0.1f * fWeight;
935 for (
int i = 0; i < nHistogramSize; i++)
937 fSum += pHistogram[i];
942 const float fOneBySum = 1.0f / fSum;
944 for (
int i = 0; i < nHistogramSize; i++)
946 pHistogram[i] *= fOneBySum;
951 const float fDummy = 1.0f / (
float)nHistogramSize;
953 for (
int i = 0; i < nHistogramSize; i++)
955 pHistogram[i] = fDummy;