28 #include <Eigen/Eigenvalues>
36 if (!reducedGMM || countComp < 1)
41 reducedGMM->normalize();
43 const int FULL_GMM_SIZE = fullGMM->size();
45 while (reducedGMM->size() > countComp)
47 float minCost = FLT_MAX;
48 int mergeIndexes = -1;
50 for (
int i = 0; i < reducedGMM->size(); ++i)
51 for (
int j = i + 1; j < reducedGMM->size(); ++j)
58 mergeIndexes = i * FULL_GMM_SIZE + j;
64 mergeGMMComponents(reducedGMM, mergeIndexes / FULL_GMM_SIZE, mergeIndexes % FULL_GMM_SIZE);
91 if (!reducedGMM || devMeasure < 0)
97 float precalcDeviation = 0.f;
103 precalcDeviation = maxDeviation * maxDeviation;
107 precalcDeviation = maxDeviation * maxDeviation * maxDeviation;
111 precalcDeviation = 0.f;
114 reducedGMM->normalize();
118 struct PairDistanceComparator
122 return (i.second < j.second);
128 const int REDUCED_GMM_SIZE = reducedGMM->size();
130 distVector.reserve((REDUCED_GMM_SIZE - 1 * REDUCED_GMM_SIZE) / 2);
139 for (GMMCompPairDistanceVector::const_iterator it = distVector.begin(); it != distVector.end(); ++it)
141 const int index1 = it->first / REDUCED_GMM_SIZE;
142 const int index2 = it->first % REDUCED_GMM_SIZE;
143 GaussianMixtureComponent mergedComp;
144 mergeGMMComponents(reducedGMM->getComponent(index1), reducedGMM->getComponent(index2), mergedComp);
145 bool doMerge =
false;
146 Eigen::Matrix3f cov = NormalDistributionPtr::dynamicCast(mergedComp.gaussian)->toEigenCovariance();
152 doMerge = (cov(0, 0) < precalcDeviation &&
153 cov(1, 1) < precalcDeviation &&
154 cov(2, 2) < precalcDeviation);
160 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> es(cov);
161 Eigen::Vector3f evals = es.eigenvalues();
162 doMerge = (evals(0) < precalcDeviation &&
163 evals(1) < precalcDeviation &&
164 evals(2) < precalcDeviation);
170 doMerge = sqrtf(cov.determinant()) < precalcDeviation;
180 std::cout <<
"Adding component: " << mergedComp.gaussian->output() <<
" (instead of " << index1 <<
" and " << index2 <<
")" << std::endl;
197 const Eigen::VectorXf x1 = gaussian1->toEigenMean();
198 const Eigen::VectorXf x2 = gaussian2->toEigenMean();
199 const Eigen::MatrixXf p1 = gaussian1->toEigenCovariance();
200 const Eigen::MatrixXf p2 = gaussian2->toEigenCovariance();
202 const float w1 = comp1.weight;
203 const float w2 = comp2.weight;
205 const float k = 1. / (w1 + w2);
206 const Eigen::VectorXf d = x1 - x2;
208 const Eigen::VectorXf
mean = k * (w1 * x1 + w2 * x2);
209 const Eigen::MatrixXf cov = k * (w1 * p1 + w2 * p2 + k * w1 * w2 * d * d.transpose());
212 mergedComp.weight = w1 + w2;
217 gmm->setComponent(index1, mergedComp);
218 gmm->removeComponent(index2);
223 GaussianMixtureComponent comp1 = gmm->getComponent(index1);
224 GaussianMixtureComponent comp2 = gmm->getComponent(index2);
226 GaussianMixtureComponent mergedComp;
233 return gmmDistance->getDistance(gmm->getComponent(c1), gmm->getComponent(c2));
238 const int GMM_SIZE = gmm->size();
240 for (
int i = 0; i < GMM_SIZE - 1; ++i)
241 for (
int j = i + 1; j < GMM_SIZE; ++j)
244 const int index = i * GMM_SIZE + j;