33 #include <DataStructures/KdTree/KdTree.h>
34 #include <Tracking/ICP.h>
39 m_pKdTree =
new CKdTree();
41 m_nNumScenePoints = 0;
42 m_pValues =
new float*[1];
49 for (
int i = 0; i < m_nNumScenePoints; i++)
51 delete[] m_pValues[i];
61 m_aScenePoints.clear();
63 for (
int i = 0; i < m_nNumScenePoints; i++)
65 delete[] m_pValues[i];
72 const int nSize = aScenePoints.size();
74 for (
int i = 0; i < nSize; i++)
76 m_aScenePoints.push_back(aScenePoints.at(i));
79 m_pKdTree =
new CKdTree(nSize);
81 m_pValues =
new float*[nSize];
82 m_nNumScenePoints = nSize;
84 for (
int i = 0; i < nSize; i++)
86 m_pValues[i] =
new float[7];
87 m_pValues[i][0] = aScenePoints.at(i).x;
88 m_pValues[i][1] = aScenePoints.at(i).y;
89 m_pValues[i][2] = aScenePoints.at(i).z;
90 m_pValues[i][3] = m_fColorWeight * aScenePoints.at(i).r;
91 m_pValues[i][4] = m_fColorWeight * aScenePoints.at(i).g;
92 m_pValues[i][5] = m_fColorWeight * aScenePoints.at(i).b;
93 m_pValues[i][6] = m_fColorWeight * aScenePoints.at(i).i;
100 m_pKdTree->Build(m_pValues, 0, nSize - 1, m_nKdTreeBucketSize, 7, 0);
104 m_pKdTree->Build(m_pValues, 0, nSize - 1, m_nKdTreeBucketSize, 6, 1);
112 const float fBestDistanceUntilNow)
114 Math3d::SetMat(mRotation, Math3d::unit_mat);
115 Math3d::SetVec(vTranslation, 0, 0, 0);
117 if (aObjectPoints.size() < 3)
123 if (m_aScenePoints.size() < 3)
129 float fLastDistance = FLT_MAX;
130 float fDistance = 0, fPointDistance;
131 Vec3d vPoint, vPointTransformed;
132 float* pPointData =
new float[7];
133 float* pNearestNeighbor;
134 Vec3d* pPointPositions =
new Vec3d[aObjectPoints.size()];
135 Vec3d* pCorrespondingPointPositions =
new Vec3d[aObjectPoints.size()];
136 int nNumPointCorrespondences;
139 for (
int n = 0; n < m_nMaxIterations; n++)
142 nNumPointCorrespondences = 0;
145 for (
size_t i = 0; i < aObjectPoints.size(); i++)
148 vPoint, aObjectPoints.at(i).x, aObjectPoints.at(i).y, aObjectPoints.at(i).z);
149 Math3d::MulMatVec(mRotation, vPoint, vTranslation, vPointTransformed);
151 pPointData[0] = vPointTransformed.x;
152 pPointData[1] = vPointTransformed.y;
153 pPointData[2] = vPointTransformed.z;
154 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
155 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
156 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
157 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
159 m_pKdTree->NearestNeighborBBF(pPointData, fPointDistance, pNearestNeighbor);
162 fPointDistance = sqrtf(fPointDistance);
172 if (fPointDistance > m_fCutoffDistance)
174 fDistance += m_fCutoffDistance;
178 fDistance += fPointDistance;
179 Math3d::SetVec(pPointPositions[nNumPointCorrespondences], vPoint);
180 Math3d::SetVec(pCorrespondingPointPositions[nNumPointCorrespondences],
183 pNearestNeighbor[2]);
184 nNumPointCorrespondences++;
188 if (nNumPointCorrespondences < 3)
190 ARMARX_IMPORTANT_S <<
"CColorICP::SearchObject: less than 3 correspondences found - no "
191 "transformation determined";
196 CICP::CalculateOptimalTransformation(pPointPositions,
197 pCorrespondingPointPositions,
198 nNumPointCorrespondences,
205 if (0.8f * fDistance < fBestDistanceUntilNow)
208 if (1.0f - fDistance / fLastDistance < 0.01f * m_fConvergenceDelta)
213 else if ((1.0f - fDistance / fLastDistance < m_fConvergenceDelta) ||
214 (2 * n > m_nMaxIterations))
219 else if ((0.5f * fDistance > fBestDistanceUntilNow) && (3 * n > m_nMaxIterations))
225 fLastDistance = fDistance;
231 delete[] pPointPositions;
232 delete[] pCorrespondingPointPositions;
234 return fDistance / aObjectPoints.size();
239 float fCutoffDistance,
240 float fConvergenceDelta,
242 int nKdTreeBucketSize)
244 m_fColorWeight = fColorWeight;
245 m_fCutoffDistance = fCutoffDistance;
246 m_fConvergenceDelta = fConvergenceDelta;
247 m_nMaxIterations = nMaxIterations;
248 m_nKdTreeBucketSize = nKdTreeBucketSize;
252 CColorICP::FindNNBruteForce(
const float* pPoint,
float& fSquaredDistance,
float*& pNeighbor)
254 float fMinDist = FLT_MAX;
258 for (
int i = 0; i < m_nNumScenePoints; i++)
262 for (
int j = 0; j < 6; j++)
264 fDist += (pPoint[j] - m_pValues[i][j]) * (pPoint[j] - m_pValues[i][j]);
267 if (fDist < fMinDist)
274 fSquaredDistance = fMinDist;
275 pNeighbor = m_pValues[nBestIndex];
280 std::vector<float>& aPointMatchDistances)
282 float* pPointData =
new float[7];
283 float* pNearestNeighbor;
286 for (
size_t i = 0; i < aObjectPoints.size(); i++)
288 pPointData[0] = aObjectPoints.at(i).x;
289 pPointData[1] = aObjectPoints.at(i).y;
290 pPointData[2] = aObjectPoints.at(i).z;
291 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
292 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
293 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
294 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
296 m_pKdTree->NearestNeighborBBF(pPointData, fDistance, pNearestNeighbor);
298 aPointMatchDistances.push_back(fDistance);
306 std::vector<CColorICP::CPointXYZRGBI>& aNeighbors,
307 std::vector<float>& aPointMatchDistances)
309 float* pPointData =
new float[7];
310 float* pNearestNeighbor;
313 const float fColorWeightFactor = 1.0f / m_fColorWeight;
315 for (
size_t i = 0; i < aObjectPoints.size(); i++)
317 pPointData[0] = aObjectPoints.at(i).x;
318 pPointData[1] = aObjectPoints.at(i).y;
319 pPointData[2] = aObjectPoints.at(i).z;
320 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
321 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
322 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
323 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
325 m_pKdTree->NearestNeighborBBF(pPointData, fDistance, pNearestNeighbor);
327 pNearestNeighborPoint.
x = pNearestNeighbor[0];
328 pNearestNeighborPoint.
y = pNearestNeighbor[1];
329 pNearestNeighborPoint.
z = pNearestNeighbor[2];
330 pNearestNeighborPoint.
r = fColorWeightFactor * pNearestNeighbor[3];
331 pNearestNeighborPoint.
g = fColorWeightFactor * pNearestNeighbor[4];
332 pNearestNeighborPoint.
b = fColorWeightFactor * pNearestNeighbor[5];
333 pNearestNeighborPoint.
i = fColorWeightFactor * pNearestNeighbor[6];
335 aNeighbors.push_back(pNearestNeighborPoint);
336 aPointMatchDistances.push_back(fDistance);
362 Math3d::SetVec(pRet->
vPosition, pPoint.
x, pPoint.
y, pPoint.
z);
374 const float x = pPoint.
x;
375 const float y = pPoint.
y;
376 const float z = pPoint.
z;
377 pPoint.
x = mRotation.r1 * x + mRotation.r2 * y + mRotation.r3 * z + vTranslation.x;
378 pPoint.
y = mRotation.r4 * x + mRotation.r5 * y + mRotation.r6 * z + vTranslation.y;
379 pPoint.
z = mRotation.r7 * x + mRotation.r8 * y + mRotation.r9 * z + vTranslation.z;