29 #include <Calibration/StereoCalibration.h>
30 #include <Calibration/Calibration.h>
31 #include <Image/ByteImage.h>
32 #include <Image/ImageProcessor.h>
35 #include <opencv2/opencv.hpp>
49 Math3d::Transpose(m1, mTemp1);
50 Math3d::MulMatMat(m2, mTemp1, mTemp2);
51 Math3d::GetAxisAndAngle(mTemp2, vTemp, fRotationAngle);
53 if (Math3d::ScalarProduct(vTemp, vTemp) < 0.9f)
55 Math3d::SetMat(mResult, m1);
59 Math3d::SetRotationMatAxis(mTemp1, vTemp, fWeight * fRotationAngle);
60 Math3d::MulMatMat(mTemp1, m1, mResult);
70 Math3d::AddVecVec(v1, v2, vResult);
71 Math3d::MulVecScalar(vResult, fWeight, vResult);
76 void ClusterXMeans(
const std::vector<CHypothesisPoint*>& aPoints,
const int nMinNumClusters,
const int nMaxNumClusters,
const float fBICFactor, std::vector<std::vector<CHypothesisPoint*> >& aaPointClusters)
78 std::vector<Vec3d> aPointsVec3d;
79 std::vector<std::vector<Vec3d> > aaPointClustersVec3d;
80 std::vector<std::vector<int> > aaOldIndices;
82 for (
size_t i = 0; i < aPoints.size(); i++)
84 aPointsVec3d.push_back(aPoints.at(i)->vPosition);
88 ClusterXMeans(aPointsVec3d, nMinNumClusters, nMaxNumClusters, fBICFactor, aaPointClustersVec3d, aaOldIndices);
93 aaPointClusters.clear();
95 for (
size_t i = 0; i < aaOldIndices.size(); i++)
97 std::vector<CHypothesisPoint*> aNewCluster;
98 aaPointClusters.push_back(aNewCluster);
101 for (
size_t i = 0; i < aaOldIndices.size(); i++)
103 for (
size_t j = 0; j < aaOldIndices.at(i).size(); j++)
105 aaPointClusters.at(i).push_back(aPoints.at(aaOldIndices.at(i).at(j))->GetCopy());
113 void ClusterXMeans(
const std::vector<Vec3d>& aPoints,
const int nMinNumClusters,
const int nMaxNumClusters,
const float fBICFactor, std::vector<std::vector<Vec3d> >& aaPointClusters, std::vector<std::vector<int> >& aaOldIndices)
116 cv::Mat mClusterLabels;
117 const int nNumberOfDifferentInitialisations = 7;
121 const int nNumberOfSamples = aPoints.size();
122 mSamples.create(nNumberOfSamples, 3, CV_32FC1);
124 for (
int i = 0; i < nNumberOfSamples; i++)
126 mSamples.at<
float>(i, 0) = aPoints.at(i).x;
127 mSamples.at<
float>(i, 1) = aPoints.at(i).y;
128 mSamples.at<
float>(i, 2) = aPoints.at(i).z;
131 mClusterLabels.create(nNumberOfSamples, 1, CV_32SC1);
135 double dMinBIC = FLT_MAX;
136 int nOptK = nMinNumClusters;
137 const int nMaxNumClustersSafe = (10 * nMaxNumClusters < nNumberOfSamples) ? nMaxNumClusters : nNumberOfSamples / 10;
139 #pragma omp parallel for schedule(dynamic, 1)
140 for (
int i = nMaxNumClustersSafe; i >= nMinNumClusters; i--)
143 #ifdef OLP_USE_NEW_OPENCV
144 cv::kmeans(mSamples, i, mClusterLabels, tTerminationCriteria, nNumberOfDifferentInitialisations, cv::KMEANS_RANDOM_CENTERS);
146 cv::Mat mClusterCenters;
147 cv::kmeans(mSamples, i, mClusterLabels, tTerminationCriteria, nNumberOfDifferentInitialisations, cv::KMEANS_PP_CENTERS, &mClusterCenters);
149 double dLogVar, dBIC;
150 Vec3d* pvClusterMeans =
new Vec3d[nMaxNumClusters];
151 double* pdClusterVariances =
new double[nMaxNumClusters];
152 int* pnClusterSizes =
new int[nMaxNumClusters];
155 double dMLVariance = 0;
157 for (
int j = 0; j < i; j++)
159 pvClusterMeans[j].x = 0;
160 pvClusterMeans[j].y = 0;
161 pvClusterMeans[j].z = 0;
162 pdClusterVariances[j] = 0;
163 pnClusterSizes[j] = 0;
165 for (
int l = 0; l < nNumberOfSamples; l++)
167 if (mClusterLabels.at<
int>(l, 0) == j)
169 pvClusterMeans[j].x += mSamples.at<
float>(l, 0);
170 pvClusterMeans[j].y += mSamples.at<
float>(l, 1);
171 pvClusterMeans[j].z += mSamples.at<
float>(l, 2);
176 pvClusterMeans[j].x /= (
float)pnClusterSizes[j];
177 pvClusterMeans[j].y /= (
float)pnClusterSizes[j];
178 pvClusterMeans[j].z /= (
float)pnClusterSizes[j];
180 for (
int l = 0; l < nNumberOfSamples; l++)
182 if (mClusterLabels.at<
int>(l, 0) == j)
184 pdClusterVariances[j] += (pvClusterMeans[j].x - mSamples.at<
float>(l, 0)) * (pvClusterMeans[j].x - mSamples.at<
float>(l, 0))
185 + (pvClusterMeans[j].y - mSamples.at<
float>(l, 1)) * (pvClusterMeans[j].x - mSamples.at<
float>(l, 1))
186 + (pvClusterMeans[j].z - mSamples.at<
float>(l, 2)) * (pvClusterMeans[j].x - mSamples.at<
float>(l, 2));
190 if (pnClusterSizes[j] > 1)
192 pdClusterVariances[j] /= (
float)(pnClusterSizes[j] - 1);
196 pdClusterVariances[j] = 0;
199 dMLVariance += pdClusterVariances[j];
202 const int nNumberOfFreeParameters = (i - 1) + (3 * i) + i;
204 dLogVar = log(dMLVariance / i);
205 dBIC = fBICFactor * 0.35 * dLogVar + ((double)nNumberOfFreeParameters / (
double)nNumberOfSamples) * log((
double)nNumberOfSamples);
216 delete[] pvClusterMeans;
217 delete[] pdClusterVariances;
218 delete[] pnClusterSizes;
226 #ifdef OLP_USE_NEW_OPENCV
227 double dKMeansCompactness = cv::kmeans(mSamples, nOptK, mClusterLabels, tTerminationCriteria, nNumberOfDifferentInitialisations, cv::KMEANS_RANDOM_CENTERS);
229 cv::Mat mClusterCenters;
230 double dKMeansCompactness = cv::kmeans(mSamples, nOptK, mClusterLabels, tTerminationCriteria, nNumberOfDifferentInitialisations, cv::KMEANS_PP_CENTERS, &mClusterCenters);
235 aaPointClusters.clear();
236 aaOldIndices.clear();
238 for (
int i = 0; i < nOptK; i++)
240 std::vector<Vec3d> aNewCluster;
241 aaPointClusters.push_back(aNewCluster);
242 std::vector<int> aClusterIndices;
243 aaOldIndices.push_back(aClusterIndices);
246 for (
int i = 0; i < nNumberOfSamples; i++)
248 const int nLabel = mClusterLabels.at<
int>(i, 0);
250 if ((nLabel >= 0) && (nLabel < nOptK))
252 vPoint.x = mSamples.at<
float>(i, 0);
253 vPoint.y = mSamples.at<
float>(i, 1);
254 vPoint.z = mSamples.at<
float>(i, 2);
255 aaPointClusters.at(nLabel).push_back(vPoint);
256 aaOldIndices.at(nLabel).push_back(i);
260 ARMARX_WARNING_S <<
"Invalid cluster label: " << nLabel <<
"nOptK: " << nOptK <<
", i: " << i <<
", nNumberOfSamples: " << nNumberOfSamples <<
", dKMeansCompactness: " << dKMeansCompactness;
267 aaPointClusters.clear();
268 std::vector<Vec3d> aNewCluster;
269 aaPointClusters.push_back(aNewCluster);
270 aaOldIndices.clear();
271 std::vector<int> aClusterIndices;
272 aaOldIndices.push_back(aClusterIndices);
275 for (
int i = 0; i < nNumberOfSamples; i++)
277 vPoint.x = mSamples.at<
float>(i, 0);
278 vPoint.y = mSamples.at<
float>(i, 1);
279 vPoint.z = mSamples.at<
float>(i, 2);
280 aaPointClusters.at(0).push_back(vPoint);
281 aaOldIndices.at(0).push_back(i);
289 void FilterForegroundPoints(
const std::vector<CHypothesisPoint*>& aAllPoints,
const CByteImage* pForegroundImage,
const CCalibration* calibration, std::vector<CHypothesisPoint*>& aForegroundPoints)
293 for (
size_t i = 0; i < aAllPoints.size(); i++)
295 calibration->WorldToImageCoordinates(aAllPoints.at(i)->vPosition, vImagePoint,
false);
296 const int nIndex = ((int)vImagePoint.y) *
OLP_IMG_WIDTH + (int)vImagePoint.x;
300 if (pForegroundImage->pixels[nIndex] > 0)
302 aForegroundPoints.push_back(aAllPoints.at(i)->GetCopy());
313 calibration->WorldToImageCoordinates(vPoint, vImagePoint,
false);
314 const int nIndex = ((int)vImagePoint.y) *
OLP_IMG_WIDTH + (int)vImagePoint.x;
318 return (pForegroundImage->pixels[nIndex] > 0);
345 pPoints2D =
new Vec2d[nNumPoints];
347 for (
int i = 0; i < nNumPoints; i++)
349 calibration->WorldToImageCoordinates(pHypothesis->
aVisibleConfirmedPoints.at(i)->vPosition, pPoints2D[i],
false);
355 pPoints2D =
new Vec2d[nNumPoints];
357 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
359 calibration->WorldToImageCoordinates(pHypothesis->
aNewPoints.at(i)->vPosition, pPoints2D[i],
false);
368 int nNumForegroundPoints = 0;
369 long nForegroundSum = 0;
371 for (
int i = 0; i < nNumPoints; i++)
373 int nIndex = (
OLP_IMG_WIDTH * (int)pPoints2D[i].y) + (int)pPoints2D[i].x;
377 nForegroundSum += pForegroundImage->pixels[nIndex];
379 if (pForegroundImage->pixels[nIndex] > 0)
381 nNumForegroundPoints++;
386 nNumForegroundPixels = nNumForegroundPoints;
387 fForegroundRatio = (double)nForegroundSum / ((
double)nNumPoints * 255.0);
453 float fMinX = pPoints[0].x;
454 float fMaxX = pPoints[0].x;
455 float fMinY = pPoints[0].y;
456 float fMaxY = pPoints[0].y;
457 float fSecondMinX = pPoints[0].x;
458 float fSecondMaxX = pPoints[0].x;
459 float fSecondMinY = pPoints[0].y;
460 float fSecondMaxY = pPoints[0].y;
462 for (
int i = 0; i < nNumPoints; i++)
464 if (pPoints[i].x < fMinX)
467 fMinX = pPoints[i].x;
469 else if (pPoints[i].x < fSecondMinX)
471 fSecondMinX = pPoints[i].x;
474 if (pPoints[i].x > fMaxX)
477 fMaxX = pPoints[i].x;
479 else if (pPoints[i].x > fSecondMaxX)
481 fSecondMaxX = pPoints[i].x;
484 if (pPoints[i].y < fMinY)
487 fMinY = pPoints[i].y;
489 else if (pPoints[i].y < fSecondMinY)
491 fSecondMinY = pPoints[i].y;
494 if (pPoints[i].y > fMaxY)
497 fMaxY = pPoints[i].y;
499 else if (pPoints[i].y > fSecondMaxY)
501 fSecondMaxY = pPoints[i].y;
506 Vec2d* pRotatedPoints =
new Vec2d[nNumPoints];
508 for (
int i = 0; i < nNumPoints; i++)
510 pRotatedPoints[i].x = pPoints[i].x - pPoints[i].y;
511 pRotatedPoints[i].y = pPoints[i].x + pPoints[i].y;
514 float fMinXr = pRotatedPoints[0].x;
515 float fMaxXr = pRotatedPoints[0].x;
516 float fMinYr = pRotatedPoints[0].y;
517 float fMaxYr = pRotatedPoints[0].y;
518 float fSecondMinXr = pRotatedPoints[0].x;
519 float fSecondMaxXr = pRotatedPoints[0].x;
520 float fSecondMinYr = pRotatedPoints[0].y;
521 float fSecondMaxYr = pRotatedPoints[0].y;
523 for (
int i = 0; i < nNumPoints; i++)
525 if (pRotatedPoints[i].x < fMinXr)
527 fSecondMinXr = fMinXr;
528 fMinXr = pRotatedPoints[i].x;
530 else if (pRotatedPoints[i].x < fSecondMinXr)
532 fSecondMinXr = pRotatedPoints[i].x;
535 if (pRotatedPoints[i].x > fMaxXr)
537 fSecondMaxXr = fMaxXr;
538 fMaxXr = pRotatedPoints[i].x;
540 else if (pRotatedPoints[i].x > fSecondMaxXr)
542 fSecondMaxXr = pRotatedPoints[i].x;
545 if (pRotatedPoints[i].y < fMinYr)
547 fSecondMinYr = fMinYr;
548 fMinYr = pRotatedPoints[i].y;
550 else if (pRotatedPoints[i].y < fSecondMinYr)
552 fSecondMinYr = pRotatedPoints[i].y;
555 if (pRotatedPoints[i].y > fMaxYr)
557 fSecondMaxYr = fMaxYr;
558 fMaxYr = pRotatedPoints[i].y;
560 else if (pRotatedPoints[i].y > fSecondMaxYr)
562 fSecondMaxYr = pRotatedPoints[i].y;
566 const float fSqrt2Fact = 0.5f * sqrtf(2.0f);
567 fMinXr *= fSqrt2Fact;
568 fMaxXr *= fSqrt2Fact;
569 fMinYr *= fSqrt2Fact;
570 fMaxYr *= fSqrt2Fact;
571 fSecondMinXr *= fSqrt2Fact;
572 fSecondMaxXr *= fSqrt2Fact;
573 fSecondMinYr *= fSqrt2Fact;
574 fSecondMaxYr *= fSqrt2Fact;
576 if (bUseSecondMaxPoints)
579 if ((fSecondMaxX - fSecondMinX) * (fSecondMaxY - fSecondMinY) < (fSecondMaxXr - fSecondMinXr) * (fSecondMaxYr - fSecondMinYr))
582 Math2d::SetVec(p1, fSecondMinX, fSecondMinY);
583 Math2d::SetVec(p2, fSecondMaxX, fSecondMinY);
584 Math2d::SetVec(p3, fSecondMaxX, fSecondMaxY);
585 Math2d::SetVec(p4, fSecondMinX, fSecondMaxY);
590 Math2d::SetVec(p1, fSqrt2Fact * (fSecondMinXr + fSecondMinYr), fSqrt2Fact * (-fSecondMinXr + fSecondMinYr));
591 Math2d::SetVec(p2, fSqrt2Fact * (fSecondMaxXr + fSecondMinYr), fSqrt2Fact * (-fSecondMaxXr + fSecondMinYr));
592 Math2d::SetVec(p3, fSqrt2Fact * (fSecondMaxXr + fSecondMaxYr), fSqrt2Fact * (-fSecondMaxXr + fSecondMaxYr));
593 Math2d::SetVec(p4, fSqrt2Fact * (fSecondMinXr + fSecondMaxYr), fSqrt2Fact * (-fSecondMinXr + fSecondMaxYr));
599 if ((fMaxX - fMinX) * (fMaxY - fMinY) < (fMaxXr - fMinXr) * (fMaxYr - fMinYr))
602 Math2d::SetVec(p1, fMinX, fMinY);
603 Math2d::SetVec(p2, fMaxX, fMinY);
604 Math2d::SetVec(p3, fMaxX, fMaxY);
605 Math2d::SetVec(p4, fMinX, fMaxY);
610 Math2d::SetVec(p1, fSqrt2Fact * (fMinXr + fMinYr), fSqrt2Fact * (-fMinXr + fMinYr));
611 Math2d::SetVec(p2, fSqrt2Fact * (fMaxXr + fMinYr), fSqrt2Fact * (-fMaxXr + fMinYr));
612 Math2d::SetVec(p3, fSqrt2Fact * (fMaxXr + fMaxYr), fSqrt2Fact * (-fMaxXr + fMaxYr));
613 Math2d::SetVec(p4, fSqrt2Fact * (fMinXr + fMaxYr), fSqrt2Fact * (-fMinXr + fMaxYr));
617 delete[] pRotatedPoints;
623 int nStartY = (int)vMiddleMin.y;
624 int nEndY = (
int)vMiddleMax.y;
625 int nMiddleY1, nMiddleY2;
626 float fDeltaLeft1, fDeltaLeft2, fDeltaLeft3, fDeltaRight1, fDeltaRight2, fDeltaRight3;
631 if (vMinMiddle.y < vMaxMiddle.y)
633 nMiddleY1 = (int)vMinMiddle.y;
634 nMiddleY2 = (
int)vMaxMiddle.y;
635 fDeltaLeft1 = (vMinMiddle.x - vMiddleMin.x) / (vMinMiddle.y - vMiddleMin.y);
636 fDeltaLeft2 = (vMiddleMax.x - vMinMiddle.x) / (vMiddleMax.y - vMinMiddle.y);
637 fDeltaLeft3 = fDeltaLeft2;
638 fDeltaRight1 = (vMaxMiddle.x - vMiddleMin.x) / (vMaxMiddle.y - vMiddleMin.y);
639 fDeltaRight2 = fDeltaRight1;
640 fDeltaRight3 = (vMiddleMax.x - vMaxMiddle.x) / (vMiddleMax.y - vMaxMiddle.y);
644 nMiddleY1 = (int)vMaxMiddle.y;
645 nMiddleY2 = (
int)vMinMiddle.y;
646 fDeltaLeft1 = (vMinMiddle.x - vMiddleMin.x) / (vMinMiddle.y - vMiddleMin.y);
647 fDeltaLeft2 = fDeltaLeft1;
648 fDeltaLeft3 = (vMiddleMax.x - vMinMiddle.x) / (vMiddleMax.y - vMinMiddle.y);
649 fDeltaRight1 = (vMaxMiddle.x - vMiddleMin.x) / (vMaxMiddle.y - vMiddleMin.y);
650 fDeltaRight2 = (vMiddleMax.x - vMaxMiddle.x) / (vMiddleMax.y - vMaxMiddle.y);
651 fDeltaRight3 = fDeltaRight2;
654 float fLeft = vMiddleMin.x;
655 float fRight = vMiddleMin.x;
658 for (
int i = nStartY; i < nMiddleY1; i++)
660 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
665 fLeft += fDeltaLeft1;
666 fRight += fDeltaRight1;
670 for (
int i = nMiddleY1; i < nMiddleY2; i++)
672 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
677 fLeft += fDeltaLeft2;
678 fRight += fDeltaRight2;
682 for (
int i = nMiddleY2; i < nEndY; i++)
684 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
689 fLeft += fDeltaLeft3;
690 fRight += fDeltaRight3;
701 std::vector<Vec3d> aPoints3d;
703 for (
size_t i = 0; i < pHypothesisPoints.size(); i++)
705 aPoints3d.push_back(pHypothesisPoints.at(i)->vPosition);
721 const int nNumPoints = aPoints.size();
725 const float fNumPointsInv = 1.0f / (
float)nNumPoints;
728 for (
int i = 0; i < nNumPoints; i++)
730 vMean.x += aPoints.at(i).x;
731 vMean.y += aPoints.at(i).y;
732 vMean.z += aPoints.at(i).z;
735 vMean.x *= fNumPointsInv;
736 vMean.y *= fNumPointsInv;
737 vMean.z *= fNumPointsInv;
740 for (
int i = 0; i < nNumPoints; i++)
742 fVariance += (vMean.x - aPoints.at(i).x) * (vMean.x - aPoints.at(i).x)
743 + (vMean.y - aPoints.at(i).y) * (vMean.y - aPoints.at(i).y)
744 + (vMean.z - aPoints.at(i).z) * (vMean.z - aPoints.at(i).z);
747 fVariance *= fNumPointsInv;
759 void RemoveOutliers(std::vector<Vec3d>& aPoints,
const float fStdDevFactor, std::vector<int>* pOldIndices)
761 if (aPoints.size() < 9)
763 if (pOldIndices != NULL)
765 pOldIndices->clear();
767 for (
size_t i = 0; i < aPoints.size(); i++)
769 pOldIndices->push_back(i);
779 const float fThreshold2 = fStdDevFactor * fStdDevFactor * fVariance;
781 ARMARX_VERBOSE_S <<
"Mean: (" << vMean.x <<
", " << vMean.y <<
", " << vMean.z <<
"), std dev: " << sqrtf(fVariance);
786 if (pOldIndices != NULL)
788 pOldIndices->clear();
790 for (
size_t i = 0; i < aPoints.size(); i++)
792 pOldIndices->push_back(i);
795 for (
size_t i = 0; i < aPoints.size(); i++)
797 fDist2 = (vMean.x - aPoints.at(i).x) * (vMean.x - aPoints.at(i).x)
798 + (vMean.y - aPoints.at(i).y) * (vMean.y - aPoints.at(i).y)
799 + (vMean.z - aPoints.at(i).z) * (vMean.z - aPoints.at(i).z);
801 if (fDist2 > fThreshold2)
803 Math3d::SetVec(aPoints.at(i), aPoints.at(aPoints.size() - 1));
804 pOldIndices->at(i) = pOldIndices->at(aPoints.size() - 1);
806 pOldIndices->pop_back();
813 for (
size_t i = 0; i < aPoints.size(); i++)
815 fDist2 = (vMean.x - aPoints.at(i).x) * (vMean.x - aPoints.at(i).x)
816 + (vMean.y - aPoints.at(i).y) * (vMean.y - aPoints.at(i).y)
817 + (vMean.z - aPoints.at(i).z) * (vMean.z - aPoints.at(i).z);
819 if (fDist2 > fThreshold2)
821 aPoints[i] = aPoints[aPoints.size() - 1];
831 void RemoveOutliers(std::vector<CHypothesisPoint*>& aPoints,
const float fStdDevFactor)
833 std::vector<Vec3d> aPointsVec3d;
834 std::vector<int> pOldIndices;
836 for (
size_t i = 0; i < aPoints.size(); i++)
838 aPointsVec3d.push_back(aPoints.at(i)->vPosition);
843 ARMARX_VERBOSE_S <<
"RemoveOutliers: " << pOldIndices.size() <<
" of " << aPoints.size() <<
" points left\n";
847 std::vector<CHypothesisPoint*> aPointsCopy;
848 std::vector<bool> aPointStillIncluded;
850 for (
size_t i = 0; i < aPoints.size(); i++)
852 aPointsCopy.push_back(aPoints.at(i));
853 aPointStillIncluded.push_back(
false);
856 for (
size_t i = 0; i < pOldIndices.size(); i++)
858 aPointStillIncluded.at(pOldIndices.at(i)) =
true;
863 for (
size_t i = 0; i < aPointsCopy.size(); i++)
865 if (aPointStillIncluded.at(i))
867 aPoints.push_back(aPointsCopy.at(i));
871 delete aPointsCopy.at(i);
880 float fMinDist = FLT_MAX;
885 fDist = Math3d::Distance(vPoint, pHypothesis->
aConfirmedPoints.at(i)->vPosition);
887 if (fDist < fMinDist)
895 fDist = Math3d::Distance(vPoint, pHypothesis->
aDoubtablePoints.at(i)->vPosition);
897 if (fDist < fMinDist)
908 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBA>);
917 cloud->points[i].x = p->
vPosition.x - vCenter.x;
918 cloud->points[i].y = p->
vPosition.y - vCenter.y;
919 cloud->points[i].z = p->
vPosition.z - vCenter.z;
923 cloud->points[i].a = 1;
931 static const int division_table[] =
933 0, 1048576, 524288, 349525, 262144, 209715, 174762, 149796,
934 131072, 116508, 104857, 95325, 87381, 80659, 74898, 69905,
935 65536, 61680, 58254, 55188, 52428, 49932, 47662, 45590,
936 43690, 41943, 40329, 38836, 37449, 36157, 34952, 33825,
937 32768, 31775, 30840, 29959, 29127, 28339, 27594, 26886,
938 26214, 25575, 24966, 24385, 23831, 23301, 22795, 22310,
939 21845, 21399, 20971, 20560, 20164, 19784, 19418, 19065,
940 18724, 18396, 18078, 17772, 17476, 17189, 16912, 16644,
941 16384, 16131, 15887, 15650, 15420, 15196, 14979, 14768,
942 14563, 14364, 14169, 13981, 13797, 13617, 13443, 13273,
943 13107, 12945, 12787, 12633, 12483, 12336, 12192, 12052,
944 11915, 11781, 11650, 11522, 11397, 11275, 11155, 11037,
945 10922, 10810, 10699, 10591, 10485, 10381, 10280, 10180,
946 10082, 9986, 9892, 9799, 9709, 9619, 9532, 9446,
947 9362, 9279, 9198, 9118, 9039, 8962, 8886, 8811,
948 8738, 8665, 8594, 8525, 8456, 8388, 8322, 8256,
949 8192, 8128, 8065, 8004, 7943, 7884, 7825, 7767,
950 7710, 7653, 7598, 7543, 7489, 7436, 7384, 7332,
951 7281, 7231, 7182, 7133, 7084, 7037, 6990, 6944,
952 6898, 6853, 6808, 6765, 6721, 6678, 6636, 6594,
953 6553, 6512, 6472, 6432, 6393, 6355, 6316, 6278,
954 6241, 6204, 6168, 6132, 6096, 6061, 6026, 5991,
955 5957, 5924, 5890, 5857, 5825, 5793, 5761, 5729,
956 5698, 5667, 5637, 5607, 5577, 5548, 5518, 5489,
957 5461, 5433, 5405, 5377, 5349, 5322, 5295, 5269,
958 5242, 5216, 5190, 5165, 5140, 5115, 5090, 5065,
959 5041, 5017, 4993, 4969, 4946, 4922, 4899, 4877,
960 4854, 4832, 4809, 4788, 4766, 4744, 4723, 4702,
961 4681, 4660, 4639, 4619, 4599, 4578, 4559, 4539,
962 4519, 4500, 4481, 4462, 4443, 4424, 4405, 4387,
963 4369, 4350, 4332, 4315, 4297, 4279, 4262, 4245,
964 4228, 4211, 4194, 4177, 4161, 4144, 4128, 4112
969 void ConvertRGB2HSV(
const unsigned char r,
const unsigned char g,
const unsigned char b,
unsigned char& h,
unsigned char&
s,
unsigned char&
v)
972 const int max = MY_MAX(MY_MAX(r, g), b);
973 const int min = MY_MIN(MY_MIN(r, g), b);
974 const int delta =
max -
min;
981 hInt = g > b ? 180 + ((30 * (g - b) * division_table[delta]) >> 20) : 180 - ((30 * (b - g) * division_table[delta]) >> 20);
985 hInt = b > r ? 60 + ((30 * (b - r) * division_table[delta]) >> 20) : 60 - ((30 * (r - b) * division_table[delta]) >> 20);
989 hInt = r > g ? 120 + ((30 * (r - g) * division_table[delta]) >> 20) : 120 - ((30 * (g - r) * division_table[delta]) >> 20);
992 h = (hInt >= 180) ? hInt - 180 : hInt;
995 s = (255 * delta * division_table[
max]) >> 20;
1007 ARMARX_WARNING_S <<
"CreateHueHistogram: wrong hypothesis type (not RGBD or SingleColored)!";
1015 unsigned char r, g, b, h,
s,
v;
1027 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1028 const int nHistogramIndexHue = h / nBucketSize;
1029 aHueHistogram.at(nHistogramIndexHue) += fWeight;
1030 const int nHistogramIndexSaturation =
s / nBucketSize;
1031 aSaturationHistogram.at(nHistogramIndexSaturation) += 1;
1035 const float fCandidatePointWeightFactor = 0.01f;
1037 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1046 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1047 const int nHistogramIndexHue = h / nBucketSize;
1048 aHueHistogram.at(nHistogramIndexHue) += fCandidatePointWeightFactor * fWeight;
1049 const int nHistogramIndexSaturation =
s / nBucketSize;
1050 aSaturationHistogram.at(nHistogramIndexSaturation) += fCandidatePointWeightFactor;
1062 std::vector<float>& aHueHistogram, std::vector<float>& aSaturationHistogram)
1071 for (
int i = nMinY; i < nMaxY; i++)
1073 for (
int j = nMinX; j < nMaxX; j++)
1078 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1079 const int nHistogramIndexHue = h / nBucketSize;
1080 aHueHistogram.at(nHistogramIndexHue) += fWeight;
1081 const int nHistogramIndexSaturation =
s / nBucketSize;
1082 aSaturationHistogram.at(nHistogramIndexSaturation) += 1;
1097 std::vector<float> aHistogramTemp;
1098 const int nHistogramSize = aHistogram.size();
1099 aHistogramTemp.resize(nHistogramSize);
1101 for (
int i = 0; i < nHistogramSize; i++)
1103 aHistogramTemp.at(i) = aHistogram.at(i);
1107 for (
int i = 0; i < nHistogramSize; i++)
1114 aHistogram.at(i) = 0.7f * aHistogramTemp.at(i)
1115 + 0.15f * aHistogramTemp.at((i - 1 + nHistogramSize) % nHistogramSize)
1116 + 0.15f * aHistogramTemp.at((i + 1) % nHistogramSize);
1126 for (
size_t i = 0; i < aHistogram.size(); i++)
1128 fSum += aHistogram.at(i);
1131 const float fInverseSum = 1.0f / fSum;
1133 for (
size_t i = 0; i < aHistogram.size(); i++)
1135 aHistogram.at(i) *= fInverseSum;
1144 const int n = (int)aHistogram1.size();
1148 for (
int i = 0; i < n; i++)
1150 fDist += fabsf(aHistogram1.at(i) - aHistogram2.at(i));
1159 const int n = (int)aHistogram1.size();
1163 for (
int i = 0; i < n; i++)
1165 fDist += (aHistogram1.at(i) - aHistogram2.at(i)) * (aHistogram1.at(i) - aHistogram2.at(i));
1168 return sqrtf(fDist);
1174 const int n = (int)aHistogram1.size();
1178 for (
int i = 0; i < n; i++)
1180 fDist += (aHistogram1.at(i) - aHistogram2.at(i)) * (aHistogram1.at(i) - aHistogram2.at(i)) / (aHistogram1.at(i) + aHistogram2.at(i) + 0.00001f);
1183 return sqrtf(fDist);
1189 void DrawCross(CByteImage* pGreyImage,
int x,
int y,
int nBrightness)
1193 for (
int j = -3; j <= 3; j++)
1195 pGreyImage->pixels[(y + j)*
OLP_IMG_WIDTH + x] = nBrightness;
1196 pGreyImage->pixels[y *
OLP_IMG_WIDTH + x + j] = nBrightness;
1202 void DrawCross(CByteImage* pColorImage,
int x,
int y,
int r,
int g,
int b)
1206 for (
int j = -3; j <= 3; j++)
1209 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x) + 1] = g;
1210 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x) + 2] = b;
1213 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 1] = g;
1214 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 2] = b;
1220 void DrawFatCross(CByteImage* pColorImage,
int x,
int y,
int r,
int g,
int b)
1224 for (
int j = -3; j <= 4; j++)
1227 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x) + 1] = g;
1228 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x) + 2] = b;
1230 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x + 1)] = r;
1231 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x + 1) + 1] = g;
1232 pColorImage->pixels[3 * ((y + j)*
OLP_IMG_WIDTH + x + 1) + 2] = b;
1236 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 1] = g;
1237 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 2] = b;
1239 pColorImage->pixels[3 * ((y + 1)*
OLP_IMG_WIDTH + x + j)] = r;
1240 pColorImage->pixels[3 * ((y + 1)*
OLP_IMG_WIDTH + x + j) + 1] = g;
1241 pColorImage->pixels[3 * ((y + 1)*
OLP_IMG_WIDTH + x + j) + 2] = b;
1251 if (pForegroundImage == NULL)
1255 else if (pForegroundImage->width !=
OLP_IMG_WIDTH || pForegroundImage->height !=
OLP_IMG_HEIGHT || pForegroundImage->type != CByteImage::eGrayScale)
1257 delete pForegroundImage;
1264 pForegroundImage->pixels[i] = 0;
1273 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1277 pForegroundImage->pixels[nIndex] = 255;
1283 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1286 calibration->WorldToImageCoordinates(pHypothesis->
aNewPoints.at(i)->vPosition, vPoint2D,
false);
1287 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1291 pForegroundImage->pixels[nIndex] = 255;
1302 ImageProcessor::Dilate(pForegroundImage, pTempImage);
1303 ImageProcessor::Dilate(pTempImage, pForegroundImage);
1308 ImageProcessor::Erode(pForegroundImage, pTempImage);
1309 ImageProcessor::Erode(pTempImage, pForegroundImage);
1321 if (pProbabilityImage == NULL)
1330 pProbabilityImage->pixels[i] = 0;
1334 const int probValueConfirmedPoints = 255;
1335 const int probValueCandidatePoints = 51;
1338 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1340 calibration->WorldToImageCoordinates(pHypothesis->
aNewPoints.at(i)->vPosition, vPoint2D,
false);
1341 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1345 pProbabilityImage->pixels[nIndex] = probValueCandidatePoints;
1352 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1356 pProbabilityImage->pixels[nIndex] = probValueConfirmedPoints;
1360 CByteImage* tempImage =
new CByteImage(pProbabilityImage);
1362 const int nKernelSize = 4 * sigma + 1;
1363 ImageProcessor::GaussianSmooth(pProbabilityImage, tempImage, sigma * sigma, nKernelSize);
1364 ImageProcessor::HistogramStretching(tempImage, pProbabilityImage, 0.0f, 1.0f);
1365 ImageProcessor::GaussianSmooth(pProbabilityImage, tempImage, sigma * sigma, nKernelSize);
1366 ImageProcessor::HistogramStretching(tempImage, pProbabilityImage, 0.0f, 1.0f);
1380 for (
int i = 0; i < nNumDigits; i++)
1382 int nDecimalDivisor = 1;
1384 for (
int j = 0; j < i; j++)
1386 nDecimalDivisor *= 10;
1389 sFileName.at(sFileName.length() - (5 + i)) =
'0' + (nNumber / nDecimalDivisor) % 10;
1402 int nIntersectingPoints = 0;
1403 int nUnionPoints = 0;
1407 nIntersectingPoints += (pHypothesisRegionImage1->pixels[i] * pHypothesisRegionImage2->pixels[i] != 0);
1408 nUnionPoints += (pHypothesisRegionImage1->pixels[i] + pHypothesisRegionImage2->pixels[i] != 0);
1411 delete pHypothesisRegionImage1;
1412 delete pHypothesisRegionImage2;
1414 if (nUnionPoints > 0)
1416 return (
float)nIntersectingPoints / (
float)nUnionPoints;
1433 for (
int i = 0; 2 * i < nSize; i++)
1440 ImageProcessor::Zero(pImage);
1446 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1457 CByteImage* pTempImg =
new CByteImage(pImage);
1463 CByteImage* pSegmentationProbability = NULL;
1466 sFileName +=
"SegmProb.bmp";
1467 pSegmentationProbability->SaveToFile(sFileName.c_str());
1471 if (pSegmentationProbability->pixels[i] < 1 + nNumFusedHypotheses / 3)
1473 pImage->pixels[3 * i] *= 0.3;
1474 pImage->pixels[3 * i + 1] *= 0.3;
1475 pImage->pixels[3 * i + 2] *= 0.3;
1481 void FillHolesRGB(
const CByteImage* pInputImage, CByteImage* pOutputImage,
const int nRadius)
1485 pOutputImage->pixels[i] = pInputImage->pixels[i];
1494 if (pInputImage->pixels[3 * nIndex] + pInputImage->pixels[3 * nIndex + 1] + pInputImage->pixels[3 * nIndex + 2] == 0)
1496 int r, g, b, nNumPixels;
1497 r = g = b = nNumPixels = 0;
1499 for (
int l = -nRadius; l <= nRadius; l++)
1501 for (
int k = -nRadius; k <= nRadius; k++)
1505 if (pInputImage->pixels[nTempIndex] + pInputImage->pixels[nTempIndex + 1] + pInputImage->pixels[nTempIndex + 2] != 0)
1507 r += pInputImage->pixels[nTempIndex];
1508 g += pInputImage->pixels[nTempIndex + 1];
1509 b += pInputImage->pixels[nTempIndex + 2];
1517 pOutputImage->pixels[3 * nIndex] = r / nNumPixels;
1518 pOutputImage->pixels[3 * nIndex + 1] = g / nNumPixels;
1519 pOutputImage->pixels[3 * nIndex + 2] = b / nNumPixels;
1527 void FillHolesGray(
const CByteImage* pInputImage, CByteImage* pOutputImage,
const int nRadius)
1531 pOutputImage->pixels[i] = pInputImage->pixels[i];
1540 if (pInputImage->pixels[nIndex] == 0)
1545 for (
int l = -nRadius; l <= nRadius; l++)
1547 for (
int k = -nRadius; k <= nRadius; k++)
1551 if (pInputImage->pixels[nTempIndex] != 0)
1553 nSum += pInputImage->pixels[nTempIndex];
1561 pOutputImage->pixels[nIndex] = nSum / nNumPixels;
1570 void SortByPositionZ(std::vector<CHypothesisPoint*>& aHypothesisPoints,
const int nLeftLimit,
const int nRightLimit)
1572 if (aHypothesisPoints.size() <= 1 || nRightLimit - nLeftLimit <= 0)
1577 float fPivot = aHypothesisPoints.at((nLeftLimit + nRightLimit) / 2)->vPosition.z;
1579 int nLeftIndex = nLeftLimit;
1580 int nRightIndex = nRightLimit;
1582 while (nLeftIndex <= nRightIndex)
1584 while (aHypothesisPoints.at(nLeftIndex)->vPosition.z < fPivot && (nLeftIndex <= nRightIndex))
1589 while (aHypothesisPoints.at(nRightIndex)->vPosition.z > fPivot && (nLeftIndex <= nRightIndex))
1594 if (nLeftIndex <= nRightIndex)
1597 aHypothesisPoints.at(nLeftIndex) = aHypothesisPoints.at(nRightIndex);
1598 aHypothesisPoints.at(nRightIndex) = pTemp;
1618 CByteImage* pTempImage =
new CByteImage(pImageGray);
1620 ImageProcessor::GaussianSmooth5x5(pImageGray, pTempImage);
1621 ImageProcessor::CalculateGradientImageSobel(pTempImage, pEdgeImage);
1625 pEdgesFromImage[i] = pEdgeImage->pixels[i];
1629 sScreenshotFile +=
"edge-img.bmp";
1630 pEdgeImage->SaveToFile(sScreenshotFile.c_str());
1636 int nNumZeroDisparityPixels = 0;
1640 if (pDisparity->pixels[i] == 0)
1642 nNumZeroDisparityPixels++;
1647 ImageProcessor::HistogramStretching(pDisparity, pTempImage, fZeroDisparityPixelRatio + 0.1f, 0.9f);
1649 sScreenshotFile +=
"disp.bmp";
1650 pTempImage->SaveToFile(sScreenshotFile.c_str());
1652 const float fSigma = 7;
1653 const int nKernelSize = 4 * fSigma + 1;
1654 ImageProcessor::GaussianSmooth(pTempImage, pEdgeImage, fSigma * fSigma, nKernelSize);
1656 ImageProcessor::CalculateGradientImageSobel(pEdgeImage, pTempImage);
1660 pEdgesFromDisparity[i] = pTempImage->pixels[i];
1664 sScreenshotFile +=
"edge-disp.bmp";
1665 pTempImage->SaveToFile(sScreenshotFile.c_str());
1673 fValue = sqrtf(pEdgesFromImage[i] * pEdgesFromDisparity[i] * sqrtf(pEdgesFromDisparity[i]));
1674 pEdgeImage->pixels[i] = (fValue > 255) ? 255 : fValue;
1678 sScreenshotFile +=
"edge-full.bmp";
1679 pEdgeImage->SaveToFile(sScreenshotFile.c_str());