OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
Classes | Public Member Functions | Private Attributes | List of all members
ossimKMeansClustering Class Reference

#include <ossimKMeansClustering.h>

Inheritance diagram for ossimKMeansClustering:
ossimReferenced

Classes

class  Cluster
 

Public Member Functions

 ossimKMeansClustering ()
 
 ~ossimKMeansClustering ()
 
void setNumClusters (ossim_uint32 K)
 
template<class T >
void setSamples (T *samples, ossim_uint32 num_entries)
 
template<class T >
void setPopulations (T *populations, ossim_uint32 num_entries)
 
bool computeKmeans ()
 
ossim_uint32 getNumClusters () const
 
double getMean (ossim_uint32 groupId) const
 
double getSigma (ossim_uint32 groupId) const
 
double getMinValue (ossim_uint32 groupId) const
 
double getMaxValue (ossim_uint32 groupId) const
 
const ossimKMeansClustering::ClustergetCluster (ossim_uint32 i) const
 
void setVerbose (bool v=true) const
 
- Public Member Functions inherited from ossimReferenced
 ossimReferenced ()
 
 ossimReferenced (const ossimReferenced &)
 
ossimReferencedoperator= (const ossimReferenced &)
 
void ref () const
 increment the reference count by one, indicating that this object has another pointer which is referencing it. More...
 
void unref () const
 decrement the reference count by one, indicating that a pointer to this object is referencing it. More...
 
void unref_nodelete () const
 decrement the reference count by one, indicating that a pointer to this object is referencing it. More...
 
int referenceCount () const
 

Private Attributes

ossim_uint32 m_numEntries
 
double * m_samples
 
double * m_populations
 
std::vector< Clusterm_clusters
 
bool m_clustersValid
 
bool m_verbose
 

Additional Inherited Members

- Protected Member Functions inherited from ossimReferenced
virtual ~ossimReferenced ()
 

Detailed Description

Definition at line 25 of file ossimKMeansClustering.h.

Constructor & Destructor Documentation

◆ ossimKMeansClustering()

ossimKMeansClustering::ossimKMeansClustering ( )

Definition at line 13 of file ossimKMeansClustering.cpp.

◆ ~ossimKMeansClustering()

ossimKMeansClustering::~ossimKMeansClustering ( )

Definition at line 23 of file ossimKMeansClustering.cpp.

References m_clusters, m_populations, and m_samples.

24 {
25  delete m_samples;
26  delete m_populations;
27  m_clusters.clear();
28 }
std::vector< Cluster > m_clusters

Member Function Documentation

◆ computeKmeans()

bool ossimKMeansClustering::computeKmeans ( )

Definition at line 37 of file ossimKMeansClustering.cpp.

References m_clusters, m_clustersValid, m_numEntries, m_populations, m_samples, m_verbose, max, min, n, OSSIM_DEFAULT_MAX_PIX_DOUBLE, and OSSIM_DEFAULT_MIN_PIX_DOUBLE.

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

38 {
39  if ((m_numEntries == 0) || (m_samples == 0))
40  return false;
41 
42  if (m_verbose)
43  std::cout.precision(6);
44 
45  // If populations aren't provided, assume only 1 of each sample:
46  if (m_populations == 0)
47  {
48  m_populations = new double [m_numEntries];
49  for (ossim_uint32 i=0; i<m_numEntries; ++i)
50  m_populations[i] = 1.0;
51  }
52 
53  // Scan for min and max:
54  double overall_min = OSSIM_DEFAULT_MAX_PIX_DOUBLE;
55  double overall_max = OSSIM_DEFAULT_MIN_PIX_DOUBLE;
56  for (ossim_uint32 i=0; i<m_numEntries; i++)
57  {
58  if (m_populations[i] == 0)
59  continue;
60 
61  if (m_samples[i] < overall_min)
62  overall_min = m_samples[i];
63  else if (m_samples[i] > overall_max)
64  overall_max = m_samples[i];
65  }
66 
67  double max_delta = overall_max - overall_min;
68  // double convergenceThreshold = 0.1*(max_delta)/m_numEntries;
69  ossim_uint32 numClusters = m_clusters.size();
70  double* variances = new double [numClusters];
71  ossim_uint32* priorCounts = new ossim_uint32 [numClusters];
72  double interm_samples = (overall_max - overall_min) / numClusters;
73  double mean_i = overall_min + interm_samples / 2.0; // initial mean for cluster 0;
74  double bound = overall_min;
75  for (ossim_uint32 gid=0; gid<numClusters; ++gid)
76  {
77  //Initialize cluster with even spread and initial mean:
78  m_clusters[gid].min = bound;
79  bound += interm_samples;
80  m_clusters[gid].max = bound;
81  m_clusters[gid].mean = mean_i;
82  m_clusters[gid].new_mean = 0;
83  mean_i += interm_samples;
84  m_clusters[gid].n = 0;
85  m_clusters[gid].sigma = 1.0;
86  variances[gid] = 0.0;
87  priorCounts[gid] = 0;
88  }
89  double delta, min_delta;
90  // ossim_uint32 best_gid, np, iters = 0, max_iters = 20;
91  ossim_uint32 best_gid, iters = 0, max_iters = 20;
92  bool converged = false;
93 
94  // Loop until converged on best solution:
95  while (!converged && (iters < max_iters))
96  {
97  converged = true; // prove otherwise
98  ++iters;
99 
100  for (ossim_uint32 gid=0; gid<numClusters; ++gid)
101  {
102  m_clusters[gid].min = overall_max;
103  m_clusters[gid].max = overall_min;
104  }
105 
106  for (ossim_uint32 i=0; i<m_numEntries; i++)
107  {
108  if ( m_populations[i] == 0)
109  continue;
110 
111  // Find the current cluster:
112  best_gid = 0;
113  min_delta = OSSIM_DEFAULT_MAX_PIX_DOUBLE;
114  for (ossim_uint32 gid=0; gid<numClusters; ++gid)
115  {
116  delta = fabs((m_samples[i] - m_clusters[gid].mean));
117  if (delta < min_delta)
118  {
119  min_delta = delta;
120  best_gid = gid;
121  }
122  }
123 
124  // Possible update of min/max for current cluster:
125  if (m_samples[i] < m_clusters[best_gid].min)
126  m_clusters[best_gid].min = m_samples[i];
127  else if (m_samples[i] > m_clusters[best_gid].max)
128  m_clusters[best_gid].max = m_samples[i];
129 
130  // Accumulate sample for the new mean for this cluster:
131  m_clusters[best_gid].new_mean += m_populations[i]*m_samples[i];
132  m_clusters[best_gid].n += m_populations[i];
133 
134  // Add this bin's contribution to the cluster stats. Use the sigma member as accumulator,
135  // normalize later:
136  delta = m_clusters[best_gid].mean - m_samples[i];
137  variances[best_gid] += m_populations[i]*delta*delta;
138 
139  } // End loop over bins
140 
141  // Finished processing all input pixels for this iteration. Update the means:
142  for (ossim_uint32 gid=0; gid<numClusters; ++gid)
143  {
144  // Compute new mean from accumulation:
145  if (m_clusters[gid].n)
146  {
147  m_clusters[gid].new_mean /= m_clusters[gid].n;
148  m_clusters[gid].sigma = sqrt(variances[gid] / m_clusters[gid].n);
149  variances[gid] = 0.0;
150  }
151 
152  //if (fabs(m_clusters[gid].mean - m_clusters[gid].new_mean) > convergenceThreshold )
153  if (m_clusters[gid].n != priorCounts[gid])
154  converged = false;
155 
156 // if (m_verbose)
157 // {
158 // cout<<"iteration: "<<iters<<endl;
159 // cout<<"cluster["<<gid<<"].mean = "<<m_clusters[gid].mean<<endl;
160 // cout<<"cluster["<<gid<<"].new_mean = "<<m_clusters[gid].new_mean<<endl;
161 // cout<<"cluster["<<gid<<"].sigma = "<<m_clusters[gid].sigma<<endl;
162 // cout<<"cluster["<<gid<<"].n = "<<(int)m_clusters[gid].n<<" prior: "<<priorCounts[gid]<<endl;
163 // cout<<"cluster["<<gid<<"].min = "<<m_clusters[gid].min<<endl;
164 // cout<<"cluster["<<gid<<"].max = "<<m_clusters[gid].max<<endl;
165 // cout << endl;
166 // }
167  if (m_clusters[gid].n)
168  m_clusters[gid].mean = m_clusters[gid].new_mean;
169 
170  if (!converged)
171  {
172  priorCounts[gid] = m_clusters[gid].n;
173  m_clusters[gid].n = 0;
174  m_clusters[gid].new_mean = 0;
175  }
176  }
177  } // End overall loop for convergence:
178 
179  if (m_verbose)
180  {
181  cout<<"\nossimKMeansClustering Summary ("<<iters<<" iterations):"<<endl;
182  for (ossim_uint32 gid=0; gid<numClusters; gid++)
183  {
184  cout<<"\n cluster["<<gid<<"] n = "<<(int)m_clusters[gid].n<<endl;
185  cout<<" mean = "<<m_clusters[gid].mean<<endl;
186  cout<<" sigma = "<<m_clusters[gid].sigma<<endl;
187  cout<<" min = "<<m_clusters[gid].min<<endl;
188  cout<<" max = "<<m_clusters[gid].max<<endl;
189  }
190  cout << endl;
191  }
192 
193  delete [] variances;
194  delete [] priorCounts;
195  m_clustersValid = true;
196  return true;
197 
198 }
#define OSSIM_DEFAULT_MAX_PIX_DOUBLE
#define OSSIM_DEFAULT_MIN_PIX_DOUBLE
os2<< "> n<< " > nendobj n
unsigned int ossim_uint32
std::vector< Cluster > m_clusters
#define max(a, b)
Definition: auxiliary.h:76
#define min(a, b)
Definition: auxiliary.h:75

◆ getCluster()

const ossimKMeansClustering::Cluster * ossimKMeansClustering::getCluster ( ossim_uint32  i) const

Definition at line 233 of file ossimKMeansClustering.cpp.

References m_clusters.

Referenced by ossimKMeansFilter::getTile(), and ossimKMeansFilter::saveState().

234 {
235  if (i >= m_clusters.size())
236  return 0;
237  return &(m_clusters[i]);
238 }
std::vector< Cluster > m_clusters

◆ getMaxValue()

double ossimKMeansClustering::getMaxValue ( ossim_uint32  groupId) const

Definition at line 224 of file ossimKMeansClustering.cpp.

References m_clusters, and ossim::nan().

225 {
226  if (clusterId >= m_clusters.size())
227  return ossim::nan();
228 
229  return m_clusters[clusterId].max;
230 }
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
std::vector< Cluster > m_clusters

◆ getMean()

double ossimKMeansClustering::getMean ( ossim_uint32  groupId) const

Definition at line 200 of file ossimKMeansClustering.cpp.

References m_clusters, and ossim::nan().

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

201 {
202  if (clusterId >= m_clusters.size())
203  return ossim::nan();
204 
205  return m_clusters[clusterId].mean;
206 }
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
std::vector< Cluster > m_clusters

◆ getMinValue()

double ossimKMeansClustering::getMinValue ( ossim_uint32  groupId) const

Definition at line 216 of file ossimKMeansClustering.cpp.

References m_clusters, and ossim::nan().

217 {
218  if (clusterId >= m_clusters.size())
219  return ossim::nan();
220 
221  return m_clusters[clusterId].min;
222 }
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
std::vector< Cluster > m_clusters

◆ getNumClusters()

ossim_uint32 ossimKMeansClustering::getNumClusters ( ) const
inline

Definition at line 50 of file ossimKMeansClustering.h.

Referenced by ossimKMeansFilter::computeKMeans().

50 { return m_clusters.size(); }
std::vector< Cluster > m_clusters

◆ getSigma()

double ossimKMeansClustering::getSigma ( ossim_uint32  groupId) const

Definition at line 208 of file ossimKMeansClustering.cpp.

References m_clusters, and ossim::nan().

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

209 {
210  if (clusterId >= m_clusters.size())
211  return ossim::nan();
212 
213  return m_clusters[clusterId].sigma;
214 }
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
std::vector< Cluster > m_clusters

◆ setNumClusters()

void ossimKMeansClustering::setNumClusters ( ossim_uint32  K)

Definition at line 30 of file ossimKMeansClustering.cpp.

References m_clusters, and m_clustersValid.

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

31 {
32  m_clusters.clear();
33  m_clusters.resize(K);
34  m_clustersValid = false;
35 }
std::vector< Cluster > m_clusters

◆ setPopulations()

template<class T >
void ossimKMeansClustering::setPopulations ( T *  populations,
ossim_uint32  num_entries 
)

Definition at line 81 of file ossimKMeansClustering.h.

References m_clustersValid, and m_populations.

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

83 {
84  if ((num_entries == 0) || (populations == 0))
85  return;
86 
87  m_clustersValid = false;
88  m_populations = new double[num_entries];
89  for (ossim_uint32 i=0; i<num_entries; i++)
90  m_populations[i] = (double) populations[i];
91 }
unsigned int ossim_uint32

◆ setSamples()

template<class T >
void ossimKMeansClustering::setSamples ( T *  samples,
ossim_uint32  num_entries 
)

Definition at line 69 of file ossimKMeansClustering.h.

References m_clustersValid, m_numEntries, and m_samples.

Referenced by ossimShorelineTool::autoComputeThreshold(), and ossimKMeansFilter::computeKMeans().

70 {
71  if ((num_entries == 0) || (samples == 0))
72  return;
73 
74  m_clustersValid = false;
75  m_numEntries = num_entries;
76  m_samples = new double[num_entries];
77  for (ossim_uint32 i=0; i<num_entries; i++)
78  m_samples[i] = (double) samples[i];
79 }
unsigned int ossim_uint32

◆ setVerbose()

void ossimKMeansClustering::setVerbose ( bool  v = true) const
inline

Definition at line 58 of file ossimKMeansClustering.h.

Referenced by ossimKMeansFilter::computeKMeans().

Member Data Documentation

◆ m_clusters

std::vector<Cluster> ossimKMeansClustering::m_clusters
private

◆ m_clustersValid

bool ossimKMeansClustering::m_clustersValid
private

Definition at line 65 of file ossimKMeansClustering.h.

Referenced by computeKmeans(), setNumClusters(), setPopulations(), and setSamples().

◆ m_numEntries

ossim_uint32 ossimKMeansClustering::m_numEntries
private

Definition at line 61 of file ossimKMeansClustering.h.

Referenced by computeKmeans(), and setSamples().

◆ m_populations

double* ossimKMeansClustering::m_populations
private

Definition at line 63 of file ossimKMeansClustering.h.

Referenced by computeKmeans(), setPopulations(), and ~ossimKMeansClustering().

◆ m_samples

double* ossimKMeansClustering::m_samples
private

Definition at line 62 of file ossimKMeansClustering.h.

Referenced by computeKmeans(), setSamples(), and ~ossimKMeansClustering().

◆ m_verbose

bool ossimKMeansClustering::m_verbose
mutableprivate

Definition at line 66 of file ossimKMeansClustering.h.

Referenced by computeKmeans().


The documentation for this class was generated from the following files: