31 #include "Math/FloatMatrix.h"
32 #include "Math/FloatVector.h"
33 #include "Math/LinearAlgebra.h"
34 #include <Calibration/Calibration.h>
35 #include <Features/SIFTFeatures/SIFTFeatureCalculator.h>
36 #include <Features/SIFTFeatures/SIFTFeatureEntry.h>
37 #include <Image/ByteImage.h>
38 #include <Image/ImageProcessor.h>
53 this->calibration = calibration;
56 m_pSIFTFeatureCalculator =
new CSIFTFeatureCalculator();
63 m_pHypothesesCoveringImage =
65 m_pSaliencyHypothesisRegionsImage =
75 new LCCPSegmentationWrapper(6, 15.0, 0.0, 1.0, 4.0,
false, 10.0, 0.1, 0,
false,
true, 800);
77 new LCCPSegmentationWrapper(15, 26.0, 0.0, 1.0, 4.0,
false, 10.0, 0.1, 0,
false,
true, 800);
93 delete m_pSIFTFeatureCalculator;
94 delete m_pSaliencyImage;
95 delete m_pHypothesesCoveringImage;
96 delete m_pSaliencyHypothesisRegionsImage;
97 delete m_pTempImageGray;
100 delete lccpSegmentation1;
101 delete lccpSegmentation2;
107 CByteImage* pImageRightColor,
108 CByteImage* pImageLeftGrey,
109 CByteImage* pImageRightGrey,
111 std::vector<CMSERDescriptor3D*>& aAllMSERs,
112 std::vector<CHypothesisPoint*>& aPointsFromDisparity,
117 omp_set_nested(
true);
119 timeval tStartAll, tEndAll;
120 timeval tStart, tEnd;
122 gettimeofday(&tStartAll, 0);
129 m_vFeaturePoints3d.Clear();
133 for (
int i = 0; i < aAllSIFTPoints.GetSize(); i++)
135 m_vFeaturePoints3d.AddElement(aAllSIFTPoints[i]->point3d);
141 SortMSERsByX(aAllMSERs);
143 std::vector<Vec3d> aMSERSigmaPoints;
146 for (
int i = 0; i < (int)aAllMSERs.size(); i++)
148 m_vFeaturePoints3d.AddElement(aAllMSERs.at(i)->vPosition);
152 if (aAllMSERs.at(i)->pRegionLeft->fEigenvalue1 > 25.0f)
154 m_vFeaturePoints3d.AddElement(aAllMSERs.at(i)->vSigmaPoint1a);
155 m_vFeaturePoints3d.AddElement(aAllMSERs.at(i)->vSigmaPoint1b);
156 aMSERSigmaPoints.push_back(aAllMSERs.at(i)->vSigmaPoint1a);
157 aMSERSigmaPoints.push_back(aAllMSERs.at(i)->vSigmaPoint1b);
160 if (aAllMSERs.at(i)->pRegionLeft->fEigenvalue2 > 25.0f)
162 m_vFeaturePoints3d.AddElement(aAllMSERs.at(i)->vSigmaPoint2a);
163 m_vFeaturePoints3d.AddElement(aAllMSERs.at(i)->vSigmaPoint2b);
164 aMSERSigmaPoints.push_back(aAllMSERs.at(i)->vSigmaPoint2a);
165 aMSERSigmaPoints.push_back(aAllMSERs.at(i)->vSigmaPoint2b);
178 int nNumSingleColoredRegionHypotheses = 0;
180 #ifdef OLP_FIND_UNICOLORED_HYPOTHESES
182 gettimeofday(&tStart, 0);
185 const int nNumPoints = aPointsFromDisparity.size();
186 Vec2d* pDepthMapPoints2D =
new Vec2d[nNumPoints];
188 for (
int i = 0; i < nNumPoints; i++)
190 calibration->WorldToImageCoordinates(
191 aPointsFromDisparity.at(i)->vPosition, pDepthMapPoints2D[i],
false);
195 std::vector<CMSERDescriptor3D*> aFilteredMSERs;
197 for (
size_t i = 0; i < aAllMSERs.size(); i++)
202 aFilteredMSERs.push_back(aAllMSERs.at(i));
207 SortMSERsBySize(aFilteredMSERs);
209 for (
size_t i = 0; i < aFilteredMSERs.size(); i++)
211 for (
size_t j = i + 1; j < aFilteredMSERs.size(); j++)
214 if (Math3d::Distance(aFilteredMSERs.at(i)->vPosition, aFilteredMSERs.at(j)->vPosition) <
218 for (
size_t k = j + 1; k < aFilteredMSERs.size(); k++)
220 aFilteredMSERs.at(k - 1) = aFilteredMSERs.at(k);
223 aFilteredMSERs.pop_back();
230 const float fPixelDistanceTolerance2 = fPixelDistanceTolerance * fPixelDistanceTolerance;
231 #pragma omp parallel for schedule(dynamic, 1)
232 for (
size_t i = 0; i < aFilteredMSERs.size(); i++)
239 const std::vector<Vec2d>* pRegionPoints = aFilteredMSERs.at(i)->pRegionLeft->pPoints2D;
242 float minX = pRegionPoints->at(0).x;
243 float minY = pRegionPoints->at(0).y;
244 float maxX = pRegionPoints->at(0).x;
245 float maxY = pRegionPoints->at(0).y;
247 for (
size_t k = 1; k < pRegionPoints->size(); k++)
249 minX = (pRegionPoints->at(k).x < minX) ? pRegionPoints->at(k).x : minX;
250 minY = (pRegionPoints->at(k).y < minY) ? pRegionPoints->at(k).y : minY;
251 maxX = (pRegionPoints->at(k).x > maxX) ? pRegionPoints->at(k).x : maxX;
252 maxY = (pRegionPoints->at(k).y > maxY) ? pRegionPoints->at(k).y : maxY;
255 minX -= fPixelDistanceTolerance;
256 minY -= fPixelDistanceTolerance;
257 maxX += fPixelDistanceTolerance;
258 maxY += fPixelDistanceTolerance;
260 CVec3dArray pNewColorHypothesisPoints;
262 for (
int j = 0; j < nNumPoints; j++)
264 const float x = pDepthMapPoints2D[j].x;
265 const float y = pDepthMapPoints2D[j].y;
267 if (minX < x && minY < y && x < maxX && y < maxY)
270 for (
size_t k = 0; k < pRegionPoints->size(); k++)
272 if ((x - pRegionPoints->at(k).x) * (x - pRegionPoints->at(k).x) +
273 (y - pRegionPoints->at(k).y) * (y - pRegionPoints->at(k).y) <
274 fPixelDistanceTolerance2)
276 pNewColorHypothesisPoints.AddElement(aPointsFromDisparity.at(j)->vPosition);
289 for (
int j = 0; j < pNewColorHypothesisPoints.GetSize(); j++)
291 paSingleColoredRegions[nNumSingleColoredRegionHypotheses].AddElement(
292 pNewColorHypothesisPoints[j]);
295 nNumSingleColoredRegionHypotheses++;
298 pNewColorHypothesisPoints.Clear();
303 gettimeofday(&tEnd, 0);
305 (1000 * tEnd.tv_sec + tEnd.tv_usec / 1000) - (1000 * tStart.tv_sec + tStart.tv_usec / 1000);
308 << aFilteredMSERs.size() <<
" unique MSERs. Found "
309 << nNumSingleColoredRegionHypotheses <<
" unicolored object hypotheses. Took "
310 << tTimeDiff <<
"ms.";
321 gettimeofday(&tStart, 0);
322 const int maxNumLccpHypotheses = 3000;
323 CVec3dArray* lccpSegmentPoints1 =
new CVec3dArray[maxNumLccpHypotheses];
324 CVec3dArray* lccpSegmentPoints2 =
new CVec3dArray[maxNumLccpHypotheses];
325 int nNumLCCPSegmentHypotheses1 = 0;
326 int nNumLCCPSegmentHypotheses2 = 0;
328 lccpSegmentation1->CreateHypothesesFromLCCPSegments(
329 aPointsFromDisparity, maxNumLccpHypotheses, lccpSegmentPoints1, nNumLCCPSegmentHypotheses1);
330 lccpSegmentation2->CreateHypothesesFromLCCPSegments(
331 aPointsFromDisparity, maxNumLccpHypotheses, lccpSegmentPoints2, nNumLCCPSegmentHypotheses2);
333 int nNumLCCPSegmentHypotheses = nNumLCCPSegmentHypotheses1 + nNumLCCPSegmentHypotheses2;
334 CVec3dArray* lccpSegmentPoints =
new CVec3dArray[nNumLCCPSegmentHypotheses];
335 for (
int i = 0; i < nNumLCCPSegmentHypotheses1; i++)
337 lccpSegmentPoints[i] = lccpSegmentPoints1[i];
339 for (
int i = 0; i < nNumLCCPSegmentHypotheses2; i++)
341 lccpSegmentPoints[nNumLCCPSegmentHypotheses1 + i] = lccpSegmentPoints2[i];
347 gettimeofday(&tEnd, 0);
349 (1000 * tEnd.tv_sec + tEnd.tv_usec / 1000) - (1000 * tStart.tv_sec + tStart.tv_usec / 1000);
350 ARMARX_VERBOSE_S <<
"Time for finding LCCP segments: " << tTimeDiff <<
" ms";
359 gettimeofday(&tStart, 0);
364 int nNumberOfPlanes = 0;
366 int nNumberOfPlanesAfterClustering = 0;
368 CVec3dArray** pPlanePointsAfterClustering =
375 int nNumberOfCylinders = 0;
376 const int nMaxNumberOfClustersPerCylinder = nMaxNumberOfClustersPerPlane;
377 int nNumberOfCylindersAfterClustering = 0;
378 const float fBICFactorCylinders = fBICFactorPlanes;
379 CVec3dArray** pCylinderPointsAfterClustering =
381 Vec3d* pCylinderAxesAfterClustering =
383 Vec3d* pCylinderCentersAfterClustering =
385 float* pCylinderRadiusesAfterClustering =
391 int nNumberOfSpheres = 0;
393 #ifdef OLP_FIND_PLANES
397 #ifdef OLP_FIND_CYLINDERS
399 const float fMaxCylinderRadius = 50.0f;
402 #ifdef OLP_FIND_SPHERES
405 const float fMaxSphereRadius = 80.0f;
409 bool bFoundObject =
true;
411 int nNumberOfPointsOnPlane, nNumberOfPointsOnSphere;
412 int nNumberOfPointsOnCylinder = 1000000;
419 #ifdef OLP_FIND_PLANES
421 bFoundPlane = RANSACPlane(m_vFeaturePoints3d,
422 fRansacThresholdPlanes,
423 nRansacIterationsPlanes,
424 paPlanes[nNumberOfPlanes],
425 pPlaneNormals[nNumberOfPlanes],
426 pPlaneDs[nNumberOfPlanes]);
427 nNumberOfPointsOnPlane = bFoundPlane ? paPlanes[nNumberOfPlanes].GetSize() : 0;
434 nNumberOfPointsOnPlane = 0;
437 #ifdef OLP_FIND_SPHERES
438 bFoundSphere = RANSACSphere(m_vFeaturePoints3d,
439 fRansacThresholdSpheres,
441 nRansacIterationsSpheres,
442 paSpheres[nNumberOfSpheres],
443 pSphereCenters[nNumberOfSpheres],
444 pSphereRadiuses[nNumberOfSpheres]);
449 ? paSpheres[nNumberOfSpheres].GetSize()
454 nNumberOfPointsOnSphere = 0;
459 nNumberOfPointsOnSphere = 0;
462 #ifdef OLP_FIND_CYLINDERS
464 if ((nNumberOfPointsOnPlane < nNumberOfPointsOnCylinder) &&
465 (nNumberOfPointsOnSphere < nNumberOfPointsOnCylinder))
468 bFoundCylinder = RANSACCylinders2(m_vFeaturePoints3d,
470 fRansacThresholdCylinders,
472 paCylinders[nNumberOfCylinders],
473 pCylinderAxes[nNumberOfCylinders],
474 pCylinderCenters[nNumberOfCylinders],
475 pCylinderRadiuses[nNumberOfCylinders]);
479 nNumberOfPointsOnCylinder =
481 ? paCylinders[nNumberOfCylinders].GetSize()
486 nNumberOfPointsOnCylinder = 0;
495 nNumberOfPointsOnCylinder = 0;
500 if ((nNumberOfPointsOnCylinder > nNumberOfPointsOnPlane) &&
501 (nNumberOfPointsOnCylinder > nNumberOfPointsOnSphere))
503 RemoveOutliers(paCylinders[nNumberOfCylinders], 1.7f, NULL);
506 std::vector<CVec3dArray*> aaPointClusters;
507 ClusterXMeans(paCylinders[nNumberOfCylinders],
508 nMaxNumberOfClustersPerCylinder,
513 for (
int i = 0; i < (int)aaPointClusters.size(); i++)
515 RemoveOutliers(*aaPointClusters.at(i), 1.7f, NULL);
519 if (aaPointClusters.at(i)->GetSize() /
520 GetVariance(*aaPointClusters.at(i), vTemp) >
523 pCylinderPointsAfterClustering[nNumberOfCylindersAfterClustering] =
524 aaPointClusters.at(i);
525 pCylinderAxesAfterClustering[nNumberOfCylindersAfterClustering] =
526 pCylinderAxes[nNumberOfCylinders];
527 pCylinderCentersAfterClustering[nNumberOfCylindersAfterClustering] =
528 pCylinderCenters[nNumberOfCylinders];
529 pCylinderRadiusesAfterClustering[nNumberOfCylindersAfterClustering] =
530 pCylinderRadiuses[nNumberOfCylinders];
534 j < pCylinderPointsAfterClustering[nNumberOfCylindersAfterClustering]
538 for (
int k = 0; k < m_vFeaturePoints3d.GetSize(); k++)
540 if (m_vFeaturePoints3d[k].x ==
541 (*pCylinderPointsAfterClustering
542 [nNumberOfCylindersAfterClustering])[j]
544 m_vFeaturePoints3d[k].y ==
545 (*pCylinderPointsAfterClustering
546 [nNumberOfCylindersAfterClustering])[j]
548 m_vFeaturePoints3d[k].z ==
549 (*pCylinderPointsAfterClustering
550 [nNumberOfCylindersAfterClustering])[j]
553 const int nEnd = m_vFeaturePoints3d.GetSize() - 1;
554 m_vFeaturePoints3d[k] = m_vFeaturePoints3d[nEnd];
555 m_vFeaturePoints3d.DeleteElement(nEnd);
561 nNumberOfCylindersAfterClustering++;
566 aaPointClusters.clear();
570 nNumberOfCylinders++;
572 else if (nNumberOfPointsOnSphere > nNumberOfPointsOnPlane)
574 RemoveOutliers(paSpheres[nNumberOfSpheres], 1.6f, NULL);
579 for (
int j = 0; j < paSpheres[nNumberOfSpheres].GetSize(); j++)
581 for (
int l = 0; l < m_vFeaturePoints3d.GetSize(); l++)
583 if (m_vFeaturePoints3d[l].x == paSpheres[nNumberOfSpheres][j].x &&
584 m_vFeaturePoints3d[l].y == paSpheres[nNumberOfSpheres][j].y &&
585 m_vFeaturePoints3d[l].z == paSpheres[nNumberOfSpheres][j].z)
587 const int nEnd = m_vFeaturePoints3d.GetSize() - 1;
588 m_vFeaturePoints3d[l] = m_vFeaturePoints3d[nEnd];
589 m_vFeaturePoints3d.DeleteElement(nEnd);
598 else if (bFoundPlane)
600 RemoveOutliers(paPlanes[nNumberOfPlanes], 1.7f, NULL);
603 std::vector<CVec3dArray*> aaPointClusters;
604 ClusterXMeans(paPlanes[nNumberOfPlanes],
605 nMaxNumberOfClustersPerPlane,
610 for (
int i = 0; i < (int)aaPointClusters.size(); i++)
612 RemoveOutliers(*aaPointClusters.at(i), 1.7f, NULL);
613 RemoveOutliers(*aaPointClusters.at(i), 2.0f, NULL);
617 if (aaPointClusters.at(i)->GetSize() /
618 GetVariance(*aaPointClusters.at(i), vTemp) >
621 pPlanePointsAfterClustering[nNumberOfPlanesAfterClustering] =
622 aaPointClusters.at(i);
627 pPlanePointsAfterClustering[nNumberOfPlanesAfterClustering]->GetSize();
630 for (
int k = 0; k < m_vFeaturePoints3d.GetSize(); k++)
632 if (m_vFeaturePoints3d[k].x ==
633 (*pPlanePointsAfterClustering
634 [nNumberOfPlanesAfterClustering])[j]
636 m_vFeaturePoints3d[k].y ==
637 (*pPlanePointsAfterClustering
638 [nNumberOfPlanesAfterClustering])[j]
640 m_vFeaturePoints3d[k].z ==
641 (*pPlanePointsAfterClustering
642 [nNumberOfPlanesAfterClustering])[j]
645 const int nEnd = m_vFeaturePoints3d.GetSize() - 1;
646 m_vFeaturePoints3d[k] = m_vFeaturePoints3d[nEnd];
647 m_vFeaturePoints3d.DeleteElement(nEnd);
653 nNumberOfPlanesAfterClustering++;
658 aaPointClusters.clear();
666 bFoundObject =
false;
671 ARMARX_VERBOSE_S <<
"Found " << nNumberOfCylinders <<
" cylinders and " << nNumberOfPlanes
672 <<
" planes (" << nNumberOfPlanesAfterClustering
673 <<
" planes after clustering)";
675 gettimeofday(&tEnd, 0);
677 (1000 * tEnd.tv_sec + tEnd.tv_usec / 1000) - (1000 * tStart.tv_sec + tStart.tv_usec / 1000);
678 ARMARX_VERBOSE_S <<
"Time for finding planes, cylinders and spheres: " << tTimeDiff <<
" ms";
688 gettimeofday(&tStart, 0);
691 int nNumberOfUnstructuredClusters = 0;
692 CVec3dArray** pUnstructuredPointClusters = NULL;
693 #ifdef OLP_FIND_IRREGULAR_CLUSTERS
694 std::vector<CVec3dArray*> aaUnstructuredPointClusters;
702 pUnstructuredPointClusters =
new CVec3dArray*[nMaxNumberOfUnstructuredClusters];
705 RemoveOutliers(m_vFeaturePoints3d, 2.0f);
708 ClusterXMeans(m_vFeaturePoints3d,
709 nMaxNumberOfUnstructuredClusters,
710 fBICFactorLeftoverPoints,
711 aaUnstructuredPointClusters);
715 for (
int i = 0; i < (int)aaUnstructuredPointClusters.size(); i++)
717 RemoveOutliers(*aaUnstructuredPointClusters.at(i), 1.5f, NULL);
718 RemoveOutliers(*aaUnstructuredPointClusters.at(i), 2.0f, NULL);
722 if (aaUnstructuredPointClusters.at(i)->GetSize() /
723 GetVariance(*aaUnstructuredPointClusters.at(i), vTemp) >
726 pUnstructuredPointClusters[nNumberOfUnstructuredClusters] =
727 aaUnstructuredPointClusters.at(i);
731 j < pUnstructuredPointClusters[nNumberOfUnstructuredClusters]->GetSize();
734 for (
int k = 0; k < m_vFeaturePoints3d.GetSize(); k++)
736 if (m_vFeaturePoints3d[k].x ==
737 (*pUnstructuredPointClusters[nNumberOfUnstructuredClusters])[j].x &&
738 m_vFeaturePoints3d[k].y ==
739 (*pUnstructuredPointClusters[nNumberOfUnstructuredClusters])[j].y &&
740 m_vFeaturePoints3d[k].z ==
741 (*pUnstructuredPointClusters[nNumberOfUnstructuredClusters])[j].z)
743 const int nEnd = m_vFeaturePoints3d.GetSize() - 1;
744 m_vFeaturePoints3d[k] = m_vFeaturePoints3d[nEnd];
745 m_vFeaturePoints3d.DeleteElement(nEnd);
751 nNumberOfUnstructuredClusters++;
756 aaUnstructuredPointClusters.clear();
777 for (
int i = 0; i < nNumberOfPlanesAfterClustering; i++)
784 aObjectHypotheses.AddElement(pHypothesis);
788 for (
int i = 0; i < nNumberOfCylindersAfterClustering; i++)
791 pCylinderAxesAfterClustering[i],
792 pCylinderCentersAfterClustering[i],
793 pCylinderRadiusesAfterClustering[i],
798 aObjectHypotheses.AddElement(pHypothesis);
803 for (
int i = 0; i < nNumberOfSpheres; i++)
812 aObjectHypotheses.AddElement(pHypothesis);
817 for (
int i = 0; i < nNumberOfUnstructuredClusters; i++)
825 aObjectHypotheses.AddElement(pHypothesis);
829 for (
int i = 0; i < nNumSingleColoredRegionHypotheses; i++)
837 aObjectHypotheses.AddElement(pHypothesis);
842 ARMARX_VERBOSE_S <<
"Adding " << nNumLCCPSegmentHypotheses <<
" hypotheses from LCCP";
844 for (
int i = 0; i < nNumLCCPSegmentHypotheses; i++)
850 lccpSegmentPoints[i], aAllMSERs, aMSERSigmaPoints, pImageLeftColor, pImageLeftGrey);
852 aObjectHypotheses.AddElement(pHypothesis);
854 #ifdef OLP_MAKE_LCCP_SEG_IMAGES
855 CByteImage* segmentationImage =
858 pHypothesis, calibration, segmentationImage);
861 fileName.append(
"lccp0000.bmp");
862 int fileNumber = m_nIterations * 1000 + counter;
865 ARMARX_VERBOSE_S <<
"Saving LCCP segmentation image for segment " << i <<
": "
867 segmentationImage->SaveToFile(fileName.c_str());
868 delete segmentationImage;
880 #ifdef OLP_FIND_SALIENCY_HYPOTHESES
882 gettimeofday(&tStart, 0);
888 ImageProcessor::Zero(m_pHypothesesCoveringImage);
890 for (
int i = 0; i < aObjectHypotheses.GetSize(); i++)
893 aObjectHypotheses[i], calibration, m_pTempImageGray);
895 m_pHypothesesCoveringImage, m_pTempImageGray, m_pHypothesesCoveringImage);
898 ImageProcessor::Dilate(m_pHypothesesCoveringImage, m_pTempImageGray);
899 ImageProcessor::Dilate(m_pTempImageGray, m_pHypothesesCoveringImage);
900 ImageProcessor::Dilate(m_pHypothesesCoveringImage, m_pTempImageGray);
901 ImageProcessor::Dilate(m_pTempImageGray, m_pHypothesesCoveringImage);
902 ImageProcessor::Dilate(m_pHypothesesCoveringImage, m_pTempImageGray);
903 ImageProcessor::Erode(m_pTempImageGray, m_pHypothesesCoveringImage);
904 ImageProcessor::Erode(m_pHypothesesCoveringImage, m_pTempImageGray);
905 ImageProcessor::Erode(m_pTempImageGray, m_pHypothesesCoveringImage);
909 ImageProcessor::HistogramStretching(
910 m_pSaliencyImage, m_pSaliencyHypothesisRegionsImage, 0.5f, 1.0f);
914 m_pSaliencyHypothesisRegionsImage->pixels[i] =
915 (m_pHypothesesCoveringImage->pixels[i]) ? 0
916 : m_pSaliencyHypothesisRegionsImage->pixels[i];
922 std::vector<CHypothesisPoint*> aPointsInSalientRegions;
924 m_pSaliencyHypothesisRegionsImage,
926 aPointsInSalientRegions);
928 std::vector<std::vector<CHypothesisPoint*>> aSalientRegionsPointsClusters;
933 aSalientRegionsPointsClusters);
934 ARMARX_VERBOSE_S << aSalientRegionsPointsClusters.size() <<
" clusters in salient regions";
937 for (
size_t i = 0; i < aSalientRegionsPointsClusters.size(); i++)
939 CVec3dArray aTempArray;
941 for (
size_t j = 0; j < aSalientRegionsPointsClusters.at(i).size(); j++)
943 aTempArray.AddElement(aSalientRegionsPointsClusters.at(i).at(j)->vPosition);
946 RemoveOutliers(aTempArray, 1.5f, NULL);
951 aTempArray, aAllMSERs, aMSERSigmaPoints, pImageLeftColor, pImageLeftGrey);
953 aObjectHypotheses.AddElement(pHypothesis);
957 gettimeofday(&tEnd, 0);
959 (1000 * tEnd.tv_sec + tEnd.tv_usec / 1000) - (1000 * tStart.tv_sec + tStart.tv_usec / 1000);
971 for (
int i = 1; i < aObjectHypotheses.GetSize(); i++)
973 pHypothesis = aObjectHypotheses[i];
974 nSize = (int)aObjectHypotheses[i]->aNewPoints.size();
977 while ((j > 0) && ((int)aObjectHypotheses[j - 1]->aNewPoints.size() < nSize))
979 aObjectHypotheses[j] = aObjectHypotheses[j - 1];
983 aObjectHypotheses[j] = pHypothesis;
989 delete aObjectHypotheses[i];
990 aObjectHypotheses.DeleteElement(i);
994 for (
int i = 0; i < aObjectHypotheses.GetSize(); i++)
1027 delete[] pPlaneNormals;
1030 for (
int i = 0; i < nNumberOfPlanesAfterClustering; i++)
1032 delete pPlanePointsAfterClustering[i];
1035 delete[] pPlanePointsAfterClustering;
1037 delete[] paCylinders;
1038 delete[] pCylinderAxes;
1039 delete[] pCylinderCenters;
1040 delete[] pCylinderRadiuses;
1042 for (
int i = 0; i < nNumberOfCylindersAfterClustering; i++)
1044 delete pCylinderPointsAfterClustering[i];
1047 delete[] pCylinderPointsAfterClustering;
1048 delete[] pCylinderAxesAfterClustering;
1049 delete[] pCylinderCentersAfterClustering;
1050 delete[] pCylinderRadiusesAfterClustering;
1053 delete[] pSphereCenters;
1054 delete[] pSphereRadiuses;
1056 delete[] pUnstructuredPointClusters;
1061 gettimeofday(&tEndAll, 0);
1062 tTimeDiff = (1000 * tEndAll.tv_sec + tEndAll.tv_usec / 1000) -
1063 (1000 * tStartAll.tv_sec + tStartAll.tv_usec / 1000);
1064 ARMARX_VERBOSE_S <<
"Time for complete hypothesis generation: " << tTimeDiff <<
" ms";
1068 CHypothesisGeneration::GetVariance(
const CVec3dArray& avPoints,
Vec3d& vMean)
1073 float fVariance = 0;
1076 for (
int i = 0; i < avPoints.GetSize(); i++)
1078 vMean.x += avPoints[i].x;
1079 vMean.y += avPoints[i].y;
1080 vMean.z += avPoints[i].z;
1083 vMean.x /= (
float)avPoints.GetSize();
1084 vMean.y /= (
float)avPoints.GetSize();
1085 vMean.z /= (
float)avPoints.GetSize();
1088 for (
int i = 0; i < avPoints.GetSize(); i++)
1090 fVariance += (vMean.x - avPoints[i].x) * (vMean.x - avPoints[i].x) +
1091 (vMean.y - avPoints[i].y) * (vMean.y - avPoints[i].y) +
1092 (vMean.z - avPoints[i].z) * (vMean.z - avPoints[i].z);
1095 return (fVariance / (
float)avPoints.GetSize());
1099 CHypothesisGeneration::RemoveOutliers(CVec3dArray& avPoints,
1100 float fStdDevFactor,
1101 std::vector<int>* paIndices)
1103 if (avPoints.GetSize() < 9)
1109 const float fStandardDeviation = sqrtf(GetVariance(avPoints, vMean));
1110 const float fThreshold2 =
1111 fStdDevFactor * fStdDevFactor * fStandardDeviation * fStandardDeviation;
1116 if (paIndices != NULL)
1118 for (
int i = 0; i < avPoints.GetSize(); i++)
1120 fDist2 = (vMean.x - avPoints[i].x) * (vMean.x - avPoints[i].x) +
1121 (vMean.y - avPoints[i].y) * (vMean.y - avPoints[i].y) +
1122 (vMean.z - avPoints[i].z) * (vMean.z - avPoints[i].z);
1124 if (fDist2 > fThreshold2)
1126 avPoints[i] = avPoints[avPoints.GetSize() - 1];
1127 paIndices->at(i) = paIndices->at(avPoints.GetSize() - 1);
1128 avPoints.DeleteElement(avPoints.GetSize() - 1);
1129 paIndices->pop_back();
1136 for (
int i = 0; i < avPoints.GetSize(); i++)
1138 fDist2 = (vMean.x - avPoints[i].x) * (vMean.x - avPoints[i].x) +
1139 (vMean.y - avPoints[i].y) * (vMean.y - avPoints[i].y) +
1140 (vMean.z - avPoints[i].z) * (vMean.z - avPoints[i].z);
1142 if (fDist2 > fThreshold2)
1144 avPoints[i] = avPoints[avPoints.GetSize() - 1];
1145 avPoints.DeleteElement(avPoints.GetSize() - 1);
1153 CHypothesisGeneration::FindCylinder(
const CVec3dArray& avSamplePoints,
1154 const CVec3dArray& avAllPoints,
1155 const float fToleranceThreshold,
1156 const float fMaxRadius,
1157 CVec3dArray& avResultPoints,
1158 Vec3d& vCylinderAxis,
1159 Vec3d& vCylinderCenter,
1160 float& fCylinderRadius)
1162 avResultPoints.Clear();
1164 const int nNumberOfSamples = avSamplePoints.GetSize();
1166 if (nNumberOfSamples < 5)
1171 const int nNumberOfAllPoints = avAllPoints.GetSize();
1173 const Vec3d vZAxis = {0.0f, 0.0f, 1.0f};
1175 Vec3d vBestCylinderCenter, vBestCylinderAxis;
1176 float fBestCylinderRadius = 0;
1177 int nMaxNumberOfPointsOnCylinder = 0;
1179 Vec3d vAvgPoint = {0.0f, 0.0f, 0.0f};
1181 for (
int i = 0; i < nNumberOfSamples; i++)
1183 vAvgPoint.x += avSamplePoints[i].x;
1184 vAvgPoint.y += avSamplePoints[i].y;
1185 vAvgPoint.z += avSamplePoints[i].z;
1188 vAvgPoint.x /= (
float)nNumberOfSamples;
1189 vAvgPoint.y /= (
float)nNumberOfSamples;
1190 vAvgPoint.z /= (
float)nNumberOfSamples;
1192 CFloatMatrix mSamplePoints(3, nNumberOfSamples);
1194 for (
int i = 0; i < nNumberOfSamples; i++)
1196 mSamplePoints(0, i) = avSamplePoints[i].x - vAvgPoint.x;
1197 mSamplePoints(1, i) = avSamplePoints[i].y - vAvgPoint.y;
1198 mSamplePoints(2, i) = avSamplePoints[i].z - vAvgPoint.z;
1201 CFloatMatrix mEigenVectors(3, 3);
1202 CFloatMatrix mEigenValues(1, 3);
1203 CFloatMatrix mProjection(2, 3);
1204 Mat3d mTransformation;
1206 LinearAlgebra::PCA(&mSamplePoints, &mEigenVectors, &mEigenValues);
1214 Vec3d vTemp1, vTemp2;
1216 for (
int n = 0; n < 3; n++)
1222 vCylinderAxis.x = mEigenVectors(0, 0);
1223 vCylinderAxis.y = mEigenVectors(0, 1);
1224 vCylinderAxis.z = mEigenVectors(0, 2);
1225 Math3d::NormalizeVec(vCylinderAxis);
1229 mProjection(0, 0) = mEigenVectors(1, 0);
1230 mProjection(0, 1) = mEigenVectors(1, 1);
1231 mProjection(0, 2) = mEigenVectors(1, 2);
1232 mProjection(1, 0) = mEigenVectors(2, 0);
1233 mProjection(1, 1) = mEigenVectors(2, 1);
1234 mProjection(1, 2) = mEigenVectors(2, 2);
1238 mTransformation.r1 = mEigenVectors(0, 0);
1239 mTransformation.r2 = mEigenVectors(1, 0);
1240 mTransformation.r3 = mEigenVectors(2, 0);
1241 mTransformation.r4 = mEigenVectors(0, 1);
1242 mTransformation.r5 = mEigenVectors(1, 1);
1243 mTransformation.r6 = mEigenVectors(2, 1);
1244 mTransformation.r7 = mEigenVectors(0, 2);
1245 mTransformation.r8 = mEigenVectors(1, 2);
1246 mTransformation.r9 = mEigenVectors(2, 2);
1252 vCylinderAxis.x = mEigenVectors(1, 0);
1253 vCylinderAxis.y = mEigenVectors(1, 1);
1254 vCylinderAxis.z = mEigenVectors(1, 2);
1255 Math3d::NormalizeVec(vCylinderAxis);
1259 mProjection(0, 0) = mEigenVectors(0, 0);
1260 mProjection(0, 1) = mEigenVectors(0, 1);
1261 mProjection(0, 2) = mEigenVectors(0, 2);
1262 mProjection(1, 0) = mEigenVectors(2, 0);
1263 mProjection(1, 1) = mEigenVectors(2, 1);
1264 mProjection(1, 2) = mEigenVectors(2, 2);
1268 mTransformation.r1 = mEigenVectors(1, 0);
1269 mTransformation.r2 = mEigenVectors(0, 0);
1270 mTransformation.r3 = mEigenVectors(2, 0);
1271 mTransformation.r4 = mEigenVectors(1, 1);
1272 mTransformation.r5 = mEigenVectors(0, 1);
1273 mTransformation.r6 = mEigenVectors(2, 1);
1274 mTransformation.r7 = mEigenVectors(1, 2);
1275 mTransformation.r8 = mEigenVectors(0, 2);
1276 mTransformation.r9 = mEigenVectors(2, 2);
1283 if (fabs(mEigenVectors(0, 1)) > fabs(mEigenVectors(1, 1)))
1285 if (fabs(mEigenVectors(0, 1)) > fabs(mEigenVectors(2, 1)))
1287 vCylinderAxis.x = mEigenVectors(0, 0);
1288 vCylinderAxis.y = 2.0f * mEigenVectors(0, 1);
1289 vCylinderAxis.z = mEigenVectors(0, 2);
1293 vCylinderAxis.x = mEigenVectors(2, 0);
1294 vCylinderAxis.y = 2.0f * mEigenVectors(2, 1);
1295 vCylinderAxis.z = mEigenVectors(2, 2);
1300 if (fabs(mEigenVectors(1, 1)) > fabs(mEigenVectors(2, 1)))
1302 vCylinderAxis.x = mEigenVectors(1, 0);
1303 vCylinderAxis.y = 2.0f * mEigenVectors(1, 1);
1304 vCylinderAxis.z = mEigenVectors(1, 2);
1305 Math3d::NormalizeVec(vCylinderAxis);
1309 vCylinderAxis.x = mEigenVectors(2, 0);
1310 vCylinderAxis.y = 2.0f * mEigenVectors(2, 1);
1311 vCylinderAxis.z = mEigenVectors(2, 2);
1315 Math3d::NormalizeVec(vCylinderAxis);
1318 Math3d::CrossProduct(vCylinderAxis, vZAxis, vTemp1);
1319 Math3d::NormalizeVec(vTemp1);
1320 Math3d::CrossProduct(vCylinderAxis, vTemp1, vTemp2);
1323 mProjection(0, 0) = vTemp1.x;
1324 mProjection(0, 1) = vTemp1.y;
1325 mProjection(0, 2) = vTemp1.z;
1326 mProjection(1, 0) = vTemp2.x;
1327 mProjection(1, 1) = vTemp2.y;
1328 mProjection(1, 2) = vTemp2.z;
1332 mTransformation.r1 = vCylinderAxis.x;
1333 mTransformation.r2 = vTemp1.x;
1334 mTransformation.r3 = vTemp2.x;
1335 mTransformation.r4 = vCylinderAxis.y;
1336 mTransformation.r5 = vTemp1.y;
1337 mTransformation.r6 = vTemp2.y;
1338 mTransformation.r7 = vCylinderAxis.z;
1339 mTransformation.r8 = vTemp1.z;
1340 mTransformation.r9 = vTemp2.z;
1346 vCylinderAxis.x = 0.0f;
1347 vCylinderAxis.y = 1.0f;
1348 vCylinderAxis.z = 0.0f;
1352 mProjection(0, 0) = 1.0f;
1353 mProjection(0, 1) = 0.0f;
1354 mProjection(0, 2) = 0.0f;
1355 mProjection(1, 0) = 0.0f;
1356 mProjection(1, 1) = 0.0f;
1357 mProjection(1, 2) = 1.0f;
1361 mTransformation.r1 = 0.0f;
1362 mTransformation.r2 = 1.0f;
1363 mTransformation.r3 = 0.0f;
1364 mTransformation.r4 = 1.0f;
1365 mTransformation.r5 = 0.0f;
1366 mTransformation.r6 = 0.0f;
1367 mTransformation.r7 = 0.0f;
1368 mTransformation.r8 = 0.0f;
1369 mTransformation.r9 = 1.0f;
1374 CFloatMatrix mProjectedPoints(2, nNumberOfSamples);
1375 LinearAlgebra::MulMatMat(&mSamplePoints, &mProjection, &mProjectedPoints);
1385 QuickSort2DPointsX(mProjectedPoints, 0, nNumberOfSamples - 1);
1393 float fCenterX = 0, fCenterY = 0;
1397 float xi = 0, yi = 0, xj = 0, yj = 0, xk = 0, yk = 0;
1399 int nTwentyPercent = nNumberOfSamples / 5;
1415 for (
int i = 0; i < nTwentyPercent; i++)
1417 xi += mProjectedPoints(0, i);
1418 yi += mProjectedPoints(1, i);
1421 for (
int i = 2 * nTwentyPercent; i < 3 * nTwentyPercent; i++)
1423 xj += mProjectedPoints(0, i);
1424 yj += mProjectedPoints(1, i);
1427 for (
int i = 4 * nTwentyPercent; i < nNumberOfSamples; i++)
1429 xk += mProjectedPoints(0, i);
1430 yk += mProjectedPoints(1, i);
1433 const float fOneByNumUsedSamples = 1.0f / (
float)nNumberOfSamples;
1434 xi *= fOneByNumUsedSamples;
1435 yi *= fOneByNumUsedSamples;
1436 xj *= fOneByNumUsedSamples;
1437 yj *= fOneByNumUsedSamples;
1438 xk *= fOneByNumUsedSamples;
1439 yk *= fOneByNumUsedSamples;
1442 const float fDelta1 = (xi * (yk - yj) + xj * (yi - yk) + xk * (yj - yi));
1448 if (fabs(fDelta1) > 0.001f)
1450 fCenterX = 0.5f / fDelta1 *
1451 ((yk - yj) * (xi * xi + yi * yi) + (yi - yk) * (xj * xj + yj * yj) +
1452 (yj - yi) * (xk * xk + yk * yk));
1453 fCenterY = -0.5f / fDelta1 *
1454 ((xk - xj) * (xi * xi + yi * yi) + (xi - xk) * (xj * xj + yj * yj) +
1455 (xj - xi) * (xk * xk + yk * yk));
1541 Vec3d vCenter2D = {0.0f, fCenterX, fCenterY};
1544 Mat3d mInverseTransformation;
1545 Math3d::Invert(mTransformation, mInverseTransformation);
1546 Math3d::MulMatVec(mInverseTransformation, vCenter2D, vCylinderCenter);
1548 vCylinderCenter.x += vAvgPoint.x;
1549 vCylinderCenter.y += vAvgPoint.y;
1550 vCylinderCenter.z += vAvgPoint.z;
1554 fCylinderRadius = 0;
1556 for (
int i = 0; i < nNumberOfSamples; i++)
1558 Math3d::SubtractVecVec(avSamplePoints[i], vCylinderCenter, vTemp1);
1559 Math3d::CrossProduct(vCylinderAxis, vTemp1, vTemp2);
1560 fCylinderRadius += Math3d::Length(vTemp2);
1563 fCylinderRadius /= (
float)nNumberOfSamples;
1573 if (fCylinderRadius < fMaxRadius)
1579 Math3d::CrossProduct(vCylinderAxis, vZAxis, vTemp1);
1580 Math3d::CrossProduct(vCylinderAxis, vTemp1, vPlaneNormal);
1581 const float fD = -Math3d::ScalarProduct(vPlaneNormal, vCylinderCenter);
1586 int nNumberOfPointsOnCylinder = 0;
1588 for (
int i = 0; i < nNumberOfAllPoints; i++)
1593 fTemp = Math3d::ScalarProduct(vPlaneNormal, avAllPoints[i]) + fD;
1598 Math3d::SubtractVecVec(avAllPoints[i], vCylinderCenter, vTemp1);
1599 Math3d::CrossProduct(vCylinderAxis, vTemp1, vTemp2);
1600 fDist = Math3d::Length(vTemp2);
1603 if (fabsf(fDist - fCylinderRadius) <= fToleranceThreshold)
1605 nNumberOfPointsOnCylinder++;
1610 if (nNumberOfPointsOnCylinder > nMaxNumberOfPointsOnCylinder)
1612 nMaxNumberOfPointsOnCylinder = nNumberOfPointsOnCylinder;
1614 Math3d::SetVec(vBestCylinderCenter, vCylinderCenter);
1615 Math3d::SetVec(vBestCylinderAxis, vCylinderAxis);
1616 fBestCylinderRadius = fCylinderRadius;
1624 if (nMaxNumberOfPointsOnCylinder == 0)
1630 Math3d::SetVec(vCylinderCenter, vBestCylinderCenter);
1631 Math3d::SetVec(vCylinderAxis, vBestCylinderAxis);
1632 fCylinderRadius = fBestCylinderRadius;
1637 for (
int i = 0; i < nNumberOfAllPoints; i++)
1639 Math3d::SubtractVecVec(avAllPoints[i], vBestCylinderCenter, vTemp1);
1640 Math3d::CrossProduct(vBestCylinderAxis, vTemp1, vTemp2);
1641 fDist = Math3d::Length(vTemp2);
1645 if (fabsf(fDist - fBestCylinderRadius) <= fToleranceThreshold)
1647 avResultPoints.AddElement(avAllPoints[i]);
1656 CHypothesisGeneration::QuickSort2DPointsX(CFloatMatrix& mPoints,
int nLeft,
int nRight)
1658 int nPivotPos, i, j;
1659 float fPivotElemX, fTempElemX, fTempElemY;
1661 while (nRight - nLeft >= 16)
1665 nPivotPos = nLeft + rand() % (nRight - nLeft);
1668 fTempElemX = mPoints(0, nLeft);
1669 fTempElemY = mPoints(1, nLeft);
1670 mPoints(0, nLeft) = mPoints(0, nPivotPos);
1671 mPoints(1, nLeft) = mPoints(1, nPivotPos);
1672 mPoints(0, nPivotPos) = fTempElemX;
1673 mPoints(1, nPivotPos) = fTempElemY;
1678 fPivotElemX = mPoints(0, nLeft);
1684 while (mPoints(0, i) < fPivotElemX)
1689 while (mPoints(0, j) > fPivotElemX)
1697 fTempElemX = mPoints(0, i);
1698 fTempElemY = mPoints(1, i);
1699 mPoints(0, i) = mPoints(0, j);
1700 mPoints(1, i) = mPoints(1, j);
1701 mPoints(0, j) = fTempElemX;
1702 mPoints(1, j) = fTempElemY;
1709 if (i < (nLeft + nRight) / 2)
1711 QuickSort2DPointsX(mPoints, nLeft, j);
1716 QuickSort2DPointsX(mPoints, i, nRight);
1724 for (i = nLeft + 1; i <= nRight; i++)
1726 fTempElemX = mPoints(0, i);
1727 fTempElemY = mPoints(1, i);
1730 while ((j > nLeft) && (mPoints(0, j - 1) > fTempElemX))
1732 mPoints(0, j) = mPoints(0, j - 1);
1733 mPoints(1, j) = mPoints(1, j - 1);
1737 mPoints(0, j) = fTempElemX;
1738 mPoints(1, j) = fTempElemY;
1744 CHypothesisGeneration::ClusterPointsRegularGrid2D(
const CVec3dArray& avPoints,
1745 const CCalibration* calibration,
1746 const int nNumSectionsX,
1747 const int nNumSectionsY,
1748 CVec3dArray*& pClusters,
1751 nNumClusters = nNumSectionsX * nNumSectionsY + (nNumSectionsX + 1) * (nNumSectionsY + 1);
1752 int nShiftOffset = nNumSectionsX * nNumSectionsY;
1753 pClusters =
new CVec3dArray[nNumClusters];
1756 const int nNumPoints = avPoints.GetSize();
1758 int nIndex, nIndexShifted;
1764 for (
int i = 0; i < nNumPoints; i++)
1766 calibration->CameraToImageCoordinates(avPoints[i], vPoint2D,
false);
1768 nIndex = nNumSectionsX * ((int)vPoint2D.y / nIntervalY) + (int)vPoint2D.x / nIntervalX;
1770 nIndexShifted = (nNumSectionsX + 1) * (((int)vPoint2D.y + nIntervalY2) / nIntervalY) +
1771 ((
int)vPoint2D.x + nIntervalX2) / nIntervalX;
1777 if (nIndex + nIndex < nNumClusters)
1779 pClusters[nIndex].AddElement(avPoints[i]);
1782 if (nShiftOffset + nIndexShifted < nNumClusters)
1784 pClusters[nShiftOffset + nIndexShifted].AddElement(avPoints[i]);
1965 CHypothesisGeneration::RANSACCylinders2(
const CVec3dArray& avPoints,
1966 const CCalibration* calibration,
1967 const float fToleranceThreshold,
1968 const float fMaxRadius,
1969 CVec3dArray& avCylinder,
1970 Vec3d& vCylinderAxis,
1971 Vec3d& vCylinderCenter,
1972 float& fCylinderRadius)
1976 CVec3dArray avAxisBlacklist(nMaxAxisIterations);
1977 bool bBreakIfNextAxisIsBad =
false;
1978 Vec3d vBestCylinderAxis, vBestCylinderCenter;
1979 float fBestRadius = 0;
1990 int nNumGridClusters;
1993 nNumGridClusters = 1;
1994 const CVec3dArray* pRegularGridClusters = &avPoints;
1998 const int nOverallNumberOfPoints = avPoints.GetSize();
1999 CVec3dArray avGaussMap(nOverallNumberOfPoints);
2000 CVec3dArray avCorrespondingPoints(nOverallNumberOfPoints);
2001 int nMaxSupport = 0;
2004 for (
int i = 0; i < nNumGridClusters; i++)
2006 const int nClusterSize = pRegularGridClusters[i].GetSize();
2008 if (nClusterSize >= 5)
2010 #pragma omp parallel
2012 CFloatMatrix mSampleMatrix(3, 5);
2013 CFloatMatrix mU(5, 5);
2014 CFloatMatrix mSigma(3, 5);
2015 CFloatMatrix mV(3, 3);
2016 Vec3d vPoint, vNeighbour1, vNeighbour2, vNeighbour3, vNeighbour4, vNormal, vMean,
2018 float fMinDist1, fMinDist2, fMinDist3, fMinDist4, fDist;
2020 #pragma omp for schedule(static, 10)
2021 for (
int j = 0; j < nClusterSize; j++)
2024 Math3d::SetVec(vPoint, pRegularGridClusters[i][j]);
2025 fMinDist1 = 1000000;
2026 fMinDist2 = 1000000;
2027 fMinDist3 = 1000000;
2028 fMinDist4 = 1000000;
2030 for (
int k = 0; k < nClusterSize; k++)
2034 fDist = Math3d::Distance(vPoint, pRegularGridClusters[i][k]);
2036 if (fDist < fMinDist1)
2038 fMinDist4 = fMinDist3;
2039 Math3d::SetVec(vNeighbour4, vNeighbour3);
2040 fMinDist3 = fMinDist2;
2041 Math3d::SetVec(vNeighbour3, vNeighbour2);
2042 fMinDist2 = fMinDist1;
2043 Math3d::SetVec(vNeighbour2, vNeighbour1);
2045 Math3d::SetVec(vNeighbour1, pRegularGridClusters[i][k]);
2047 else if (fDist < fMinDist2)
2049 fMinDist4 = fMinDist3;
2050 Math3d::SetVec(vNeighbour4, vNeighbour3);
2051 fMinDist3 = fMinDist2;
2052 Math3d::SetVec(vNeighbour3, vNeighbour2);
2054 Math3d::SetVec(vNeighbour2, pRegularGridClusters[i][k]);
2056 else if (fDist < fMinDist3)
2058 fMinDist4 = fMinDist3;
2059 Math3d::SetVec(vNeighbour4, vNeighbour3);
2061 Math3d::SetVec(vNeighbour3, pRegularGridClusters[i][k]);
2063 else if (fDist < fMinDist4)
2066 Math3d::SetVec(vNeighbour4, pRegularGridClusters[i][k]);
2078 if (fMinDist2 < 25.0f)
2081 Math3d::SubtractVecVec(vNeighbour1, vPoint, vTemp1);
2082 Math3d::SubtractVecVec(vNeighbour2, vPoint, vTemp2);
2083 Math3d::CrossProduct(vTemp1, vTemp2, vNormal);
2084 Math3d::NormalizeVec(vNormal);
2086 if (Math3d::Length(vNormal) > 0.9f)
2088 #pragma omp critical
2090 avGaussMap.AddElement(vNormal);
2091 avCorrespondingPoints.AddElement(vPoint);
2096 if (fMinDist4 < 50.0f)
2098 vMean.x = 0.2f * (vPoint.x + vNeighbour1.x + vNeighbour2.x + vNeighbour3.x +
2100 vMean.y = 0.2f * (vPoint.y + vNeighbour1.y + vNeighbour2.y + vNeighbour3.y +
2102 vMean.z = 0.2f * (vPoint.z + vNeighbour1.z + vNeighbour2.z + vNeighbour3.z +
2105 mSampleMatrix(0, 0) = vPoint.x - vMean.x;
2106 mSampleMatrix(1, 0) = vPoint.y - vMean.y;
2107 mSampleMatrix(2, 0) = vPoint.z - vMean.z;
2108 mSampleMatrix(0, 1) = vNeighbour1.x - vMean.x;
2109 mSampleMatrix(1, 1) = vNeighbour1.y - vMean.y;
2110 mSampleMatrix(2, 1) = vNeighbour1.z - vMean.z;
2111 mSampleMatrix(0, 2) = vNeighbour2.x - vMean.x;
2112 mSampleMatrix(1, 2) = vNeighbour2.y - vMean.y;
2113 mSampleMatrix(2, 2) = vNeighbour2.z - vMean.z;
2114 mSampleMatrix(0, 3) = vNeighbour3.x - vMean.x;
2115 mSampleMatrix(1, 3) = vNeighbour3.y - vMean.y;
2116 mSampleMatrix(2, 3) = vNeighbour3.z - vMean.z;
2117 mSampleMatrix(0, 4) = vNeighbour4.x - vMean.x;
2118 mSampleMatrix(1, 4) = vNeighbour4.y - vMean.y;
2119 mSampleMatrix(2, 4) = vNeighbour4.z - vMean.z;
2121 LinearAlgebra::SVD(&mSampleMatrix, &mSigma, &mU, &mV);
2123 vNormal.x = mV(2, 0);
2124 vNormal.y = mV(2, 1);
2125 vNormal.z = mV(2, 2);
2126 Math3d::NormalizeVec(vNormal);
2128 if (Math3d::Length(vNormal) < 0.9f)
2136 #pragma omp critical
2138 avGaussMap.AddElement(vNormal);
2139 avCorrespondingPoints.AddElement(vPoint);
2292 for (
int n = 0; n < nMaxAxisIterations; n++)
2302 const int nGaussCircleIterations =
2305 : 2 * avGaussMap.GetSize();
2306 const int nNumberOfPointsInGaussMap = avGaussMap.GetSize();
2307 const float fGaussMapThreshold = 0.15f;
2308 const float fBadAxisFactor = 0.1f;
2309 int nMaxAxisSupport = 0;
2312 #pragma omp parallel
2314 int nFirstIndex, nSecondIndex, nSupport;
2315 Vec3d vPoint1, vPoint2, vNormal;
2316 bool bCloseToBadAxis;
2318 #pragma omp for schedule(static, 16)
2319 for (
int i = 0; i < nGaussCircleIterations; i++)
2322 srand((rand() % 17) * i + i);
2323 nFirstIndex = rand() % nNumberOfPointsInGaussMap;
2327 nSecondIndex = rand() % nNumberOfPointsInGaussMap;
2328 }
while (nSecondIndex == nFirstIndex);
2330 vPoint1 = avGaussMap[nFirstIndex];
2331 vPoint2 = avGaussMap[nSecondIndex];
2335 Math3d::CrossProduct(vPoint1, vPoint2, vNormal);
2336 Math3d::NormalizeVec(vNormal);
2339 if (Math3d::ScalarProduct(vNormal, vNormal) > 0.9f)
2342 bCloseToBadAxis =
false;
2344 for (
int j = 0; j < avAxisBlacklist.GetSize(); j++)
2347 (fabsf(Math3d::ScalarProduct(vNormal, avAxisBlacklist[j])) >
2348 1.0f - fBadAxisFactor * fGaussMapThreshold);
2351 if (!bCloseToBadAxis)
2356 for (
int j = 0; j < nNumberOfPointsInGaussMap; j++)
2358 if (fabsf(Math3d::ScalarProduct(vNormal, avGaussMap[j])) <
2366 if (nSupport > nMaxAxisSupport)
2368 #pragma omp critical
2369 if (nSupport > nMaxAxisSupport)
2371 nMaxAxisSupport = nSupport;
2372 Math3d::SetVec(vBestNormal, vNormal);
2388 if (bBreakIfNextAxisIsBad)
2394 else if (2 * n > nMaxAxisIterations)
2396 bBreakIfNextAxisIsBad =
true;
2398 avAxisBlacklist.AddElement(vBestNormal);
2404 avAxisBlacklist.AddElement(vBestNormal);
2418 CVec3dArray avCylinderCandidates;
2420 for (
int j = 0; j < nNumberOfPointsInGaussMap; j++)
2422 if (fabsf(Math3d::ScalarProduct(vBestNormal, avGaussMap[j])) <=
2423 1.0f * fGaussMapThreshold)
2426 bool bDouble =
false;
2428 for (
int i = 0; i < avCylinderCandidates.GetSize(); i++)
2430 if (avCorrespondingPoints[j].x == avCylinderCandidates[i].x)
2432 if ((avCorrespondingPoints[j].y == avCylinderCandidates[i].y) &&
2433 (avCorrespondingPoints[j].z == avCylinderCandidates[i].z))
2443 avCylinderCandidates.AddElement(avCorrespondingPoints[j]);
2452 const Vec3d vCylinderAxis = {vBestNormal.x, vBestNormal.y, vBestNormal.z};
2453 const Vec3d vZAxis = {0, 0, 1};
2454 Vec3d vTemp1, vTemp2;
2455 Math3d::CrossProduct(vCylinderAxis, vZAxis, vTemp1);
2456 Math3d::CrossProduct(vCylinderAxis, vTemp1, vTemp2);
2457 const Mat3d mTransform = {vCylinderAxis.x,
2466 Mat3d mTransformInv;
2467 Math3d::Invert(mTransform, mTransformInv);
2468 const int nNumCylinderCandidates = avCylinderCandidates.GetSize();
2469 CVec3dArray avCylinderCandidatesTransformed(nNumCylinderCandidates);
2471 for (
int i = 0; i < nNumCylinderCandidates; i++)
2473 Math3d::MulMatVec(mTransform, avCylinderCandidates[i], vTemp1);
2474 avCylinderCandidatesTransformed.AddElement(vTemp1);
2490 const float fMaxRadius2 =
2491 fMaxRadius * fMaxRadius;
2492 const float fToleranceThreshold2 = fToleranceThreshold * fToleranceThreshold;
2493 const int nMaxCircleIterations =
2495 const int nCircleIterationsPrep =
2497 sqrtf((
float)nNumCylinderCandidates));
2498 const int nCircleIterations = (nCircleIterationsPrep < nMaxCircleIterations)
2499 ? nCircleIterationsPrep
2500 : nMaxCircleIterations;
2512 #pragma omp parallel
2514 int nFirstIndex, nSecondIndex, nThirdIndex, nSupport;
2515 float xi, yi, xj, yj, xk, yk, fCenterX, fCenterY, fRadius2, fDist2;
2516 Vec3d vCylinderCenter, vTemp1, vTemp2;
2518 Vec3d vBestCylinderCenterLocal;
2519 float fBestRadiusLocal = 0;
2521 #pragma omp for schedule(static, 32)
2522 for (
int i = 0; i < nCircleIterations; i++)
2527 srand((rand() % 17) * i + i);
2528 nFirstIndex = rand() % nNumCylinderCandidates;
2532 nSecondIndex = rand() % nNumCylinderCandidates;
2533 }
while (nSecondIndex == nFirstIndex);
2537 nThirdIndex = rand() % nNumCylinderCandidates;
2538 }
while (nThirdIndex == nFirstIndex || nThirdIndex == nSecondIndex);
2540 xi = avCylinderCandidatesTransformed[nFirstIndex].y;
2541 yi = avCylinderCandidatesTransformed[nFirstIndex].z;
2542 xj = avCylinderCandidatesTransformed[nSecondIndex].y;
2543 yj = avCylinderCandidatesTransformed[nSecondIndex].z;
2544 xk = avCylinderCandidatesTransformed[nThirdIndex].y;
2545 yk = avCylinderCandidatesTransformed[nThirdIndex].z;
2548 const float fDelta = (xi * (yk - yj) + xj * (yi - yk) + xk * (yj - yi));
2551 if (fabs(fDelta) > 0.001f)
2553 fCenterX = 0.5f / fDelta *
2554 ((yk - yj) * (xi * xi + yi * yi) + (yi - yk) * (xj * xj + yj * yj) +
2555 (yj - yi) * (xk * xk + yk * yk));
2556 fCenterY = -0.5f / fDelta *
2557 ((xk - xj) * (xi * xi + yi * yi) + (xi - xk) * (xj * xj + yj * yj) +
2558 (xj - xi) * (xk * xk + yk * yk));
2559 fRadius2 = (fCenterX - xi) * (fCenterX - xi) +
2560 (fCenterY - yi) * (fCenterY - yi);
2569 if (fRadius2 < fMaxRadius2)
2575 Math3d::SetVec(vTemp1, 0, fCenterX, fCenterY);
2576 Math3d::MulMatVec(mTransformInv, vTemp1, vCylinderCenter);
2581 Math3d::CrossProduct(vCylinderAxis, vZAxis, vTemp1);
2582 Math3d::CrossProduct(vCylinderAxis, vTemp1, vPlaneNormal);
2583 const float fD = -Math3d::ScalarProduct(vPlaneNormal, vCylinderCenter);
2624 for (
int j = 0; j < nNumCylinderCandidates; j++)
2630 Math3d::ScalarProduct(vPlaneNormal, avCylinderCandidates[j]) + fD;
2634 Math3d::SubtractVecVec(
2635 avCylinderCandidates[j], vCylinderCenter, vTemp1);
2636 Math3d::CrossProduct(vCylinderAxis, vTemp1, vTemp2);
2637 fTemp = Math3d::ScalarProduct(vTemp2, vTemp2);
2640 fDist2 = fTemp - 2.0f * sqrtf(fTemp * fRadius2) + fRadius2;
2642 if (fDist2 < fToleranceThreshold2)
2649 if (nSupport > nMaxSupportLocal)
2651 nMaxSupportLocal = nSupport;
2652 Math3d::SetVec(vBestCylinderCenterLocal, vCylinderCenter);
2653 fBestRadiusLocal = sqrtf(fRadius2);
2659 #pragma omp critical
2660 if (nMaxSupportLocal > nMaxSupportForThisAxis)
2662 nMaxSupportForThisAxis = nMaxSupportLocal;
2664 if (nMaxSupportLocal > nMaxSupport)
2666 nMaxSupport = nMaxSupportLocal;
2667 Math3d::SetVec(vBestCylinderCenter, vBestCylinderCenterLocal);
2668 Math3d::SetVec(vBestCylinderAxis, vCylinderAxis);
2669 fBestRadius = fBestRadiusLocal;
2680 avAxisBlacklist.AddElement(vCylinderAxis);
2692 Vec3d vTemp1, vTemp2;
2694 for (
int j = 0; j < nOverallNumberOfPoints; j++)
2696 Math3d::SubtractVecVec(avPoints[j], vBestCylinderCenter, vTemp1);
2697 Math3d::CrossProduct(vBestCylinderAxis, vTemp1, vTemp2);
2698 fDist = Math3d::Length(vTemp2);
2700 if (fabsf(fDist - fBestRadius) <= fToleranceThreshold)
2702 avCylinder.AddElement(avPoints[j]);
2708 Math3d::SetVec(vCylinderAxis, vBestCylinderAxis);
2709 Math3d::SetVec(vCylinderCenter, vBestCylinderCenter);
2710 fCylinderRadius = fBestRadius;
2724 std::vector<CMSERDescriptor3D*>& aMSERs,
2725 std::vector<Vec3d>& aSigmaPoints,
2726 const CByteImage* pLeftColorImage,
2727 const CByteImage* pLeftGreyImage)
2733 const int nNum3dPoints = avPlanePoints.GetSize();
2740 for (
int i = 0; i < nNum3dPoints; i++)
2744 if (CreateFeatureDescriptorForPoint(pPoint,
2762 Math3d::SetVec(hResult->
vCenter, 0, 0, 0);
2764 for (
int i = 0; i < nNum3dPoints; i++)
2766 hResult->
vCenter.x += avPlanePoints[i].x;
2767 hResult->
vCenter.y += avPlanePoints[i].y;
2768 hResult->
vCenter.z += avPlanePoints[i].z;
2777 CFloatMatrix mPoints(3, nNum3dPoints);
2778 CFloatMatrix mEigenVectors(3, 3);
2779 CFloatMatrix mEigenValues(1, 3);
2781 for (
int i = 0; i < nNum3dPoints; i++)
2783 mPoints(0, i) = avPlanePoints[i].x - hResult->
vCenter.x;
2784 mPoints(1, i) = avPlanePoints[i].y - hResult->
vCenter.y;
2785 mPoints(2, i) = avPlanePoints[i].z - hResult->
vCenter.z;
2788 LinearAlgebra::PCA(&mPoints, &mEigenVectors, &mEigenValues);
2791 if (mEigenVectors(2, 2) < 0)
2793 hResult->
vNormal.x = mEigenVectors(2, 0);
2794 hResult->
vNormal.y = mEigenVectors(2, 1);
2795 hResult->
vNormal.z = mEigenVectors(2, 2);
2803 hResult->
vNormal.x = -mEigenVectors(2, 0);
2804 hResult->
vNormal.y = -mEigenVectors(2, 1);
2805 hResult->
vNormal.z = -mEigenVectors(2, 2);
2817 Math3d::NormalizeVec(hResult->
vNormal);
2821 hResult->
fStdDev1 = mEigenValues(0, 0);
2822 hResult->
fStdDev2 = mEigenValues(0, 1);
2827 for (
int i = 0; i < nNum3dPoints; i++)
2829 fDist = Math3d::Distance(hResult->
vCenter, avPlanePoints[i]);
2846 const Vec3d vCylinderAxis,
2847 const Vec3d vCylinderCenter,
2848 const float fCylinderRadius,
2849 std::vector<CMSERDescriptor3D*>& aMSERs,
2850 std::vector<Vec3d>& aSigmaPoints,
2851 const CByteImage* pLeftColorImage,
2852 const CByteImage* pLeftGreyImage)
2858 const int nNum3dPoints = avCylinderPoints.GetSize();
2860 #pragma omp parallel
2864 #pragma omp for schedule(static, 5)
2865 for (
int i = 0; i < nNum3dPoints; i++)
2869 if (CreateFeatureDescriptorForPoint(pPoint,
2870 avCylinderPoints[i],
2876 #pragma omp critical
2888 hResult->
fRadius = fCylinderRadius;
2892 const float fVariance = GetVariance(avCylinderPoints, vMean);
2897 Vec3d vCenterOnAxis = vCylinderCenter;
2898 Vec3d vTemp1, vTemp2;
2899 Math3d::SubtractVecVec(vMean, vCylinderCenter, vTemp1);
2900 Math3d::MulVecScalar(vCylinderAxis, Math3d::ScalarProduct(vCylinderAxis, vTemp1), vTemp2);
2901 Math3d::AddToVec(vCenterOnAxis, vTemp2);
2902 Math3d::SetVec(hResult->
vCenter, vCenterOnAxis);
2905 Math3d::SubtractVecVec(vMean, vCenterOnAxis, hResult->
vNormal);
2906 Math3d::NormalizeVec(hResult->
vNormal);
2922 for (
int i = 0; i < nNum3dPoints; i++)
2924 fDist = Math3d::Distance(hResult->
vCenter, avCylinderPoints[i]);
2940 const Vec3d vSphereCenter,
2941 const float fSphereRadius,
2942 std::vector<CMSERDescriptor3D*>& aMSERs,
2943 std::vector<Vec3d>& aSigmaPoints,
2944 const CByteImage* pLeftColorImage,
2945 const CByteImage* pLeftGreyImage)
2951 const int nNum3dPoints = avSpherePoints.GetSize();
2953 #pragma omp parallel
2957 #pragma omp for schedule(static, 5)
2958 for (
int i = 0; i < nNum3dPoints; i++)
2960 if (CreateFeatureDescriptorForPoint(pPoint,
2967 #pragma omp critical
2978 Math3d::SetVec(hResult->
vCenter, vSphereCenter);
2979 hResult->
fRadius = fSphereRadius;
2984 const float fVariance = GetVariance(avSpherePoints, vMean);
2985 Math3d::SubtractVecVec(vMean, vSphereCenter, hResult->
vNormal);
2986 Math3d::NormalizeVec(hResult->
vNormal);
2990 Vec3d vXAxis = {1, 0, 0};
3002 for (
int i = 0; i < nNum3dPoints; i++)
3004 fDist = Math3d::Distance(hResult->
vCenter, avSpherePoints[i]);
3019 CHypothesisGeneration::CreateFeatureDescriptorForPoint(
CHypothesisPoint* pPoint,
3021 std::vector<CMSERDescriptor3D*>& aMSERs,
3022 std::vector<Vec3d>& aSigmaPoints,
3023 const CByteImage* pLeftColorImage,
3024 const CByteImage* pLeftGreyImage)
3032 calibration->WorldToImageCoordinates(vPosition, vPos2d,
false);
3033 const int nIndexX = round(vPos2d.x);
3034 const int nIndexY = round(vPos2d.y);
3041 const float fIntensity = pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX)] +
3042 pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX) + 1] +
3043 pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX) + 2] +
3045 pPoint->
fIntensity = (fIntensity - 3) / (3 * 255);
3047 (pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX)] + 1) / fIntensity;
3049 (pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX) + 1] + 1) / fIntensity;
3051 (pLeftColorImage->pixels[3 * (nIndexY *
OLP_IMG_WIDTH + nIndexX) + 2] + 1) / fIntensity;
3054 int nRegionIndex = FindRegionForPoint(vPosition, aMSERs);
3056 if (nRegionIndex >= 0)
3066 if (PointIsInList(vPosition, aSigmaPoints))
3081 CHypothesisGeneration::RANSACPlane(
const CVec3dArray& pointCandidates,
3082 const float fRANSACThreshold,
3083 const int nIterations,
3084 CVec3dArray& resultPoints,
3088 const int nPointCandidates = pointCandidates.GetSize();
3090 if (nPointCandidates < 3)
3093 <<
"At least 3 point candidates must be provided for RANSAC::RANSAC3DPlane ("
3094 << nPointCandidates <<
" provided)";
3098 const int nParallelityFactor = omp_get_num_procs();
3099 omp_set_num_threads(nParallelityFactor);
3101 int* pMaxPar =
new int[nParallelityFactor];
3102 float* pBestC =
new float[nParallelityFactor];
3103 Vec3d* pBestN =
new Vec3d[nParallelityFactor];
3105 for (
int i = 0; i < nParallelityFactor; i++)
3109 pBestN[i] = Math3d::zero_vec;
3113 #pragma omp parallel
3115 const int nProcIndex = omp_get_thread_num();
3117 #pragma omp for schedule(dynamic, 200)
3118 for (
int i = 0; i < nIterations; i++)
3121 srand((rand() % 17) * i + i);
3122 const int nFirstIndex = rand() % nPointCandidates;
3128 nTempIndex = rand() % nPointCandidates;
3129 }
while (nTempIndex == nFirstIndex);
3131 const int nSecondIndex = nTempIndex;
3135 nTempIndex = rand() % nPointCandidates;
3136 }
while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex);
3138 const Vec3d& p1 = pointCandidates[nFirstIndex];
3139 const Vec3d& p2 = pointCandidates[nSecondIndex];
3140 const Vec3d& p3 = pointCandidates[nTempIndex];
3143 Math3d::SubtractVecVec(p2, p1, u1);
3144 Math3d::SubtractVecVec(p3, p1, u2);
3145 Math3d::CrossProduct(u1, u2, n);
3146 Math3d::NormalizeVec(n);
3147 const float c = Math3d::ScalarProduct(n, p1);
3150 if (Math3d::ScalarProduct(n, n) < 0.9f)
3158 for (
int j = 0; j < nPointCandidates; j++)
3159 if (fabsf(Math3d::ScalarProduct(n, pointCandidates[j]) -
c) <= fRANSACThreshold)
3165 if (nSupport > pMaxPar[nProcIndex])
3167 pMaxPar[nProcIndex] = nSupport;
3168 Math3d::SetVec(pBestN[nProcIndex], n);
3169 pBestC[nProcIndex] =
c;
3176 Vec3d vBestN = {0, 0, 0};
3178 for (
int i = 0; i < nParallelityFactor; i++)
3180 if (pMaxPar[i] > nMax)
3184 Math3d::SetVec(vBestN, pBestN[i]);
3189 resultPoints.Clear();
3191 for (
int i = 0; i < nPointCandidates; i++)
3193 if (fabsf(Math3d::ScalarProduct(pointCandidates[i], vBestN) - fBestC) <= fRANSACThreshold)
3195 resultPoints.AddElement(pointCandidates[i]);
3199 Math3d::SetVec(vAxis, vBestN);
3213 const CByteImage* pLeftGreyImage)
3215 CDynamicArray afSIFTDescriptors(10);
3216 m_pSIFTFeatureCalculator->CreateSIFTDescriptors(
3217 pLeftGreyImage, &afSIFTDescriptors, vPoint2d.x, vPoint2d.y, 0.8f,
false,
true);
3218 m_pSIFTFeatureCalculator->CreateSIFTDescriptors(
3219 pLeftGreyImage, &afSIFTDescriptors, vPoint2d.x, vPoint2d.y, 1.0f,
false,
true);
3220 m_pSIFTFeatureCalculator->CreateSIFTDescriptors(
3221 pLeftGreyImage, &afSIFTDescriptors, vPoint2d.x, vPoint2d.y, 1.25f,
false,
true);
3222 const int n = afSIFTDescriptors.GetSize();
3223 CSIFTFeatureEntry** ppFeatures =
new CSIFTFeatureEntry*[n];
3225 for (
int i = 0; i < n; i++)
3227 pFeatures->AddElement(
3228 (CSIFTFeatureEntry*)((CSIFTFeatureEntry*)afSIFTDescriptors[i])->Clone());
3229 afSIFTDescriptors[i]->bDelete =
false;
3230 ppFeatures[i] = (CSIFTFeatureEntry*)afSIFTDescriptors[i];
3233 afSIFTDescriptors.Clear();
3235 for (
int i = 0; i < n; i++)
3237 delete ppFeatures[i];
3240 delete[] ppFeatures;
3244 CHypothesisGeneration::ClusterXMeans(
const CVec3dArray& aPoints,
3245 const int nMaxNumClusters,
3246 const float fBICFactor,
3247 std::vector<CVec3dArray*>& aaPointClusters)
3250 cv::Mat mClusterLabels;
3251 cv::Mat pmClusterCenters;
3252 const int nNumberOfDifferentInitialisations = 5;
3253 cv::TermCriteria tTerminationCriteria(
3257 const int nNumberOfSamples = aPoints.GetSize();
3258 mSamples.create(nNumberOfSamples, 3, CV_32FC1);
3260 for (
int i = 0; i < nNumberOfSamples; i++)
3262 mSamples.at<
float>(i, 0) = aPoints[i].x;
3263 mSamples.at<
float>(i, 1) = aPoints[i].y;
3264 mSamples.at<
float>(i, 2) = aPoints[i].z;
3267 mClusterLabels.create(nNumberOfSamples, 1, CV_32SC1);
3271 Vec3d* pvClusterMeans =
new Vec3d[nMaxNumClusters];
3272 double* pdClusterVariances =
new double[nMaxNumClusters];
3273 int* pnClusterSizes =
new int[nMaxNumClusters];
3274 double dMinBIC = 10000000;
3276 double dKMeansCompactness, dLogVar, dBIC;
3278 for (
int i = 1; (i <= nMaxNumClusters) && (i < nNumberOfSamples); i++)
3280 #ifdef OLP_USE_NEW_OPENCV
3281 dKMeansCompactness = cv::kmeans(mSamples,
3284 tTerminationCriteria,
3285 nNumberOfDifferentInitialisations,
3286 cv::KMEANS_RANDOM_CENTERS,
3290 dKMeansCompactness = cv::kmeans(mSamples,
3293 tTerminationCriteria,
3294 nNumberOfDifferentInitialisations,
3295 cv::KMEANS_PP_CENTERS,
3302 double dMLVariance = 0;
3304 for (
int j = 0; j < i; j++)
3306 pvClusterMeans[j].x = 0;
3307 pvClusterMeans[j].y = 0;
3308 pvClusterMeans[j].z = 0;
3309 pdClusterVariances[j] = 0;
3310 pnClusterSizes[j] = 0;
3312 for (
int l = 0; l < nNumberOfSamples; l++)
3314 if (mClusterLabels.at<
int>(l, 0) == j)
3316 pvClusterMeans[j].x += mSamples.at<
float>(l, 0);
3317 pvClusterMeans[j].y += mSamples.at<
float>(l, 1);
3318 pvClusterMeans[j].z += mSamples.at<
float>(l, 2);
3319 pnClusterSizes[j]++;
3323 pvClusterMeans[j].x /= (
float)pnClusterSizes[j];
3324 pvClusterMeans[j].y /= (
float)pnClusterSizes[j];
3325 pvClusterMeans[j].z /= (
float)pnClusterSizes[j];
3327 for (
int l = 0; l < nNumberOfSamples; l++)
3329 if (mClusterLabels.at<
int>(l, 0) == j)
3331 pdClusterVariances[j] += (pvClusterMeans[j].x - mSamples.at<
float>(l, 0)) *
3332 (pvClusterMeans[j].x - mSamples.at<
float>(l, 0)) +
3333 (pvClusterMeans[j].y - mSamples.at<
float>(l, 1)) *
3334 (pvClusterMeans[j].x - mSamples.at<
float>(l, 1)) +
3335 (pvClusterMeans[j].z - mSamples.at<
float>(l, 2)) *
3336 (pvClusterMeans[j].x - mSamples.at<
float>(l, 2));
3340 if (pnClusterSizes[j] > 1)
3342 pdClusterVariances[j] /= (
float)(pnClusterSizes[j] - 1);
3346 pdClusterVariances[j] = 0;
3349 dMLVariance += pdClusterVariances[j];
3353 const int nNumberOfFreeParameters = (i - 1) + (3 * i) + i;
3354 dLogVar = log(dMLVariance);
3355 dBIC = fBICFactor * 0.35 * dLogVar +
3356 ((double)nNumberOfFreeParameters / (
double)nNumberOfSamples) *
3357 log((
double)nNumberOfSamples);
3371 #ifdef OLP_USE_NEW_OPENCV
3372 dKMeansCompactness = cv::kmeans(mSamples,
3375 tTerminationCriteria,
3376 nNumberOfDifferentInitialisations,
3377 cv::KMEANS_RANDOM_CENTERS,
3381 dKMeansCompactness = cv::kmeans(mSamples,
3384 tTerminationCriteria,
3385 nNumberOfDifferentInitialisations,
3386 cv::KMEANS_PP_CENTERS,
3409 aaPointClusters.clear();
3410 CVec3dArray* paDummy;
3412 for (
int i = 0; i < nOptK; i++)
3414 paDummy =
new CVec3dArray();
3415 aaPointClusters.push_back(paDummy);
3418 for (
int i = 0; i < nNumberOfSamples; i++)
3420 if ((mClusterLabels.at<
int>(i, 0) >= 0) && (mClusterLabels.at<
int>(i, 0) < nOptK))
3422 vPoint.x = mSamples.at<
float>(i, 0);
3423 vPoint.y = mSamples.at<
float>(i, 1);
3424 vPoint.z = mSamples.at<
float>(i, 2);
3425 aaPointClusters.at(mClusterLabels.at<
int>(i, 0))->AddElement(vPoint);
3429 ARMARX_WARNING_S <<
"Invalid cluster label: " << mClusterLabels.at<
int>(i, 0)
3430 <<
"nOptK: " << nOptK <<
", i: " << i
3431 <<
", nNumberOfSamples: " << nNumberOfSamples
3432 <<
", dKMeansCompactness: " << dKMeansCompactness;
3439 aaPointClusters.clear();
3440 CVec3dArray* paDummy =
new CVec3dArray();
3441 aaPointClusters.push_back(paDummy);
3444 for (
int i = 0; i < nNumberOfSamples; i++)
3446 vPoint.x = mSamples.at<
float>(i, 0);
3447 vPoint.y = mSamples.at<
float>(i, 1);
3448 vPoint.z = mSamples.at<
float>(i, 2);
3449 aaPointClusters.at(0)->AddElement(vPoint);
3454 delete[] pvClusterMeans;
3455 delete[] pdClusterVariances;
3456 delete[] pnClusterSizes;
3460 CHypothesisGeneration::SortMSERsBySize(std::vector<CMSERDescriptor3D*>& aRegions3D)
3465 for (
int i = 1; i < (int)aRegions3D.size(); i++)
3467 pTemp = aRegions3D.at(i);
3470 while ((j > 0) && (aRegions3D.at(j - 1)->pRegionLeft->nSize < pTemp->
pRegionLeft->
nSize))
3472 aRegions3D.at(j) = aRegions3D.at(j - 1);
3476 aRegions3D.at(j) = pTemp;
3481 CHypothesisGeneration::SortMSERsByX(std::vector<CMSERDescriptor3D*>& aRegions3D)
3486 for (
int i = 1; i < (int)aRegions3D.size(); i++)
3488 pTemp = aRegions3D.at(i);
3491 while ((j > 0) && (aRegions3D.at(j - 1)->vPosition.x > pTemp->
vPosition.x))
3493 aRegions3D.at(j) = aRegions3D.at(j - 1);
3497 aRegions3D.at(j) = pTemp;
3502 CHypothesisGeneration::FindRegionForPoint(
Vec3d vPoint, std::vector<CMSERDescriptor3D*>& aRegions3D)
3506 int nRight = (int)aRegions3D.size() - 1;
3509 while (nRight > nLeft + 1)
3511 nIndex = nLeft + ((nRight - nLeft) >> 1);
3513 if (vPoint.x < aRegions3D.at(nIndex)->vPosition.x)
3517 else if (vPoint.x > aRegions3D.at(nIndex)->vPosition.x)
3526 while ((i >= nLeft) && (vPoint.x == aRegions3D.at(i)->vPosition.x))
3528 if ((vPoint.y == aRegions3D.at(i)->vPosition.y) &&
3529 (vPoint.z == aRegions3D.at(i)->vPosition.z))
3542 while ((i <= nRight) && (vPoint.x == aRegions3D.at(i)->vPosition.x))
3544 if ((vPoint.y == aRegions3D.at(i)->vPosition.y) &&
3545 (vPoint.z == aRegions3D.at(i)->vPosition.z))
3559 if (nLeft <= nRight)
3561 if ((vPoint.x == aRegions3D.at(nLeft)->vPosition.x) &&
3562 (vPoint.y == aRegions3D.at(nLeft)->vPosition.y) &&
3563 (vPoint.z == aRegions3D.at(nLeft)->vPosition.z))
3567 else if ((vPoint.x == aRegions3D.at(nRight)->vPosition.x) &&
3568 (vPoint.y == aRegions3D.at(nRight)->vPosition.y) &&
3569 (vPoint.z == aRegions3D.at(nRight)->vPosition.z))
3579 CHypothesisGeneration::SortVec3dsByX(std::vector<Vec3d>& aPoints)
3584 for (
int i = 1; i < (int)aPoints.size(); i++)
3586 Math3d::SetVec(vTemp, aPoints.at(i));
3589 while ((j > 0) && (aPoints.at(j - 1).x > vTemp.x))
3591 Math3d::SetVec(aPoints.at(j), aPoints.at(j - 1));
3595 Math3d::SetVec(aPoints.at(j), vTemp);
3600 CHypothesisGeneration::PointIsInList(
Vec3d vPoint, std::vector<Vec3d>& aPoints)
3604 int nRight = (int)aPoints.size() - 1;
3607 while (nRight > nLeft + 1)
3609 nIndex = nLeft + ((nRight - nLeft) >> 1);
3611 if (vPoint.x < aPoints.at(nIndex).x)
3615 else if (vPoint.x > aPoints.at(nIndex).x)
3619 else if ((vPoint.y == aPoints.at(nIndex).y) && (vPoint.z == aPoints.at(nIndex).z))
3629 if (nLeft <= nRight)
3631 if ((vPoint.x == aPoints.at(nLeft).x) && (vPoint.y == aPoints.at(nLeft).y) &&
3632 (vPoint.z == aPoints.at(nLeft).z))
3636 else if ((vPoint.x == aPoints.at(nRight).x) && (vPoint.y == aPoints.at(nRight).y) &&
3637 (vPoint.z == aPoints.at(nRight).z))
3647 CHypothesisGeneration::CalculateSphere(
Vec3d vPoint1,
3696 float pSubmatrix[16];
3699 float fDetM11, fDetM12, fDetM13, fDetM14, fDetM15;
3790 Math3d::SetVec(pPoints[0], vPoint1);
3791 Math3d::SetVec(pPoints[1], vPoint2);
3792 Math3d::SetVec(pPoints[2], vPoint3);
3793 Math3d::SetVec(pPoints[3], vPoint4);
3796 for (
int i = 0; i < 4; i++)
3798 pSubmatrix[4 * i + 0] = pPoints[i].x;
3799 pSubmatrix[4 * i + 1] = pPoints[i].y;
3800 pSubmatrix[4 * i + 2] = pPoints[i].z;
3801 pSubmatrix[4 * i + 3] = 1;
3807 for (
int i = 0; i < 4; i++)
3809 pSubmatrix[4 * i + 0] =
3810 pPoints[i].x * pPoints[i].x + pPoints[i].y * pPoints[i].y + pPoints[i].z * pPoints[i].z;
3811 pSubmatrix[4 * i + 1] = pPoints[i].y;
3812 pSubmatrix[4 * i + 2] = pPoints[i].z;
3813 pSubmatrix[4 * i + 3] = 1;
3819 for (
int i = 0; i < 4; i++)
3821 pSubmatrix[4 * i + 0] = pPoints[i].x;
3822 pSubmatrix[4 * i + 1] =
3823 pPoints[i].x * pPoints[i].x + pPoints[i].y * pPoints[i].y + pPoints[i].z * pPoints[i].z;
3824 pSubmatrix[4 * i + 2] = pPoints[i].z;
3825 pSubmatrix[4 * i + 3] = 1;
3831 for (
int i = 0; i < 4; i++)
3833 pSubmatrix[4 * i + 0] = pPoints[i].x;
3834 pSubmatrix[4 * i + 1] = pPoints[i].y;
3835 pSubmatrix[4 * i + 2] =
3836 pPoints[i].x * pPoints[i].x + pPoints[i].y * pPoints[i].y + pPoints[i].z * pPoints[i].z;
3837 pSubmatrix[4 * i + 3] = 1;
3843 for (
int i = 0; i < 4; i++)
3845 pSubmatrix[4 * i + 0] =
3846 pPoints[i].x * pPoints[i].x + pPoints[i].y * pPoints[i].y + pPoints[i].z * pPoints[i].z;
3847 pSubmatrix[4 * i + 1] = pPoints[i].x;
3848 pSubmatrix[4 * i + 2] = pPoints[i].y;
3849 pSubmatrix[4 * i + 3] = pPoints[i].z;
3857 vCenter.x = 0.5f * fDetM12 / fDetM11;
3858 vCenter.y = -0.5f * fDetM13 / fDetM11;
3859 vCenter.z = 0.5f * fDetM14 / fDetM11;
3860 fRadius = sqrtf(vCenter.x * vCenter.x + vCenter.y * vCenter.y + vCenter.z * vCenter.z -
3871 for (
int n = 0; n < 4; n++)
3874 for (
int i = 0; i < 3; i++)
3876 for (
int j = 0, l = 0; j < 4; j++)
3880 pSubMat[3 * i + l] = pMatrix[4 * (i + 1) + j];
3886 fDet = pSubMat[0] * pSubMat[4] * pSubMat[8] + pSubMat[1] * pSubMat[5] * pSubMat[6] +
3887 pSubMat[2] * pSubMat[3] * pSubMat[7] - pSubMat[2] * pSubMat[4] * pSubMat[6] -
3888 pSubMat[1] * pSubMat[3] * pSubMat[8] - pSubMat[0] * pSubMat[5] * pSubMat[7];
3890 if ((n == 0) || (n == 2))
3892 fRet += pMatrix[n] * fDet;
3896 fRet -= pMatrix[n] * fDet;
3904 CHypothesisGeneration::RANSACSphere(
const CVec3dArray& aPointCandidates,
3905 const float fRANSACThreshold,
3906 const float fMaxSphereRadius,
3907 const int nMaxIterations,
3908 CVec3dArray& aResultPoints,
3912 const int nPointCandidates = aPointCandidates.GetSize();
3914 aResultPoints.Clear();
3916 if (nPointCandidates < 4)
3918 ARMARX_WARNING_S <<
"At least 4 point candidates must be provided for RANSAC for sphere ("
3919 << nPointCandidates <<
" provided)";
3923 int nMaxSupport = 0;
3929 const int nIterations = (nTemp > nMaxIterations) ? nMaxIterations : nTemp;
3931 #pragma omp parallel
3933 #pragma omp for schedule(static, 40)
3934 for (
int i = 0; i < nIterations; i++)
3937 srand((rand() % 17) * i + i);
3939 const int nFirstIndex = rand() % nPointCandidates;
3943 nTempIndex = rand() % nPointCandidates;
3944 }
while (nTempIndex == nFirstIndex);
3946 const int nSecondIndex = nTempIndex;
3950 nTempIndex = rand() % nPointCandidates;
3951 }
while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex);
3953 const int nThirdIndex = nTempIndex;
3957 nTempIndex = rand() % nPointCandidates;
3958 }
while (nTempIndex == nFirstIndex || nTempIndex == nSecondIndex ||
3959 nTempIndex == nThirdIndex);
3961 const Vec3d& p1 = aPointCandidates[nFirstIndex];
3962 const Vec3d& p2 = aPointCandidates[nSecondIndex];
3963 const Vec3d& p3 = aPointCandidates[nThirdIndex];
3964 const Vec3d& p4 = aPointCandidates[nTempIndex];
3983 CalculateSphere(p1, p2, p3, p4, vTempCenter, fTempRadius);
3986 if (fTempRadius == 0)
3992 if ((fTempRadius > 100) || (vTempCenter.z < 100))
4000 for (
int j = 0; j < nPointCandidates; j++)
4002 if (fabsf(Math3d::Distance(vTempCenter, aPointCandidates[j]) - fTempRadius) <=
4013 if (nSupport > nMaxSupport)
4015 #pragma omp critical
4016 if (nSupport > nMaxSupport)
4018 nMaxSupport = nSupport;
4019 Math3d::SetVec(vBestCenter, vTempCenter);
4020 fBestRadius = fTempRadius;
4026 if (nMaxSupport < 4)
4031 for (
int i = 0; i < nPointCandidates; i++)
4033 if (fabsf(Math3d::Distance(vBestCenter, aPointCandidates[i]) - fBestRadius) <=
4036 aResultPoints.AddElement(aPointCandidates[i]);
4040 Math3d::SetVec(vCenter, vBestCenter);
4041 fRadius = fBestRadius;