30 #include <Calibration/Calibration.h>
31 #include <Calibration/StereoCalibration.h>
32 #include <Image/ByteImage.h>
33 #include <Image/ImageProcessor.h>
36 #include <opencv2/opencv.hpp>
48 Math3d::Transpose(m1, mTemp1);
49 Math3d::MulMatMat(m2, mTemp1, mTemp2);
50 Math3d::GetAxisAndAngle(mTemp2, vTemp, fRotationAngle);
52 if (Math3d::ScalarProduct(vTemp, vTemp) < 0.9f)
54 Math3d::SetMat(mResult, m1);
58 Math3d::SetRotationMatAxis(mTemp1, vTemp, fWeight * fRotationAngle);
59 Math3d::MulMatMat(mTemp1, m1, mResult);
73 Math3d::AddVecVec(v1, v2, vResult);
74 Math3d::MulVecScalar(vResult, fWeight, vResult);
79 const int nMinNumClusters,
80 const int nMaxNumClusters,
81 const float fBICFactor,
82 std::vector<std::vector<CHypothesisPoint*>>& aaPointClusters)
84 std::vector<Vec3d> aPointsVec3d;
85 std::vector<std::vector<Vec3d>> aaPointClustersVec3d;
86 std::vector<std::vector<int>> aaOldIndices;
88 for (
size_t i = 0; i < aPoints.size(); i++)
90 aPointsVec3d.push_back(aPoints.at(i)->vPosition);
104 aaPointClusters.clear();
106 for (
size_t i = 0; i < aaOldIndices.size(); i++)
108 std::vector<CHypothesisPoint*> aNewCluster;
109 aaPointClusters.push_back(aNewCluster);
112 for (
size_t i = 0; i < aaOldIndices.size(); i++)
114 for (
size_t j = 0; j < aaOldIndices.at(i).size(); j++)
116 aaPointClusters.at(i).push_back(aPoints.at(aaOldIndices.at(i).at(j))->GetCopy());
123 const int nMinNumClusters,
124 const int nMaxNumClusters,
125 const float fBICFactor,
126 std::vector<std::vector<Vec3d>>& aaPointClusters,
127 std::vector<std::vector<int>>& aaOldIndices)
130 cv::Mat mClusterLabels;
131 const int nNumberOfDifferentInitialisations = 7;
132 cv::TermCriteria tTerminationCriteria(
136 const int nNumberOfSamples = aPoints.size();
137 mSamples.create(nNumberOfSamples, 3, CV_32FC1);
139 for (
int i = 0; i < nNumberOfSamples; i++)
141 mSamples.at<
float>(i, 0) = aPoints.at(i).x;
142 mSamples.at<
float>(i, 1) = aPoints.at(i).y;
143 mSamples.at<
float>(i, 2) = aPoints.at(i).z;
146 mClusterLabels.create(nNumberOfSamples, 1, CV_32SC1);
150 double dMinBIC = FLT_MAX;
151 int nOptK = nMinNumClusters;
152 const int nMaxNumClustersSafe =
153 (10 * nMaxNumClusters < nNumberOfSamples) ? nMaxNumClusters : nNumberOfSamples / 10;
155 #pragma omp parallel for schedule(dynamic, 1)
156 for (
int i = nMaxNumClustersSafe; i >= nMinNumClusters; i--)
159 #ifdef OLP_USE_NEW_OPENCV
163 tTerminationCriteria,
164 nNumberOfDifferentInitialisations,
165 cv::KMEANS_RANDOM_CENTERS);
167 cv::Mat mClusterCenters;
171 tTerminationCriteria,
172 nNumberOfDifferentInitialisations,
173 cv::KMEANS_PP_CENTERS,
176 double dLogVar, dBIC;
177 Vec3d* pvClusterMeans =
new Vec3d[nMaxNumClusters];
178 double* pdClusterVariances =
new double[nMaxNumClusters];
179 int* pnClusterSizes =
new int[nMaxNumClusters];
182 double dMLVariance = 0;
184 for (
int j = 0; j < i; j++)
186 pvClusterMeans[j].x = 0;
187 pvClusterMeans[j].y = 0;
188 pvClusterMeans[j].z = 0;
189 pdClusterVariances[j] = 0;
190 pnClusterSizes[j] = 0;
192 for (
int l = 0; l < nNumberOfSamples; l++)
194 if (mClusterLabels.at<
int>(l, 0) == j)
196 pvClusterMeans[j].x += mSamples.at<
float>(l, 0);
197 pvClusterMeans[j].y += mSamples.at<
float>(l, 1);
198 pvClusterMeans[j].z += mSamples.at<
float>(l, 2);
203 pvClusterMeans[j].x /= (
float)pnClusterSizes[j];
204 pvClusterMeans[j].y /= (
float)pnClusterSizes[j];
205 pvClusterMeans[j].z /= (
float)pnClusterSizes[j];
207 for (
int l = 0; l < nNumberOfSamples; l++)
209 if (mClusterLabels.at<
int>(l, 0) == j)
211 pdClusterVariances[j] +=
212 (pvClusterMeans[j].x - mSamples.at<
float>(l, 0)) *
213 (pvClusterMeans[j].x - mSamples.at<
float>(l, 0)) +
214 (pvClusterMeans[j].y - mSamples.at<
float>(l, 1)) *
215 (pvClusterMeans[j].x - mSamples.at<
float>(l, 1)) +
216 (pvClusterMeans[j].z - mSamples.at<
float>(l, 2)) *
217 (pvClusterMeans[j].x - mSamples.at<
float>(l, 2));
221 if (pnClusterSizes[j] > 1)
223 pdClusterVariances[j] /= (
float)(pnClusterSizes[j] - 1);
227 pdClusterVariances[j] = 0;
230 dMLVariance += pdClusterVariances[j];
233 const int nNumberOfFreeParameters = (i - 1) + (3 * i) + i;
235 dLogVar = log(dMLVariance / i);
236 dBIC = fBICFactor * 0.35 * dLogVar +
237 ((double)nNumberOfFreeParameters / (
double)nNumberOfSamples) *
238 log((
double)nNumberOfSamples);
249 delete[] pvClusterMeans;
250 delete[] pdClusterVariances;
251 delete[] pnClusterSizes;
259 #ifdef OLP_USE_NEW_OPENCV
260 double dKMeansCompactness = cv::kmeans(mSamples,
263 tTerminationCriteria,
264 nNumberOfDifferentInitialisations,
265 cv::KMEANS_RANDOM_CENTERS);
267 cv::Mat mClusterCenters;
268 double dKMeansCompactness = cv::kmeans(mSamples,
271 tTerminationCriteria,
272 nNumberOfDifferentInitialisations,
273 cv::KMEANS_PP_CENTERS,
279 aaPointClusters.clear();
280 aaOldIndices.clear();
282 for (
int i = 0; i < nOptK; i++)
284 std::vector<Vec3d> aNewCluster;
285 aaPointClusters.push_back(aNewCluster);
286 std::vector<int> aClusterIndices;
287 aaOldIndices.push_back(aClusterIndices);
290 for (
int i = 0; i < nNumberOfSamples; i++)
292 const int nLabel = mClusterLabels.at<
int>(i, 0);
294 if ((nLabel >= 0) && (nLabel < nOptK))
296 vPoint.x = mSamples.at<
float>(i, 0);
297 vPoint.y = mSamples.at<
float>(i, 1);
298 vPoint.z = mSamples.at<
float>(i, 2);
299 aaPointClusters.at(nLabel).push_back(vPoint);
300 aaOldIndices.at(nLabel).push_back(i);
304 ARMARX_WARNING_S <<
"Invalid cluster label: " << nLabel <<
"nOptK: " << nOptK
305 <<
", i: " << i <<
", nNumberOfSamples: " << nNumberOfSamples
306 <<
", dKMeansCompactness: " << dKMeansCompactness;
313 aaPointClusters.clear();
314 std::vector<Vec3d> aNewCluster;
315 aaPointClusters.push_back(aNewCluster);
316 aaOldIndices.clear();
317 std::vector<int> aClusterIndices;
318 aaOldIndices.push_back(aClusterIndices);
321 for (
int i = 0; i < nNumberOfSamples; i++)
323 vPoint.x = mSamples.at<
float>(i, 0);
324 vPoint.y = mSamples.at<
float>(i, 1);
325 vPoint.z = mSamples.at<
float>(i, 2);
326 aaPointClusters.at(0).push_back(vPoint);
327 aaOldIndices.at(0).push_back(i);
334 const CByteImage* pForegroundImage,
335 const CCalibration* calibration,
336 std::vector<CHypothesisPoint*>& aForegroundPoints)
340 for (
size_t i = 0; i < aAllPoints.size(); i++)
342 calibration->WorldToImageCoordinates(aAllPoints.at(i)->vPosition, vImagePoint,
false);
343 const int nIndex = ((int)vImagePoint.y) *
OLP_IMG_WIDTH + (int)vImagePoint.x;
347 if (pForegroundImage->pixels[nIndex] > 0)
349 aForegroundPoints.push_back(aAllPoints.at(i)->GetCopy());
357 const CByteImage* pForegroundImage,
358 const CCalibration* calibration)
361 calibration->WorldToImageCoordinates(vPoint, vImagePoint,
false);
362 const int nIndex = ((int)vImagePoint.y) *
OLP_IMG_WIDTH + (int)vImagePoint.x;
366 return (pForegroundImage->pixels[nIndex] > 0);
376 const CByteImage* pForegroundImage,
377 const CCalibration* calibration)
384 const CByteImage* pForegroundImage,
385 const CCalibration* calibration,
386 float& fForegroundRatio,
387 int& nNumForegroundPixels)
396 pPoints2D =
new Vec2d[nNumPoints];
398 for (
int i = 0; i < nNumPoints; i++)
400 calibration->WorldToImageCoordinates(
408 pPoints2D =
new Vec2d[nNumPoints];
410 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
412 calibration->WorldToImageCoordinates(
413 pHypothesis->
aNewPoints.at(i)->vPosition, pPoints2D[i],
false);
418 calibration->WorldToImageCoordinates(
420 pPoints2D[pHypothesis->
aNewPoints.size() + i],
425 int nNumForegroundPoints = 0;
426 long nForegroundSum = 0;
428 for (
int i = 0; i < nNumPoints; i++)
430 int nIndex = (
OLP_IMG_WIDTH * (int)pPoints2D[i].y) + (int)pPoints2D[i].x;
434 nForegroundSum += pForegroundImage->pixels[nIndex];
436 if (pForegroundImage->pixels[nIndex] > 0)
438 nNumForegroundPoints++;
443 nNumForegroundPixels = nNumForegroundPoints;
444 fForegroundRatio = (double)nForegroundSum / ((
double)nNumPoints * 255.0);
506 const int nNumPoints,
507 const bool bUseSecondMaxPoints,
515 float fMinX = pPoints[0].x;
516 float fMaxX = pPoints[0].x;
517 float fMinY = pPoints[0].y;
518 float fMaxY = pPoints[0].y;
519 float fSecondMinX = pPoints[0].x;
520 float fSecondMaxX = pPoints[0].x;
521 float fSecondMinY = pPoints[0].y;
522 float fSecondMaxY = pPoints[0].y;
524 for (
int i = 0; i < nNumPoints; i++)
526 if (pPoints[i].x < fMinX)
529 fMinX = pPoints[i].x;
531 else if (pPoints[i].x < fSecondMinX)
533 fSecondMinX = pPoints[i].x;
536 if (pPoints[i].x > fMaxX)
539 fMaxX = pPoints[i].x;
541 else if (pPoints[i].x > fSecondMaxX)
543 fSecondMaxX = pPoints[i].x;
546 if (pPoints[i].y < fMinY)
549 fMinY = pPoints[i].y;
551 else if (pPoints[i].y < fSecondMinY)
553 fSecondMinY = pPoints[i].y;
556 if (pPoints[i].y > fMaxY)
559 fMaxY = pPoints[i].y;
561 else if (pPoints[i].y > fSecondMaxY)
563 fSecondMaxY = pPoints[i].y;
568 Vec2d* pRotatedPoints =
new Vec2d[nNumPoints];
570 for (
int i = 0; i < nNumPoints; i++)
572 pRotatedPoints[i].x = pPoints[i].x - pPoints[i].y;
573 pRotatedPoints[i].y = pPoints[i].x + pPoints[i].y;
576 float fMinXr = pRotatedPoints[0].x;
577 float fMaxXr = pRotatedPoints[0].x;
578 float fMinYr = pRotatedPoints[0].y;
579 float fMaxYr = pRotatedPoints[0].y;
580 float fSecondMinXr = pRotatedPoints[0].x;
581 float fSecondMaxXr = pRotatedPoints[0].x;
582 float fSecondMinYr = pRotatedPoints[0].y;
583 float fSecondMaxYr = pRotatedPoints[0].y;
585 for (
int i = 0; i < nNumPoints; i++)
587 if (pRotatedPoints[i].x < fMinXr)
589 fSecondMinXr = fMinXr;
590 fMinXr = pRotatedPoints[i].x;
592 else if (pRotatedPoints[i].x < fSecondMinXr)
594 fSecondMinXr = pRotatedPoints[i].x;
597 if (pRotatedPoints[i].x > fMaxXr)
599 fSecondMaxXr = fMaxXr;
600 fMaxXr = pRotatedPoints[i].x;
602 else if (pRotatedPoints[i].x > fSecondMaxXr)
604 fSecondMaxXr = pRotatedPoints[i].x;
607 if (pRotatedPoints[i].y < fMinYr)
609 fSecondMinYr = fMinYr;
610 fMinYr = pRotatedPoints[i].y;
612 else if (pRotatedPoints[i].y < fSecondMinYr)
614 fSecondMinYr = pRotatedPoints[i].y;
617 if (pRotatedPoints[i].y > fMaxYr)
619 fSecondMaxYr = fMaxYr;
620 fMaxYr = pRotatedPoints[i].y;
622 else if (pRotatedPoints[i].y > fSecondMaxYr)
624 fSecondMaxYr = pRotatedPoints[i].y;
628 const float fSqrt2Fact = 0.5f * sqrtf(2.0f);
629 fMinXr *= fSqrt2Fact;
630 fMaxXr *= fSqrt2Fact;
631 fMinYr *= fSqrt2Fact;
632 fMaxYr *= fSqrt2Fact;
633 fSecondMinXr *= fSqrt2Fact;
634 fSecondMaxXr *= fSqrt2Fact;
635 fSecondMinYr *= fSqrt2Fact;
636 fSecondMaxYr *= fSqrt2Fact;
638 if (bUseSecondMaxPoints)
641 if ((fSecondMaxX - fSecondMinX) * (fSecondMaxY - fSecondMinY) <
642 (fSecondMaxXr - fSecondMinXr) * (fSecondMaxYr - fSecondMinYr))
645 Math2d::SetVec(p1, fSecondMinX, fSecondMinY);
646 Math2d::SetVec(p2, fSecondMaxX, fSecondMinY);
647 Math2d::SetVec(p3, fSecondMaxX, fSecondMaxY);
648 Math2d::SetVec(p4, fSecondMinX, fSecondMaxY);
654 fSqrt2Fact * (fSecondMinXr + fSecondMinYr),
655 fSqrt2Fact * (-fSecondMinXr + fSecondMinYr));
657 fSqrt2Fact * (fSecondMaxXr + fSecondMinYr),
658 fSqrt2Fact * (-fSecondMaxXr + fSecondMinYr));
660 fSqrt2Fact * (fSecondMaxXr + fSecondMaxYr),
661 fSqrt2Fact * (-fSecondMaxXr + fSecondMaxYr));
663 fSqrt2Fact * (fSecondMinXr + fSecondMaxYr),
664 fSqrt2Fact * (-fSecondMinXr + fSecondMaxYr));
670 if ((fMaxX - fMinX) * (fMaxY - fMinY) < (fMaxXr - fMinXr) * (fMaxYr - fMinYr))
673 Math2d::SetVec(p1, fMinX, fMinY);
674 Math2d::SetVec(p2, fMaxX, fMinY);
675 Math2d::SetVec(p3, fMaxX, fMaxY);
676 Math2d::SetVec(p4, fMinX, fMaxY);
681 Math2d::SetVec(p1, fSqrt2Fact * (fMinXr + fMinYr), fSqrt2Fact * (-fMinXr + fMinYr));
682 Math2d::SetVec(p2, fSqrt2Fact * (fMaxXr + fMinYr), fSqrt2Fact * (-fMaxXr + fMinYr));
683 Math2d::SetVec(p3, fSqrt2Fact * (fMaxXr + fMaxYr), fSqrt2Fact * (-fMaxXr + fMaxYr));
684 Math2d::SetVec(p4, fSqrt2Fact * (fMinXr + fMaxYr), fSqrt2Fact * (-fMinXr + fMaxYr));
688 delete[] pRotatedPoints;
693 const Vec2d vMinMiddle,
694 const Vec2d vMaxMiddle,
695 const Vec2d vMiddleMax,
696 const CByteImage* pForegroundImage)
698 int nStartY = (int)vMiddleMin.y;
699 int nEndY = (
int)vMiddleMax.y;
700 int nMiddleY1, nMiddleY2;
701 float fDeltaLeft1, fDeltaLeft2, fDeltaLeft3, fDeltaRight1, fDeltaRight2, fDeltaRight3;
706 if (vMinMiddle.y < vMaxMiddle.y)
708 nMiddleY1 = (int)vMinMiddle.y;
709 nMiddleY2 = (
int)vMaxMiddle.y;
710 fDeltaLeft1 = (vMinMiddle.x - vMiddleMin.x) / (vMinMiddle.y - vMiddleMin.y);
711 fDeltaLeft2 = (vMiddleMax.x - vMinMiddle.x) / (vMiddleMax.y - vMinMiddle.y);
712 fDeltaLeft3 = fDeltaLeft2;
713 fDeltaRight1 = (vMaxMiddle.x - vMiddleMin.x) / (vMaxMiddle.y - vMiddleMin.y);
714 fDeltaRight2 = fDeltaRight1;
715 fDeltaRight3 = (vMiddleMax.x - vMaxMiddle.x) / (vMiddleMax.y - vMaxMiddle.y);
719 nMiddleY1 = (int)vMaxMiddle.y;
720 nMiddleY2 = (
int)vMinMiddle.y;
721 fDeltaLeft1 = (vMinMiddle.x - vMiddleMin.x) / (vMinMiddle.y - vMiddleMin.y);
722 fDeltaLeft2 = fDeltaLeft1;
723 fDeltaLeft3 = (vMiddleMax.x - vMinMiddle.x) / (vMiddleMax.y - vMinMiddle.y);
724 fDeltaRight1 = (vMaxMiddle.x - vMiddleMin.x) / (vMaxMiddle.y - vMiddleMin.y);
725 fDeltaRight2 = (vMiddleMax.x - vMaxMiddle.x) / (vMiddleMax.y - vMaxMiddle.y);
726 fDeltaRight3 = fDeltaRight2;
729 float fLeft = vMiddleMin.x;
730 float fRight = vMiddleMin.x;
733 for (
int i = nStartY; i < nMiddleY1; i++)
735 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
740 fLeft += fDeltaLeft1;
741 fRight += fDeltaRight1;
745 for (
int i = nMiddleY1; i < nMiddleY2; i++)
747 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
752 fLeft += fDeltaLeft2;
753 fRight += fDeltaRight2;
757 for (
int i = nMiddleY2; i < nEndY; i++)
759 for (
int j = (
int)fLeft; j <= (int)fRight; j++)
764 fLeft += fDeltaLeft3;
765 fRight += fDeltaRight3;
776 std::vector<Vec3d> aPoints3d;
778 for (
size_t i = 0; i < pHypothesisPoints.size(); i++)
780 aPoints3d.push_back(pHypothesisPoints.at(i)->vPosition);
794 const int nNumPoints = aPoints.size();
798 const float fNumPointsInv = 1.0f / (
float)nNumPoints;
801 for (
int i = 0; i < nNumPoints; i++)
803 vMean.x += aPoints.at(i).x;
804 vMean.y += aPoints.at(i).y;
805 vMean.z += aPoints.at(i).z;
808 vMean.x *= fNumPointsInv;
809 vMean.y *= fNumPointsInv;
810 vMean.z *= fNumPointsInv;
813 for (
int i = 0; i < nNumPoints; i++)
815 fVariance += (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);
820 fVariance *= fNumPointsInv;
830 const float fStdDevFactor,
831 std::vector<int>* pOldIndices)
833 if (aPoints.size() < 9)
835 if (pOldIndices != NULL)
837 pOldIndices->clear();
839 for (
size_t i = 0; i < aPoints.size(); i++)
841 pOldIndices->push_back(i);
851 const float fThreshold2 = fStdDevFactor * fStdDevFactor * fVariance;
853 ARMARX_VERBOSE_S <<
"Mean: (" << vMean.x <<
", " << vMean.y <<
", " << vMean.z
854 <<
"), std dev: " << sqrtf(fVariance);
859 if (pOldIndices != NULL)
861 pOldIndices->clear();
863 for (
size_t i = 0; i < aPoints.size(); i++)
865 pOldIndices->push_back(i);
868 for (
size_t i = 0; i < aPoints.size(); i++)
870 fDist2 = (vMean.x - aPoints.at(i).x) * (vMean.x - aPoints.at(i).x) +
871 (vMean.y - aPoints.at(i).y) * (vMean.y - aPoints.at(i).y) +
872 (vMean.z - aPoints.at(i).z) * (vMean.z - aPoints.at(i).z);
874 if (fDist2 > fThreshold2)
876 Math3d::SetVec(aPoints.at(i), aPoints.at(aPoints.size() - 1));
877 pOldIndices->at(i) = pOldIndices->at(aPoints.size() - 1);
879 pOldIndices->pop_back();
886 for (
size_t i = 0; i < aPoints.size(); i++)
888 fDist2 = (vMean.x - aPoints.at(i).x) * (vMean.x - aPoints.at(i).x) +
889 (vMean.y - aPoints.at(i).y) * (vMean.y - aPoints.at(i).y) +
890 (vMean.z - aPoints.at(i).z) * (vMean.z - aPoints.at(i).z);
892 if (fDist2 > fThreshold2)
894 aPoints[i] = aPoints[aPoints.size() - 1];
903 RemoveOutliers(std::vector<CHypothesisPoint*>& aPoints,
const float fStdDevFactor)
905 std::vector<Vec3d> aPointsVec3d;
906 std::vector<int> pOldIndices;
908 for (
size_t i = 0; i < aPoints.size(); i++)
910 aPointsVec3d.push_back(aPoints.at(i)->vPosition);
915 ARMARX_VERBOSE_S <<
"RemoveOutliers: " << pOldIndices.size() <<
" of " << aPoints.size()
920 std::vector<CHypothesisPoint*> aPointsCopy;
921 std::vector<bool> aPointStillIncluded;
923 for (
size_t i = 0; i < aPoints.size(); i++)
925 aPointsCopy.push_back(aPoints.at(i));
926 aPointStillIncluded.push_back(
false);
929 for (
size_t i = 0; i < pOldIndices.size(); i++)
931 aPointStillIncluded.at(pOldIndices.at(i)) =
true;
936 for (
size_t i = 0; i < aPointsCopy.size(); i++)
938 if (aPointStillIncluded.at(i))
940 aPoints.push_back(aPointsCopy.at(i));
944 delete aPointsCopy.at(i);
952 float fMinDist = FLT_MAX;
957 fDist = Math3d::Distance(vPoint, pHypothesis->
aConfirmedPoints.at(i)->vPosition);
959 if (fDist < fMinDist)
967 fDist = Math3d::Distance(vPoint, pHypothesis->
aDoubtablePoints.at(i)->vPosition);
969 if (fDist < fMinDist)
978 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr
981 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBA>);
990 cloud->points[i].x = p->
vPosition.x - vCenter.x;
991 cloud->points[i].y = p->
vPosition.y - vCenter.y;
992 cloud->points[i].z = p->
vPosition.z - vCenter.z;
996 cloud->points[i].a = 1;
1004 static const int division_table[] = {
1005 0, 1048576, 524288, 349525, 262144, 209715, 174762, 149796, 131072, 116508, 104857,
1006 95325, 87381, 80659, 74898, 69905, 65536, 61680, 58254, 55188, 52428, 49932,
1007 47662, 45590, 43690, 41943, 40329, 38836, 37449, 36157, 34952, 33825, 32768,
1008 31775, 30840, 29959, 29127, 28339, 27594, 26886, 26214, 25575, 24966, 24385,
1009 23831, 23301, 22795, 22310, 21845, 21399, 20971, 20560, 20164, 19784, 19418,
1010 19065, 18724, 18396, 18078, 17772, 17476, 17189, 16912, 16644, 16384, 16131,
1011 15887, 15650, 15420, 15196, 14979, 14768, 14563, 14364, 14169, 13981, 13797,
1012 13617, 13443, 13273, 13107, 12945, 12787, 12633, 12483, 12336, 12192, 12052,
1013 11915, 11781, 11650, 11522, 11397, 11275, 11155, 11037, 10922, 10810, 10699,
1014 10591, 10485, 10381, 10280, 10180, 10082, 9986, 9892, 9799, 9709, 9619,
1015 9532, 9446, 9362, 9279, 9198, 9118, 9039, 8962, 8886, 8811, 8738,
1016 8665, 8594, 8525, 8456, 8388, 8322, 8256, 8192, 8128, 8065, 8004,
1017 7943, 7884, 7825, 7767, 7710, 7653, 7598, 7543, 7489, 7436, 7384,
1018 7332, 7281, 7231, 7182, 7133, 7084, 7037, 6990, 6944, 6898, 6853,
1019 6808, 6765, 6721, 6678, 6636, 6594, 6553, 6512, 6472, 6432, 6393,
1020 6355, 6316, 6278, 6241, 6204, 6168, 6132, 6096, 6061, 6026, 5991,
1021 5957, 5924, 5890, 5857, 5825, 5793, 5761, 5729, 5698, 5667, 5637,
1022 5607, 5577, 5548, 5518, 5489, 5461, 5433, 5405, 5377, 5349, 5322,
1023 5295, 5269, 5242, 5216, 5190, 5165, 5140, 5115, 5090, 5065, 5041,
1024 5017, 4993, 4969, 4946, 4922, 4899, 4877, 4854, 4832, 4809, 4788,
1025 4766, 4744, 4723, 4702, 4681, 4660, 4639, 4619, 4599, 4578, 4559,
1026 4539, 4519, 4500, 4481, 4462, 4443, 4424, 4405, 4387, 4369, 4350,
1027 4332, 4315, 4297, 4279, 4262, 4245, 4228, 4211, 4194, 4177, 4161,
1032 const unsigned char g,
1033 const unsigned char b,
1039 const int max = MY_MAX(MY_MAX(r, g), b);
1040 const int min = MY_MIN(MY_MIN(r, g), b);
1041 const int delta =
max -
min;
1048 hInt = g > b ? 180 + ((30 * (g - b) * division_table[delta]) >> 20)
1049 : 180 - ((30 * (b - g) * division_table[delta]) >> 20);
1053 hInt = b > r ? 60 + ((30 * (b - r) * division_table[delta]) >> 20)
1054 : 60 - ((30 * (r - b) * division_table[delta]) >> 20);
1058 hInt = r > g ? 120 + ((30 * (r - g) * division_table[delta]) >> 20)
1059 : 120 - ((30 * (g - r) * division_table[delta]) >> 20);
1062 h = (hInt >= 180) ? hInt - 180 : hInt;
1065 s = (255 * delta * division_table[
max]) >> 20;
1072 std::vector<float>& aHueHistogram,
1073 std::vector<float>& aSaturationHistogram)
1079 <<
"CreateHueHistogram: wrong hypothesis type (not RGBD or SingleColored)!";
1087 unsigned char r, g, b, h,
s,
v;
1099 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1100 const int nHistogramIndexHue = h / nBucketSize;
1101 aHueHistogram.at(nHistogramIndexHue) += fWeight;
1102 const int nHistogramIndexSaturation =
s / nBucketSize;
1103 aSaturationHistogram.at(nHistogramIndexSaturation) += 1;
1107 const float fCandidatePointWeightFactor = 0.01f;
1109 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1118 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1119 const int nHistogramIndexHue = h / nBucketSize;
1120 aHueHistogram.at(nHistogramIndexHue) += fCandidatePointWeightFactor * fWeight;
1121 const int nHistogramIndexSaturation =
s / nBucketSize;
1122 aSaturationHistogram.at(nHistogramIndexSaturation) += fCandidatePointWeightFactor;
1137 std::vector<float>& aHueHistogram,
1138 std::vector<float>& aSaturationHistogram)
1147 for (
int i = nMinY; i < nMaxY; i++)
1149 for (
int j = nMinX; j < nMaxX; j++)
1154 const float fWeight = 1.0f - 1.0f / (1.0f + 0.0025f * (
s *
s));
1155 const int nHistogramIndexHue = h / nBucketSize;
1156 aHueHistogram.at(nHistogramIndexHue) += fWeight;
1157 const int nHistogramIndexSaturation =
s / nBucketSize;
1158 aSaturationHistogram.at(nHistogramIndexSaturation) += 1;
1171 std::vector<float> aHistogramTemp;
1172 const int nHistogramSize = aHistogram.size();
1173 aHistogramTemp.resize(nHistogramSize);
1175 for (
int i = 0; i < nHistogramSize; i++)
1177 aHistogramTemp.at(i) = aHistogram.at(i);
1181 for (
int i = 0; i < nHistogramSize; i++)
1189 0.7f * aHistogramTemp.at(i) +
1190 0.15f * aHistogramTemp.at((i - 1 + nHistogramSize) % nHistogramSize) +
1191 0.15f * aHistogramTemp.at((i + 1) % nHistogramSize);
1200 for (
size_t i = 0; i < aHistogram.size(); i++)
1202 fSum += aHistogram.at(i);
1205 const float fInverseSum = 1.0f / fSum;
1207 for (
size_t i = 0; i < aHistogram.size(); i++)
1209 aHistogram.at(i) *= fInverseSum;
1215 const std::vector<float>& aHistogram2)
1217 const int n = (int)aHistogram1.size();
1221 for (
int i = 0; i < n; i++)
1223 fDist += fabsf(aHistogram1.at(i) - aHistogram2.at(i));
1231 const std::vector<float>& aHistogram2)
1233 const int n = (int)aHistogram1.size();
1237 for (
int i = 0; i < n; i++)
1240 (aHistogram1.at(i) - aHistogram2.at(i)) * (aHistogram1.at(i) - aHistogram2.at(i));
1243 return sqrtf(fDist);
1248 const std::vector<float>& aHistogram2)
1250 const int n = (int)aHistogram1.size();
1254 for (
int i = 0; i < n; i++)
1256 fDist += (aHistogram1.at(i) - aHistogram2.at(i)) *
1257 (aHistogram1.at(i) - aHistogram2.at(i)) /
1258 (aHistogram1.at(i) + aHistogram2.at(i) + 0.00001f);
1261 return sqrtf(fDist);
1265 DrawCross(CByteImage* pGreyImage,
int x,
int y,
int nBrightness)
1269 for (
int j = -3; j <= 3; j++)
1271 pGreyImage->pixels[(y + j) *
OLP_IMG_WIDTH + x] = nBrightness;
1272 pGreyImage->pixels[y *
OLP_IMG_WIDTH + x + j] = nBrightness;
1278 DrawCross(CByteImage* pColorImage,
int x,
int y,
int r,
int g,
int b)
1282 for (
int j = -3; j <= 3; j++)
1285 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x) + 1] = g;
1286 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x) + 2] = b;
1289 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 1] = g;
1290 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 2] = b;
1300 for (
int j = -3; j <= 4; j++)
1303 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x) + 1] = g;
1304 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x) + 2] = b;
1306 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x + 1)] = r;
1307 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x + 1) + 1] = g;
1308 pColorImage->pixels[3 * ((y + j) *
OLP_IMG_WIDTH + x + 1) + 2] = b;
1312 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 1] = g;
1313 pColorImage->pixels[3 * (y *
OLP_IMG_WIDTH + x + j) + 2] = b;
1315 pColorImage->pixels[3 * ((y + 1) *
OLP_IMG_WIDTH + x + j)] = r;
1316 pColorImage->pixels[3 * ((y + 1) *
OLP_IMG_WIDTH + x + j) + 1] = g;
1317 pColorImage->pixels[3 * ((y + 1) *
OLP_IMG_WIDTH + x + j) + 2] = b;
1324 const CCalibration* calibration,
1325 CByteImage*& pForegroundImage)
1327 if (pForegroundImage == NULL)
1334 pForegroundImage->type != CByteImage::eGrayScale)
1336 delete pForegroundImage;
1344 pForegroundImage->pixels[i] = 0;
1352 calibration->WorldToImageCoordinates(
1354 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1358 pForegroundImage->pixels[nIndex] = 255;
1364 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1367 calibration->WorldToImageCoordinates(
1368 pHypothesis->
aNewPoints.at(i)->vPosition, vPoint2D,
false);
1369 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1373 pForegroundImage->pixels[nIndex] = 255;
1380 CByteImage* pTempImage =
1385 ImageProcessor::Dilate(pForegroundImage, pTempImage);
1386 ImageProcessor::Dilate(pTempImage, pForegroundImage);
1391 ImageProcessor::Erode(pForegroundImage, pTempImage);
1392 ImageProcessor::Erode(pTempImage, pForegroundImage);
1403 const CCalibration* calibration,
1404 CByteImage*& pProbabilityImage)
1406 if (pProbabilityImage == NULL)
1415 pProbabilityImage->pixels[i] = 0;
1419 const int probValueConfirmedPoints = 255;
1420 const int probValueCandidatePoints = 51;
1423 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size(); i++)
1425 calibration->WorldToImageCoordinates(
1426 pHypothesis->
aNewPoints.at(i)->vPosition, vPoint2D,
false);
1427 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1431 pProbabilityImage->pixels[nIndex] = probValueCandidatePoints;
1437 calibration->WorldToImageCoordinates(
1439 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1443 pProbabilityImage->pixels[nIndex] = probValueConfirmedPoints;
1447 CByteImage* tempImage =
new CByteImage(pProbabilityImage);
1449 const int nKernelSize = 4 * sigma + 1;
1450 ImageProcessor::GaussianSmooth(pProbabilityImage, tempImage, sigma * sigma, nKernelSize);
1451 ImageProcessor::HistogramStretching(tempImage, pProbabilityImage, 0.0f, 1.0f);
1452 ImageProcessor::GaussianSmooth(pProbabilityImage, tempImage, sigma * sigma, nKernelSize);
1453 ImageProcessor::HistogramStretching(tempImage, pProbabilityImage, 0.0f, 1.0f);
1466 for (
int i = 0; i < nNumDigits; i++)
1468 int nDecimalDivisor = 1;
1470 for (
int j = 0; j < i; j++)
1472 nDecimalDivisor *= 10;
1475 sFileName.at(sFileName.length() - (5 + i)) =
'0' + (nNumber / nDecimalDivisor) % 10;
1482 const CCalibration* calibration)
1484 CByteImage* pHypothesisRegionImage1 =
1486 CByteImage* pHypothesisRegionImage2 =
1491 int nIntersectingPoints = 0;
1492 int nUnionPoints = 0;
1496 nIntersectingPoints +=
1497 (pHypothesisRegionImage1->pixels[i] * pHypothesisRegionImage2->pixels[i] != 0);
1499 (pHypothesisRegionImage1->pixels[i] + pHypothesisRegionImage2->pixels[i] != 0);
1502 delete pHypothesisRegionImage1;
1503 delete pHypothesisRegionImage2;
1505 if (nUnionPoints > 0)
1507 return (
float)nIntersectingPoints / (
float)nUnionPoints;
1517 const CCalibration* calibration,
1519 const int nNumFusedHypotheses)
1527 for (
int i = 0; 2 * i < nSize; i++)
1535 ImageProcessor::Zero(pImage);
1540 calibration->WorldToImageCoordinates(
1542 int nIndex = (int)vPoint2D.y *
OLP_IMG_WIDTH + (
int)vPoint2D.x;
1546 pImage->pixels[3 * nIndex] =
1549 pImage->pixels[3 * nIndex + 1] =
1552 pImage->pixels[3 * nIndex + 2] =
1559 CByteImage* pTempImg =
new CByteImage(pImage);
1565 CByteImage* pSegmentationProbability = NULL;
1568 sFileName +=
"SegmProb.bmp";
1569 pSegmentationProbability->SaveToFile(sFileName.c_str());
1573 if (pSegmentationProbability->pixels[i] < 1 + nNumFusedHypotheses / 3)
1575 pImage->pixels[3 * i] *= 0.3;
1576 pImage->pixels[3 * i + 1] *= 0.3;
1577 pImage->pixels[3 * i + 2] *= 0.3;
1583 FillHolesRGB(
const CByteImage* pInputImage, CByteImage* pOutputImage,
const int nRadius)
1587 pOutputImage->pixels[i] = pInputImage->pixels[i];
1596 if (pInputImage->pixels[3 * nIndex] + pInputImage->pixels[3 * nIndex + 1] +
1597 pInputImage->pixels[3 * nIndex + 2] ==
1600 int r, g, b, nNumPixels;
1601 r = g = b = nNumPixels = 0;
1603 for (
int l = -nRadius; l <= nRadius; l++)
1605 for (
int k = -nRadius; k <= nRadius; k++)
1609 if (pInputImage->pixels[nTempIndex] +
1610 pInputImage->pixels[nTempIndex + 1] +
1611 pInputImage->pixels[nTempIndex + 2] !=
1614 r += pInputImage->pixels[nTempIndex];
1615 g += pInputImage->pixels[nTempIndex + 1];
1616 b += pInputImage->pixels[nTempIndex + 2];
1624 pOutputImage->pixels[3 * nIndex] = r / nNumPixels;
1625 pOutputImage->pixels[3 * nIndex + 1] = g / nNumPixels;
1626 pOutputImage->pixels[3 * nIndex + 2] = b / nNumPixels;
1634 FillHolesGray(
const CByteImage* pInputImage, CByteImage* pOutputImage,
const int nRadius)
1638 pOutputImage->pixels[i] = pInputImage->pixels[i];
1647 if (pInputImage->pixels[nIndex] == 0)
1652 for (
int l = -nRadius; l <= nRadius; l++)
1654 for (
int k = -nRadius; k <= nRadius; k++)
1658 if (pInputImage->pixels[nTempIndex] != 0)
1660 nSum += pInputImage->pixels[nTempIndex];
1668 pOutputImage->pixels[nIndex] = nSum / nNumPixels;
1678 const int nLeftLimit,
1679 const int nRightLimit)
1681 if (aHypothesisPoints.size() <= 1 || nRightLimit - nLeftLimit <= 0)
1686 float fPivot = aHypothesisPoints.at((nLeftLimit + nRightLimit) / 2)->vPosition.z;
1688 int nLeftIndex = nLeftLimit;
1689 int nRightIndex = nRightLimit;
1691 while (nLeftIndex <= nRightIndex)
1693 while (aHypothesisPoints.at(nLeftIndex)->vPosition.z < fPivot &&
1694 (nLeftIndex <= nRightIndex))
1699 while (aHypothesisPoints.at(nRightIndex)->vPosition.z > fPivot &&
1700 (nLeftIndex <= nRightIndex))
1705 if (nLeftIndex <= nRightIndex)
1708 aHypothesisPoints.at(nLeftIndex) = aHypothesisPoints.at(nRightIndex);
1709 aHypothesisPoints.at(nRightIndex) = pTemp;
1727 CByteImage* pDisparity,
1728 CByteImage* pEdgeImage)
1731 CByteImage* pTempImage =
new CByteImage(pImageGray);
1733 ImageProcessor::GaussianSmooth5x5(pImageGray, pTempImage);
1734 ImageProcessor::CalculateGradientImageSobel(pTempImage, pEdgeImage);
1738 pEdgesFromImage[i] = pEdgeImage->pixels[i];
1742 sScreenshotFile +=
"edge-img.bmp";
1743 pEdgeImage->SaveToFile(sScreenshotFile.c_str());
1749 int nNumZeroDisparityPixels = 0;
1753 if (pDisparity->pixels[i] == 0)
1755 nNumZeroDisparityPixels++;
1759 float fZeroDisparityPixelRatio =
1761 ImageProcessor::HistogramStretching(
1762 pDisparity, pTempImage, fZeroDisparityPixelRatio + 0.1f, 0.9f);
1764 sScreenshotFile +=
"disp.bmp";
1765 pTempImage->SaveToFile(sScreenshotFile.c_str());
1767 const float fSigma = 7;
1768 const int nKernelSize = 4 * fSigma + 1;
1769 ImageProcessor::GaussianSmooth(pTempImage, pEdgeImage, fSigma * fSigma, nKernelSize);
1771 ImageProcessor::CalculateGradientImageSobel(pEdgeImage, pTempImage);
1775 pEdgesFromDisparity[i] = pTempImage->pixels[i];
1779 sScreenshotFile +=
"edge-disp.bmp";
1780 pTempImage->SaveToFile(sScreenshotFile.c_str());
1789 sqrtf(pEdgesFromImage[i] * pEdgesFromDisparity[i] * sqrtf(pEdgesFromDisparity[i]));
1790 pEdgeImage->pixels[i] = (fValue > 255) ? 255 : fValue;
1794 sScreenshotFile +=
"edge-full.bmp";
1795 pEdgeImage->SaveToFile(sScreenshotFile.c_str());