39 const int nParallelityFactor = omp_get_num_procs();
40 m_pColorICPInstances =
new CColorICP*[nParallelityFactor];
42 for (
int i = 0; i < nParallelityFactor; i++)
44 m_pColorICPInstances[i] =
new CColorICP();
52 const int nParallelityFactor = omp_get_num_procs();
54 for (
int i = 0; i < nParallelityFactor; i++)
56 delete m_pColorICPInstances[i];
59 delete m_pColorICPInstances;
67 std::vector<CColorICP::CPointXYZRGBI> aScenePointsConverted;
68 aScenePointsConverted.resize(aScenePoints.size());
70 for (
size_t i = 0; i < aScenePoints.size(); i++)
76 const int nParallelityFactor = omp_get_num_procs();
78 for (
int i = 0; i < nParallelityFactor; i++)
86 const std::vector<CHypothesisPoint*>& aObjectPoints,
90 const Vec3d upwardsVector,
91 const int nEffortLevel,
92 const std::vector<Vec3d>* pPossibleLocationOffsets,
93 std::vector<CColorICP::CPointXYZRGBI>* pNearestNeighbors,
94 std::vector<float>* pPointMatchDistances,
95 const std::vector<CHypothesisPoint*>* pAdditionalPoints,
96 const float maxAcceptedDistance)
99 gettimeofday(&tStart, 0);
100 const int nParallelityFactor = omp_get_num_procs();
101 omp_set_num_threads(nParallelityFactor);
104 std::vector<Vec3d> aPossibleLocationOffsets;
105 aPossibleLocationOffsets.push_back(center);
107 if (pPossibleLocationOffsets)
109 for (
size_t i = 0; i < pPossibleLocationOffsets->size(); i++)
111 aPossibleLocationOffsets.push_back(pPossibleLocationOffsets->at(i));
115 const int nNumPossibleLocations = aPossibleLocationOffsets.size();
117 ARMARX_VERBOSE_S <<
"Trying to match object around " << nNumPossibleLocations
118 <<
" different possible locations";
120 for (
size_t i = 0; i < aPossibleLocationOffsets.size(); i++)
127 int nNumSamplesPerDimensionTemp;
129 switch (nEffortLevel)
135 nNumSamplesPerDimensionTemp = 1;
140 nNumSamplesPerDimensionTemp = 2;
145 nNumSamplesPerDimensionTemp = 3;
150 nNumSamplesPerDimensionTemp = 4;
155 nNumSamplesPerDimensionTemp = 5;
160 nNumSamplesPerDimensionTemp = 6;
164 bool tryDifferentOrientations = (Math3d::Length(upwardsVector) > 0) && (nEffortLevel >= 2);
165 const int nNumOrientations = tryDifferentOrientations ? 3 : 1;
166 Mat3d baseRotationMatrices[3];
167 Math3d::SetMat(baseRotationMatrices[0], Math3d::unit_mat);
168 Math3d::SetRotationMat(baseRotationMatrices[1], upwardsVector, -20.0 *
M_PI / 180.0);
169 Math3d::SetRotationMat(baseRotationMatrices[2], upwardsVector, 20.0 *
M_PI / 180.0);
171 const float fShift = fShiftTemp;
172 const int nNumSamplesPerDimension = nNumSamplesPerDimensionTemp;
173 const int nNumSamplesPerDimension2 = nNumSamplesPerDimension * nNumSamplesPerDimension;
174 const int nNumSamplesPerDimension3 =
175 nNumSamplesPerDimension * nNumSamplesPerDimension * nNumSamplesPerDimension;
176 const int nNumSamples = nNumOrientations * nNumSamplesPerDimension3 * nNumPossibleLocations;
177 const float fMiddle = 0.5f * (nNumSamplesPerDimension - 1);
178 Vec3d* pShiftVectors =
new Vec3d[nNumSamples];
179 Mat3d* rotationMatrices =
new Mat3d[nNumSamples];
181 for (
int n = 0; n < nNumPossibleLocations; n++)
183 const Vec3d vLocationOffset = aPossibleLocationOffsets.at(n);
185 for (
int i = 0; i < nNumSamplesPerDimension; i++)
187 for (
int j = 0; j < nNumSamplesPerDimension; j++)
189 for (
int k = 0; k < nNumSamplesPerDimension; k++)
191 for (
int l = 0; l < nNumOrientations; l++)
193 const int nIndex = n * nNumSamplesPerDimension3 * nNumOrientations +
194 i * nNumSamplesPerDimension2 * nNumOrientations +
195 j * nNumSamplesPerDimension * nNumOrientations +
196 k * nNumOrientations + l;
197 pShiftVectors[nIndex].x = vLocationOffset.x + (i - fMiddle) * fShift;
198 pShiftVectors[nIndex].y = vLocationOffset.y + (j - fMiddle) * fShift;
199 pShiftVectors[nIndex].z = vLocationOffset.z + (k - fMiddle) * fShift;
200 Math3d::SetMat(rotationMatrices[nIndex], baseRotationMatrices[l]);
209 size_t maxNumPoints = 200 + nEffortLevel * 200;
210 std::vector<CHypothesisPoint*> aObjectPointsDownsampled;
212 if (aObjectPoints.size() > maxNumPoints)
214 const float ratio = (
float)maxNumPoints / (
float)aObjectPoints.size();
215 const int randomThreshold = 1000.0f * ratio;
217 for (
size_t i = 0; i < aObjectPoints.size(); i++)
219 if (rand() % 1000 <= randomThreshold)
221 aObjectPointsDownsampled.push_back(aObjectPoints.at(i));
225 ARMARX_VERBOSE_S <<
"Object pointcloud was downsampled from " << aObjectPoints.size()
226 <<
" to " << aObjectPointsDownsampled.size() <<
" points";
230 aObjectPointsDownsampled = aObjectPoints;
236 Mat3d mBestRotation = Math3d::unit_mat;
237 Mat3d mSecondBestRotation = Math3d::unit_mat;
238 Vec3d vBestTranslation = {0, 0, 0};
239 Vec3d vSecondBestTranslation = {0, 0, 0};
240 float fBestDistance = FLT_MAX;
241 float fSecondBestDistance = FLT_MAX;
242 std::vector<float> distances;
243 std::vector<Vec3d> positions;
244 int numSamplesAlreadyDone = 0;
246 #pragma omp parallel for schedule(dynamic, 1)
247 for (
int k = 0; k < nNumSamples; k++)
249 const int nThreadNumber = omp_get_thread_num();
251 std::vector<CColorICP::CPointXYZRGBI> objectPointCloudPar;
252 objectPointCloudPar.resize(aObjectPointsDownsampled.size());
255 for (
size_t i = 0; i < aObjectPointsDownsampled.size(); i++)
258 vPointPar.
x -= center.x;
259 vPointPar.
y -= center.y;
260 vPointPar.
z -= center.z;
261 objectPointCloudPar.at(i) = vPointPar;
264 if (tryDifferentOrientations)
269 for (
size_t i = 0; i < objectPointCloudPar.size(); i++)
271 objectPointCloudPar.at(i).x += pShiftVectors[k].x;
272 objectPointCloudPar.at(i).y += pShiftVectors[k].y;
273 objectPointCloudPar.at(i).z += pShiftVectors[k].z;
276 Mat3d newRotation, newRotationGlobal;
277 Vec3d newTranslation, newTranslationGlobal;
278 float fNewObjectDistance = m_pColorICPInstances[nThreadNumber]->
SearchObject(
282 std::min(fBestDistance, maxAcceptedDistance));
290 newTranslationGlobal);
294 distances.push_back(fNewObjectDistance);
295 positions.push_back(newTranslationGlobal);
298 if (fNewObjectDistance < fBestDistance)
300 fSecondBestDistance = fBestDistance;
301 Math3d::SetMat(mSecondBestRotation, mBestRotation);
302 Math3d::SetVec(vSecondBestTranslation, vBestTranslation);
304 fBestDistance = fNewObjectDistance;
305 Math3d::SetMat(mBestRotation, newRotationGlobal);
306 Math3d::SetVec(vBestTranslation, newTranslationGlobal);
308 else if (fNewObjectDistance < fSecondBestDistance)
310 fSecondBestDistance = fNewObjectDistance;
311 Math3d::SetMat(mSecondBestRotation, newRotationGlobal);
312 Math3d::SetVec(vSecondBestTranslation, newTranslationGlobal);
315 numSamplesAlreadyDone++;
317 if (numSamplesAlreadyDone % (3 * nNumSamplesPerDimension3) == 0)
328 Vec3d vRefinementTranslation, vTemp;
329 Mat3d mRefinementRotation;
334 std::vector<CColorICP::CPointXYZRGBI> objectPointCloudConverted;
336 for (
size_t i = 0; i < aObjectPoints.size(); i++)
338 Math3d::MulMatVec(mBestRotation, aObjectPoints.at(i)->vPosition, vBestTranslation, vTemp);
342 vPoint.
r = aObjectPoints.at(i)->fColorR;
343 vPoint.
g = aObjectPoints.at(i)->fColorG;
344 vPoint.
b = aObjectPoints.at(i)->fColorB;
345 vPoint.
i = aObjectPoints.at(i)->fIntensity;
346 objectPointCloudConverted.push_back(vPoint);
350 std::vector<float> aPointMatchDistances;
352 aPointMatchDistances);
355 objectPointCloudConverted.clear();
357 for (
size_t i = 0; i < aObjectPoints.size(); i++)
362 mBestRotation, aObjectPoints.at(i)->vPosition, vBestTranslation, vTemp);
366 vPoint.
r = aObjectPoints.at(i)->fColorR;
367 vPoint.
g = aObjectPoints.at(i)->fColorG;
368 vPoint.
b = aObjectPoints.at(i)->fColorB;
369 vPoint.
i = aObjectPoints.at(i)->fIntensity;
370 objectPointCloudConverted.push_back(vPoint);
375 objectPointCloudConverted, mRefinementRotation, vRefinementTranslation, fBestDistance);
380 Math3d::SetMat(mOldBestRot, mBestRotation);
381 Math3d::MulMatMat(mRefinementRotation, mOldBestRot, mBestRotation);
383 Vec3d vOldBestTransl;
384 Math3d::SetVec(vOldBestTransl, vBestTranslation);
386 mRefinementRotation, vOldBestTransl, vRefinementTranslation, vBestTranslation);
390 if (pPointMatchDistances && pNearestNeighbors)
393 objectPointCloudConverted.clear();
395 for (
size_t i = 0; i < aObjectPoints.size(); i++)
398 mBestRotation, aObjectPoints.at(i)->vPosition, vBestTranslation, vTemp);
402 vPoint.
r = aObjectPoints.at(i)->fColorR;
403 vPoint.
g = aObjectPoints.at(i)->fColorG;
404 vPoint.
b = aObjectPoints.at(i)->fColorB;
405 vPoint.
i = aObjectPoints.at(i)->fIntensity;
406 objectPointCloudConverted.push_back(vPoint);
409 if (pAdditionalPoints)
411 for (
size_t i = 0; i < pAdditionalPoints->size(); i++)
414 mBestRotation, pAdditionalPoints->at(i)->vPosition, vBestTranslation, vTemp);
418 vPoint.
r = pAdditionalPoints->at(i)->fColorR;
419 vPoint.
g = pAdditionalPoints->at(i)->fColorG;
420 vPoint.
b = pAdditionalPoints->at(i)->fColorB;
421 vPoint.
i = pAdditionalPoints->at(i)->fIntensity;
422 objectPointCloudConverted.push_back(vPoint);
426 pNearestNeighbors->clear();
427 pPointMatchDistances->clear();
429 objectPointCloudConverted, *pNearestNeighbors, *pPointMatchDistances);
434 Math3d::SetMat(mRotation, mBestRotation);
435 Math3d::SetVec(vTranslation, vBestTranslation);
439 std::vector<float> badMatchDistances;
441 for (
size_t i = 0; i < distances.size(); i++)
443 float dist = Math3d::Distance(vBestTranslation, positions.at(i));
447 badMatchDistances.push_back(distances.at(i));
451 float averageBadMatchDistance = 0;
453 for (
size_t i = 0; i < badMatchDistances.size(); i++)
455 averageBadMatchDistance += badMatchDistances.at(i);
458 if (badMatchDistances.size() > 0)
460 averageBadMatchDistance /= badMatchDistances.size();
465 <<
" average bad match distance: " << averageBadMatchDistance;
469 delete[] pShiftVectors;
470 delete[] rotationMatrices;
473 gettimeofday(&tEnd, 0);
475 (1000 * tEnd.tv_sec + tEnd.tv_usec / 1000) - (1000 * tStart.tv_sec + tStart.tv_usec / 1000);
476 ARMARX_VERBOSE_S <<
"Time for pointcloud registration: " << tTimeDiff <<
" ms";
479 return fBestDistance;
485 const int nEffortLevel)
488 std::vector<CHypothesisPoint*> aObjectPoints;
500 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size() && i < nNewPointsLimit; i++)
502 aObjectPoints.push_back(pHypothesis->
aNewPoints.at(i));
506 size_t maxNumPoints = 200 + nEffortLevel * 200;
507 std::vector<CHypothesisPoint*> aObjectPointsDownsampled;
509 if (aObjectPoints.size() > maxNumPoints)
511 const float ratio = (
float)maxNumPoints / (
float)aObjectPoints.size();
512 const int randomThreshold = 1000.0f * ratio;
514 for (
size_t i = 0; i < aObjectPoints.size(); i++)
516 if (rand() % 1000 <= randomThreshold)
518 aObjectPointsDownsampled.push_back(aObjectPoints.at(i));
522 ARMARX_VERBOSE_S <<
"Object pointcloud was downsampled from " << aObjectPoints.size()
523 <<
" to " << aObjectPointsDownsampled.size() <<
" points";
527 aObjectPointsDownsampled = aObjectPoints;
531 std::vector<CColorICP::CPointXYZRGBI> objectPointCloudConverted;
533 for (
size_t i = 0; i < aObjectPointsDownsampled.size(); i++)
535 objectPointCloudConverted.push_back(
542 m_pColorICPInstances[0]->
SearchObject(objectPointCloudConverted, mRotation, vTranslation);
546 Vec3d vObjectCenter = {0, 0, 0};
548 for (
size_t i = 0; i < aObjectPointsDownsampled.size(); i++)
550 Math3d::AddToVec(vObjectCenter, aObjectPointsDownsampled.at(i)->vPosition);
553 Math3d::MulVecScalar(vObjectCenter, 1.0f / aObjectPointsDownsampled.size(), vObjectCenter);
555 Math3d::MulMatVec(mRotation, vObjectCenter, vTranslation, vTemp1);
556 float fTranslationLength = Math3d::Distance(vTemp1, vObjectCenter);
560 Math3d::GetAxisAndAngle(mRotation, vTemp1, fAngle);
566 ARMARX_VERBOSE_S <<
"Check at original position: Translation: " << fTranslationLength
567 <<
" Rotation: " << 180 * fAngle /
M_PI <<
"deg";
650 const Vec3d upwardsVector,
651 const int nEffortLevel,
652 const std::vector<Vec3d>* pPossibleLocations,
653 std::vector<CColorICP::CPointXYZRGBI>* pNearestNeighbors,
654 std::vector<float>* pPointMatchDistances,
655 const float maxAcceptedDistance)
657 #ifdef OLP_USE_DEPTH_MAP
660 std::vector<CHypothesisPoint*> aHypothesisPoints = pHypothesis->
aConfirmedPoints;
664 size_t maxNumPoints = 200 + nEffortLevel * 200;
665 size_t nNewPointsLimit;
667 if (aHypothesisPoints.size() >= maxNumPoints)
673 nNewPointsLimit = maxNumPoints - aHypothesisPoints.size();
682 for (
size_t i = 0; i < pHypothesis->
aNewPoints.size() && i < nNewPointsLimit; i++)
684 aHypothesisPoints.push_back(pHypothesis->
aNewPoints.at(i));
689 std::vector<CHypothesisPoint*> aAdditionalPoints;
691 for (
size_t i = nNewPointsLimit; i < pHypothesis->
aNewPoints.size(); i++)
693 aAdditionalPoints.push_back(pHypothesis->
aNewPoints.at(i));
710 pPointMatchDistances,
712 maxAcceptedDistance);
731 Vec3d center = {0, 0, 0};
745 for (
size_t i = 0; i < points.size(); i++)
748 points.at(i).x - center.x, points.at(i).y - center.y, points.at(i).z - center.z};
750 Math3d::MulMatVec(rot, point, pointRot);
751 points.at(i).x = pointRot.x + center.x;
752 points.at(i).y = pointRot.y + center.y;
753 points.at(i).z = pointRot.z + center.z;
763 Mat3d& completeRotation,
764 Vec3d& completeTranslation)
766 Math3d::MulMatMat(rotICP, rotShift, completeRotation);
769 Math3d::MulMatVec(completeRotation, center, temp1);
770 Math3d::MulMatVec(rotICP, transShift, temp2);
771 Math3d::SubtractVecVec(temp2, temp1, completeTranslation);
772 Math3d::AddToVec(completeTranslation, transICP);
782 float intensity = point.r + point.g + point.b + 3;
783 float intensityInverse = 1.0f / intensity;
784 result.
r = intensityInverse * (point.r + 1);
785 result.
g = intensityInverse * (point.g + 1);
786 result.
b = intensityInverse * (point.b + 1);
787 result.
i = intensity / (3.0f * 256.0f);