28 #include <DataStructures/KdTree/KdTree.h>
29 #include <Tracking/ICP.h>
41 m_pKdTree =
new CKdTree();
43 m_nNumScenePoints = 0;
44 m_pValues =
new float*[1];
53 for (
int i = 0; i < m_nNumScenePoints; i++)
55 delete[] m_pValues[i];
66 m_aScenePoints.clear();
68 for (
int i = 0; i < m_nNumScenePoints; i++)
70 delete[] m_pValues[i];
77 const int nSize = aScenePoints.size();
79 for (
int i = 0; i < nSize; i++)
81 m_aScenePoints.push_back(aScenePoints.at(i));
84 m_pKdTree =
new CKdTree(nSize);
86 m_pValues =
new float*[nSize];
87 m_nNumScenePoints = nSize;
89 for (
int i = 0; i < nSize; i++)
91 m_pValues[i] =
new float[7];
92 m_pValues[i][0] = aScenePoints.at(i).x;
93 m_pValues[i][1] = aScenePoints.at(i).y;
94 m_pValues[i][2] = aScenePoints.at(i).z;
95 m_pValues[i][3] = m_fColorWeight * aScenePoints.at(i).r;
96 m_pValues[i][4] = m_fColorWeight * aScenePoints.at(i).g;
97 m_pValues[i][5] = m_fColorWeight * aScenePoints.at(i).b;
98 m_pValues[i][6] = m_fColorWeight * aScenePoints.at(i).i;
105 m_pKdTree->Build(m_pValues, 0, nSize - 1, m_nKdTreeBucketSize, 7, 0);
109 m_pKdTree->Build(m_pValues, 0, nSize - 1, m_nKdTreeBucketSize, 6, 1);
116 float CColorICP::SearchObject(
const std::vector<CPointXYZRGBI>& aObjectPoints, Mat3d& mRotation,
Vec3d& vTranslation,
const float fBestDistanceUntilNow)
118 Math3d::SetMat(mRotation, Math3d::unit_mat);
119 Math3d::SetVec(vTranslation, 0, 0, 0);
121 if (aObjectPoints.size() < 3)
127 if (m_aScenePoints.size() < 3)
133 float fLastDistance = FLT_MAX;
134 float fDistance = 0, fPointDistance;
135 Vec3d vPoint, vPointTransformed;
136 float* pPointData =
new float[7];
137 float* pNearestNeighbor;
138 Vec3d* pPointPositions =
new Vec3d[aObjectPoints.size()];
139 Vec3d* pCorrespondingPointPositions =
new Vec3d[aObjectPoints.size()];
140 int nNumPointCorrespondences;
143 for (
int n = 0; n < m_nMaxIterations; n++)
146 nNumPointCorrespondences = 0;
149 for (
size_t i = 0; i < aObjectPoints.size(); i++)
151 Math3d::SetVec(vPoint, aObjectPoints.at(i).x, aObjectPoints.at(i).y, aObjectPoints.at(i).z);
152 Math3d::MulMatVec(mRotation, vPoint, vTranslation, vPointTransformed);
154 pPointData[0] = vPointTransformed.x;
155 pPointData[1] = vPointTransformed.y;
156 pPointData[2] = vPointTransformed.z;
157 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
158 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
159 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
160 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
162 m_pKdTree->NearestNeighborBBF(pPointData, fPointDistance, pNearestNeighbor);
165 fPointDistance = sqrtf(fPointDistance);
175 if (fPointDistance > m_fCutoffDistance)
177 fDistance += m_fCutoffDistance;
181 fDistance += fPointDistance;
182 Math3d::SetVec(pPointPositions[nNumPointCorrespondences], vPoint);
183 Math3d::SetVec(pCorrespondingPointPositions[nNumPointCorrespondences], pNearestNeighbor[0], pNearestNeighbor[1], pNearestNeighbor[2]);
184 nNumPointCorrespondences++;
188 if (nNumPointCorrespondences < 3)
190 ARMARX_IMPORTANT_S <<
"CColorICP::SearchObject: less than 3 correspondences found - no transformation determined";
195 CICP::CalculateOptimalTransformation(pPointPositions, pCorrespondingPointPositions, nNumPointCorrespondences, mRotation, vTranslation);
200 if (0.8f * fDistance < fBestDistanceUntilNow)
203 if (1.0f - fDistance / fLastDistance < 0.01f * m_fConvergenceDelta)
208 else if ((1.0f - fDistance / fLastDistance < m_fConvergenceDelta) || (2 * n > m_nMaxIterations))
213 else if ((0.5f * fDistance > fBestDistanceUntilNow) && (3 * n > m_nMaxIterations))
219 fLastDistance = fDistance;
225 delete[] pPointPositions;
226 delete[] pCorrespondingPointPositions;
228 return fDistance / aObjectPoints.size();
233 void CColorICP::SetParameters(
float fColorWeight,
float fCutoffDistance,
float fConvergenceDelta,
int nMaxIterations,
int nKdTreeBucketSize)
235 m_fColorWeight = fColorWeight;
236 m_fCutoffDistance = fCutoffDistance;
237 m_fConvergenceDelta = fConvergenceDelta;
238 m_nMaxIterations = nMaxIterations;
239 m_nKdTreeBucketSize = nKdTreeBucketSize;
243 void CColorICP::FindNNBruteForce(
const float* pPoint,
float& fSquaredDistance,
float*& pNeighbor)
245 float fMinDist = FLT_MAX;
249 for (
int i = 0; i < m_nNumScenePoints; i++)
253 for (
int j = 0; j < 6; j++)
255 fDist += (pPoint[j] - m_pValues[i][j]) * (pPoint[j] - m_pValues[i][j]);
258 if (fDist < fMinDist)
265 fSquaredDistance = fMinDist;
266 pNeighbor = m_pValues[nBestIndex];
274 float* pPointData =
new float[7];
275 float* pNearestNeighbor;
278 for (
size_t i = 0; i < aObjectPoints.size(); i++)
280 pPointData[0] = aObjectPoints.at(i).x;
281 pPointData[1] = aObjectPoints.at(i).y;
282 pPointData[2] = aObjectPoints.at(i).z;
283 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
284 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
285 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
286 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
288 m_pKdTree->NearestNeighborBBF(pPointData, fDistance, pNearestNeighbor);
290 aPointMatchDistances.push_back(fDistance);
299 void CColorICP::GetNearestNeighbors(
const std::vector<CPointXYZRGBI>& aObjectPoints, std::vector<CColorICP::CPointXYZRGBI>& aNeighbors, std::vector<float>& aPointMatchDistances)
301 float* pPointData =
new float[7];
302 float* pNearestNeighbor;
305 const float fColorWeightFactor = 1.0f / m_fColorWeight;
307 for (
size_t i = 0; i < aObjectPoints.size(); i++)
309 pPointData[0] = aObjectPoints.at(i).x;
310 pPointData[1] = aObjectPoints.at(i).y;
311 pPointData[2] = aObjectPoints.at(i).z;
312 pPointData[3] = m_fColorWeight * aObjectPoints.at(i).r;
313 pPointData[4] = m_fColorWeight * aObjectPoints.at(i).g;
314 pPointData[5] = m_fColorWeight * aObjectPoints.at(i).b;
315 pPointData[6] = m_fColorWeight * aObjectPoints.at(i).i;
317 m_pKdTree->NearestNeighborBBF(pPointData, fDistance, pNearestNeighbor);
319 pNearestNeighborPoint.
x = pNearestNeighbor[0];
320 pNearestNeighborPoint.
y = pNearestNeighbor[1];
321 pNearestNeighborPoint.
z = pNearestNeighbor[2];
322 pNearestNeighborPoint.
r = fColorWeightFactor * pNearestNeighbor[3];
323 pNearestNeighborPoint.
g = fColorWeightFactor * pNearestNeighbor[4];
324 pNearestNeighborPoint.
b = fColorWeightFactor * pNearestNeighbor[5];
325 pNearestNeighborPoint.
i = fColorWeightFactor * pNearestNeighbor[6];
327 aNeighbors.push_back(pNearestNeighborPoint);
328 aPointMatchDistances.push_back(fDistance);
354 Math3d::SetVec(pRet->
vPosition, pPoint.
x, pPoint.
y, pPoint.
z);
367 const float x = pPoint.
x;
368 const float y = pPoint.
y;
369 const float z = pPoint.
z;
370 pPoint.
x = mRotation.r1 * x + mRotation.r2 * y + mRotation.r3 * z + vTranslation.x;
371 pPoint.
y = mRotation.r4 * x + mRotation.r5 * y + mRotation.r6 * z + vTranslation.y;
372 pPoint.
z = mRotation.r7 * x + mRotation.r8 * y + mRotation.r9 * z + vTranslation.z;