28 #include <Eigen/Eigenvalues>
32 GaussianMixtureDistributionBasePtr
37 GaussianMixtureDistributionPtr::dynamicCast(fullGMM->clone());
39 if (!reducedGMM || countComp < 1)
44 reducedGMM->normalize();
46 const int FULL_GMM_SIZE = fullGMM->size();
48 while (reducedGMM->size() > countComp)
50 float minCost = FLT_MAX;
51 int mergeIndexes = -1;
53 for (
int i = 0; i < reducedGMM->size(); ++i)
54 for (
int j = i + 1; j < reducedGMM->size(); ++j)
61 mergeIndexes = i * FULL_GMM_SIZE + j;
68 reducedGMM, mergeIndexes / FULL_GMM_SIZE, mergeIndexes % FULL_GMM_SIZE);
75 GaussianMixtureDistributionBasePtr
82 GaussianMixtureDistributionBasePtr
89 GaussianMixtureDistributionBasePtr
91 float maxSphereRadius)
96 GaussianMixtureDistributionBasePtr
102 GaussianMixtureDistributionPtr::dynamicCast(fullGMM->clone());
104 if (!reducedGMM || devMeasure < 0)
110 float precalcDeviation = 0.f;
116 precalcDeviation = maxDeviation * maxDeviation;
120 precalcDeviation = maxDeviation * maxDeviation * maxDeviation;
124 precalcDeviation = 0.f;
127 reducedGMM->normalize();
131 struct PairDistanceComparator
136 return (i.second < j.second);
142 const int REDUCED_GMM_SIZE = reducedGMM->size();
144 distVector.reserve((REDUCED_GMM_SIZE - 1 * REDUCED_GMM_SIZE) / 2);
153 for (GMMCompPairDistanceVector::const_iterator it = distVector.begin();
154 it != distVector.end();
157 const int index1 = it->first / REDUCED_GMM_SIZE;
158 const int index2 = it->first % REDUCED_GMM_SIZE;
159 GaussianMixtureComponent mergedComp;
161 reducedGMM->getComponent(index1), reducedGMM->getComponent(index2), mergedComp);
162 bool doMerge =
false;
164 NormalDistributionPtr::dynamicCast(mergedComp.gaussian)->toEigenCovariance();
170 doMerge = (cov(0, 0) < precalcDeviation && cov(1, 1) < precalcDeviation &&
171 cov(2, 2) < precalcDeviation);
177 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> es(cov);
178 Eigen::Vector3f evals = es.eigenvalues();
179 doMerge = (evals(0) < precalcDeviation && evals(1) < precalcDeviation &&
180 evals(2) < precalcDeviation);
186 doMerge = sqrtf(cov.determinant()) < precalcDeviation;
196 std::cout <<
"Adding component: " << mergedComp.gaussian->output()
197 <<
" (instead of " << index1 <<
" and " << index2 <<
")" << std::endl;
210 const GaussianMixtureComponent& comp2,
211 GaussianMixtureComponent& mergedComp)
216 const Eigen::VectorXf x1 = gaussian1->toEigenMean();
217 const Eigen::VectorXf x2 = gaussian2->toEigenMean();
218 const Eigen::MatrixXf p1 = gaussian1->toEigenCovariance();
219 const Eigen::MatrixXf p2 = gaussian2->toEigenCovariance();
221 const float w1 = comp1.weight;
222 const float w2 = comp2.weight;
224 const float k = 1. / (w1 + w2);
225 const Eigen::VectorXf d = x1 - x2;
227 const Eigen::VectorXf
mean = k * (w1 * x1 + w2 * x2);
228 const Eigen::MatrixXf cov = k * (w1 * p1 + w2 * p2 + k * w1 * w2 * d * d.transpose());
231 mergedComp.weight = w1 + w2;
238 const GaussianMixtureComponent& mergedComp)
240 gmm->setComponent(index1, mergedComp);
241 gmm->removeComponent(index2);
247 GaussianMixtureComponent comp1 = gmm->getComponent(index1);
248 GaussianMixtureComponent comp2 = gmm->getComponent(index2);
250 GaussianMixtureComponent mergedComp;
258 return gmmDistance->getDistance(gmm->getComponent(c1), gmm->getComponent(c2));
265 const int GMM_SIZE = gmm->size();
267 for (
int i = 0; i < GMM_SIZE - 1; ++i)
268 for (
int j = i + 1; j < GMM_SIZE; ++j)
271 const int index = i * GMM_SIZE + j;