-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathGMM.cpp
More file actions
114 lines (87 loc) · 2.65 KB
/
Copy pathGMM.cpp
File metadata and controls
114 lines (87 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* GrabCut implementation source code Copyright(c) 2005-2006 Justin Talbot
*
* All Rights Reserved.
* For educational use only; commercial use expressly forbidden.
* NO WARRANTY, express or implied, for this software.
*/
/**********************************************************************************
*
* GMM
* by Hu yangyang 2016/1/12
*
***********************************************************************************/
#include "GMM.h"
#include "cluster.h"
GMM::GMM(unsigned int K) : mK(K)
{
mGaussians = new GaussianPDF[mK];
}
GMM::~GMM()
{
if (mGaussians)
delete [] mGaussians;
}
Real GMM::p(Color c)
{
Real result = 0;
if (mGaussians)
{
for (unsigned int i=0; i < mK; i++)
{
result += mGaussians[i].pi * p(i, c);
}
}
return result;
}
Real GMM::p(unsigned int i, Color c)
{
Real result = 0;
if( mGaussians[i].pi > 0 )
{
if (mGaussians[i].determinant > 0)
{
Real r = c.r - mGaussians[i].mu.r;
Real g = c.g - mGaussians[i].mu.g;
Real b = c.b - mGaussians[i].mu.b;
Real d = r * (r*mGaussians[i].inverse[0][0] + g*mGaussians[i].inverse[1][0] + b*mGaussians[i].inverse[2][0]) +
g * (r*mGaussians[i].inverse[0][1] + g*mGaussians[i].inverse[1][1] + b*mGaussians[i].inverse[2][1]) +
b * (r*mGaussians[i].inverse[0][2] + g*mGaussians[i].inverse[1][2] + b*mGaussians[i].inverse[2][2]);
result = (Real)(1.0/(sqrt(mGaussians[i].determinant)) * exp(-0.5*d));
}
}
return result;
}
int GMM::Build(double** data, uint nrows)
{
uint i,j;
int* clusterid = (int*)malloc(nrows*sizeof(int));
// run k-means clustering
const int ncols = 3;
const int nclusters = mK;
const int transpose = 0;
const char dist = 'e';
const char method = 'a';
int npass = 1;
int ifound = 0;
double error;
double* weight = (double*)malloc(ncols*sizeof(double));
int** mask = (int**)malloc(nrows*sizeof(int*));
for (i = 0; i < nrows; i++)
{
mask[i] = (int*)malloc(ncols*sizeof(int));
for (j = 0; j < ncols; j++) mask[i][j] = 1;
}
for (i = 0; i < ncols; i++) weight[i] = 1.0;
kcluster(nclusters,nrows,ncols,data,mask,weight,transpose,npass,method,dist,clusterid, &error, &ifound);
// build the GMM
GaussianFitter* gaussianFitter = new GaussianFitter[mK];
for (i = 0; i < nrows; i++) gaussianFitter[clusterid[j]].add(Color((float)data[i][0],(float)data[i][1],(float)data[i][2]));
for (i = 0; i < mK; i++) gaussianFitter[i].finalize(mGaussians[i], nrows);
delete [] gaussianFitter;
for (i = 0; i < nrows; i++) free(mask[i]);
free(mask);
free(weight);
free(clusterid);
return 1;
}