56 float getDistance(
const GaussianMixtureDistributionBasePtr& gmm1,
const GaussianMixtureDistributionBasePtr& gmm2,
60 std::vector<NormalDistributionPtr> g1, g2;
61 std::vector<float> w1, w2;
62 preprocessGMM(gmm1, g1, w1);
63 preprocessGMM(gmm2, g2, w2);
65 const float d11 = calcCrossSum(gmm1, g1, w1, gmm1, g1, w1);
66 const float d22 = calcCrossSum(gmm2, g2, w2, gmm2, g2, w2);
67 const float d12 = calcCrossSum(gmm1, g1, w1, gmm2, g2, w2);
69 const float isd = d11 + d22 - 2 * d12;
70 return normalize ? (isd / (d11 + d22)) : isd;
73 float getDistance(
const GaussianMixtureDistributionBasePtr& gmm1,
const GaussianMixtureDistributionBasePtr& gmm2)
override
75 return getDistance(gmm1, gmm2,
false);
78 float getDistance(
const GaussianMixtureDistributionBasePtr& gmm1,
const GaussianMixtureDistributionBasePtr& gmm2,
82 std::vector<NormalDistributionPtr> g1, g2;
83 std::vector<float> w1, w2;
84 preprocessGMM(gmm1, g1, w1);
85 preprocessGMM(gmm2, g2, w2);
87 const float d22 = calcCrossSum(gmm2, g2, w2, gmm2, g2, w2);
88 const float d12 = calcCrossSum(gmm1, g1, w1, gmm2, g2, w2);
90 return d11 + d22 - 2 * d12;
93 float getDistance(
const GaussianMixtureComponent& comp1,
const GaussianMixtureComponent& comp2)
override
100 std::vector<NormalDistributionPtr> g;
101 std::vector<float> w;
102 preprocessGMM(gmm, g, w);
104 return calcCrossSum(gmm, g, w, gmm, g, w);
109 void preprocessGMM(
const GaussianMixtureDistributionBasePtr& gmm, std::vector<NormalDistributionPtr>& g,
110 std::vector<float>& w)
113 for (
int i = 0; i < gmm->size(); ++i)
115 GaussianMixtureComponent
c = gmm->getComponent(i);
116 g.push_back(NormalDistributionPtr::dynamicCast(
c.gaussian));
117 w.push_back(
c.weight);
121 float calcCrossSum(
const GaussianMixtureDistributionBasePtr& gmm1, std::vector<NormalDistributionPtr>& g1,
122 std::vector<float>& w1,
123 const GaussianMixtureDistributionBasePtr& gmm2, std::vector<NormalDistributionPtr>& g2,
124 std::vector<float>& w2)
128 const int GMM2_SIZE = gmm2->size();
130 for (
int i = 0; i < gmm1->size(); ++i)
132 const float wi = w1[i];
133 const Eigen::Vector3f mi = g1[i]->toEigenMean();
136 for (
int j = 0; j < GMM2_SIZE; ++j)
138 const float f = evaluate3DGaussian(mi, g2[j]->toEigenMean(),
pi + g2[j]->toEigenCovariance());
146 float evaluate3DGaussian(
const Eigen::Vector3f& point,
const Eigen::Vector3f&
mean,
const Eigen::Matrix3f& cov)
148 return evaluate3DGaussian(point,
mean, cov.inverse(), cov.determinant());
151 float evaluate3DGaussian(
const Eigen::Vector3f& point,
const Eigen::Vector3f&
mean,
const Eigen::Matrix3f& covInv,
float covDet)
154 const float e = expf(inner);
156 static const float pm = powf(2 *
M_PI, -1.5f);
157 return pm * powf(covDet, -0.5) * e;