Structural deformable models
SensorSet.cpp
Go to the documentation of this file.
1 #ifdef WIN32
2 #include <windows.h>
3 #endif
4 #include <iostream>
5 #include <fstream>
6 #include <typeinfo>
7 #include "SensorSet.h"
8 #include "SensorColl.h"
9 #include "mathutil.h"
10 #include "Fourier.h"
11 #include "DMatrixUtil.h"
12 using namespace std;
13 
14 static
16  float clampd, float cx, float cy);
17 
18 //-----------------------------------------------------------------------------
19 //class SmoothIntensitySensor
21 {
22  enableUpdate(UPD_SCALE|UPD_DATA);
23  togglePP(PP_FORCE);
24  setScale(_scale);
25 }
26 
28  if(!isModified()) return false;
29  if(source->getDim1Size()>0) {
30  if(m_SData.getSizeX() != source->getDim1Size() ||
31  m_SData.getSizeY() != source->getDim2Size()) {
32  m_SData.setSize(source->getDim1Size(), source->getDim2Size());
33  m_FData.setSize(Fourier2D::complexX(source->getDim1Size())/2,
34  source->getDim2Size());
35  m_FT.initTransform(m_SData.getSizeX(), m_SData.getSizeY(),
36  m_SData.getData(), (double*)m_FData.getData());
37  }
38  updateScale();
39  }
40  return PPSensor::performUpdate();
41 }
42 
44 {
46  if(m_FFilter.initialized() && m_FData.initialized()) {
47  m_SData.convertFrom(values);
48  m_FT.transform();
49  m_FData *= m_FFilter;
50  m_FT.transformInv();
51  values.convertFrom(m_SData);
52  //values = values.convolve(m_SFilter);
53  }
54 }
55 
57  assert(source->getDim1Size()>0);
58  bool nosizematch = !(m_SFilter.getSizeX() == source->getDim1Size() &&
59  m_SFilter.getSizeY() == source->getDim2Size());
60  if(isModified(UPD_SCALE) || nosizematch) {
61  unsetModified(UPD_SCALE);
62  if(nosizematch) {
63  m_SFilter.setSize(source->getDim1Size(), source->getDim2Size());
64  m_FFilter.setSize(Fourier2D::complexX(m_SFilter.getSizeX())/2,
65  m_SFilter.getSizeY());
66  m_FTflt.initTransform(m_SFilter.getSizeX(), m_SFilter.getSizeY(),
67  m_SFilter.getData(),
68  (double*)m_FFilter.getData());
69  }
70  float ffltsize = pow(2,scale);
71  int fltsize = (int)ffltsize;
72  if(fltsize<1) fltsize=1;
73  m_AddSkip = fltsize/2+1;
74  double stdev = ffltsize*0.5*0.2;
75  create2DGaussian(m_SFilter, stdev, ffltsize,
76  m_SFilter.getSizeX()/2.0f,m_SFilter.getSizeY()/2.0f);
77  m_FTflt.transform();
78 //normalize transform and perform shift
79  double factor = 1.0/m_SFilter.getSize();
80  double nfactor = -factor;
81  complex<double>* freq = m_FFilter.getData();
82  for(int j=0; j<m_FFilter.getSizeY(); j++) {
83  for(int i=0; i<m_FFilter.getSizeX(); i++, freq++) {
84  if((i+j)&0x01) *freq *= nfactor;
85  else *freq *= factor;
86  }
87  }
88  setModified(UPD_DATA);
89  }
90 }
91 
92 //--- CombiSensor ------------------------------------------------------
93 
95  : m_NormalizeInput(true)
96 {
97  setNSources(nchannels);
99  //togglePP(PP_FORCE);
100 }
101 
103 {
104  for(vector<sensor_ptr>::iterator s=sources.begin();
105  s!=sources.end(); s++)
106  {
107  (*s)->unrefSuperSensor( shared_from_this() );
108  }
109 }
110 
112 {
113  vector<sensor_ptr>::iterator s=sources.begin();
114  while(s!=sources.end()) {
115  (*s)->unrefSuperSensor( shared_from_this() );
116  s++;
117  }
118  sources.clear();
119  cweights.clear();
121 }
122 
124 {
125  if(n != (int)sources.size()) {
126  //clearSources();
127  sources.resize(n,(sensor_ptr)getZeroSensor());
128  cweights.resize(n, 1);
130  }
131 }
132 
133 void CombiSensor::setSource(sensor_ptr _source, float weight, int id)
134 {
135  assert(id>=0);
136  if(id>=(int)sources.size()) {
137  setNSources(id+1);
138  }
139  else if (sources[id] != 0 && sources[id] != getZeroSensor())
140  {
141  sources[id]->unrefSuperSensor( shared_from_this() );
142  }
143  sources[id] = _source;
144  cweights[id] = weight;
145  _source->refSuperSensor( shared_from_this() );
146  source = _source;
147  if(!std::const_pointer_cast<Sensor>(source)->isUpdate(UPD_MINMAX)) {
148  std::const_pointer_cast<Sensor>(source)->enableUpdate(UPD_MINMAX);
149  std::const_pointer_cast<Sensor>(source)->setModified(UPD_MINMAX);
150  }
152 }
153 
155 {
156  if(!_source) return;
157  const string& sid = _source->getID();
158  vector<sensor_ptr>::iterator s = sources.begin();
159  while(s!=sources.end() && (*s)->getID()!=sid)
160  s++;
161  if(s!=sources.end()) { // && sid == (*s)->getID()) { // use assert?
162  source = *s;
163  PPSensor::changeSource(_source);
164  *s = std::const_pointer_cast<Sensor>(source);
165  if(!std::const_pointer_cast<Sensor>(source)->isUpdate(UPD_MINMAX)) {
166  std::const_pointer_cast<Sensor>(source)->enableUpdate(UPD_MINMAX);
167  std::const_pointer_cast<Sensor>(source)->setModified(UPD_MINMAX);
168  }
169  } else {
170  TRACE("error replacing element <" << sid << "> in combi sensor - appending instead.");
171  print(cout) << endl;
172  setSource(std::const_pointer_cast<Sensor>(_source),1.f);
173  }
174 }
175 
176 /*
177  void CombiSensor::calcMinMax()
178  {
179  minval = 0;
180  maxval = 0;
181  for(vector<float>::const_iterator w = cweights.begin();
182  w != cweights.end(); w++) {
183  maxval += *w;
184  }
185  }
186 */
187 
189 {
190  if(&rhs != this) {
191  PPSensor::assign(rhs);
192  if(typeid(&rhs) == typeid(CombiSensor*)) {
193  const CombiSensor& crhs = (const CombiSensor&) rhs;
194  if(sources != crhs.sources) {
195  setNSources(crhs.sources.size());
196  int sid = 0;
197  const vector<float>& weights = crhs.getCWeights();
198  for(vector<sensor_ptr>::const_iterator s = crhs.sources.begin();
199  s != crhs.sources.end(); s++, sid++)
200  setSource(std::const_pointer_cast<Sensor>(*s), weights[sid], sid);
201  }
202  }
203  }
204  return *this;
205 }
206 
207 ostream& CombiSensor::print(ostream& os) const
208 {
209  os << "s " << getID() << " ";
210  //Sensor::print(os); would print modified source
211  if(m_NormalizeInput) os << "k";
212  else os << "K";
213  vector<float>::const_iterator w = cweights.begin();
214  for(vector<sensor_ptr>::const_iterator s=sources.begin();
215  s!=sources.end(); s++, w++)
216  {
217  os << " " << (*s)->getID() << " " << *w;
218  }
219  return os;
220 }
221 
222 ostream& CombiSensor::hprint(ostream &os, SensorCollection *sc) const
223 {
224  if(sc->isPrinted(m_ID)) return os;
225  for(vector<sensor_ptr>::const_iterator s=sources.begin();
226  s!=sources.end(); s++)
227  {
228  (*s)->hprint(os, sc);
229  }
230  if(sc->isPrinted(m_ID)) return os;
231  sc->setPrinted(m_ID);
232  return (print(os) << endl);
233 }
234 
235 //----------------------------------------------------------------------------
237 {
238  if(&rhs != this) {
239  PPSensor::assign(rhs);
240  if(typeid(&rhs) == typeid(MahalSensor*)) {
241  const MahalSensor& crhs = (const MahalSensor&) rhs;
242  m = crhs.m;
243  icov = crhs.icov;
244  m_Filename = crhs.m_Filename;
245  }
246  }
247  return *this;
248 }
249 
250 bool MahalSensor::loadConfig(const string& fname)
251 {
252  const string& fn = fname.empty() ? m_Filename : fname;
253  ifstream is(fn.c_str());
254  if(!is) return false;
255  is >> icov;
256  is >> m;
257  if(icov.sizeX() != 3 || icov.sizeY() != 3) {
258  icov = dmutil::makeIdentity<float>(3);
259  }
260  if(m.sizeX() != 1 || m.sizeY() != 3) {
261  m.resize(1,3,0);
262  }
263  if(!fname.empty()) m_Filename = fname;
264  return true;
265 }
266 
267 bool MahalSensor::saveConfig(const string& fname) const
268 {
269  const string& fn = fname.empty() ? m_Filename : fname;
270  ofstream os(fn.c_str());
271  if(!os) return false;
272  os << icov;
273  os << mean;
274  if(!fname.empty()) m_Filename = fname;
275  return true;
276 }
277 
278 //----------------------------------------------------------------------------
279 //keep consistent with enum MappingTypes!
280 const char* MappingSensor::s_MappingNames[] =
281 {"identity","clamplu","clampl","clampu","gaussnorm","mgaussnorm",
282  "mclampu", "bias", 0};
283 
285 {
286  if(&rhs != this) {
287  PPSensor::assign(rhs);
288  if(typeid(&rhs) == typeid(MappingSensor*)) {
289  const MappingSensor& crhs = (const MappingSensor&) rhs;
290  m_MappingID = crhs.m_MappingID;
291  m_Param = crhs.m_Param;
292  }
293  }
294  return *this;
295 }
296 
297 std::ostream& MappingSensor::print(std::ostream& os) const
298 {
299  Sensor::print(os)
300  << "f " << getMappingName();
301  for(vector<float>::const_iterator p=m_Param.begin(); p!=m_Param.end(); p++)
302  {
303  os << " " << *p;
304  }
305  return os;
306 }
307 
309 {
310  if(id>=MS_LAST) m_MappingID = 0; else m_MappingID = id;
311  return m_MappingID;
312 }
313 
314 dword MappingSensor::setMapping(const string& mname)
315 {
316  dword mid = 0;
317  while(mid < MS_LAST && mname != s_MappingNames[mid]) mid++;
318  return setMappingID(mid);
319 }
320 
321 bool MappingSensor::readParams(istream& is)
322 {
323  m_Param.clear();
324  is >> ws;
325  while(is) {
326  float para= -0.12347891f;
327  is >> para;
328  if(para != -0.12347891f) m_Param.push_back(para);
329  is >> ws;
330  }
331  dword psize = m_Param.size();
332  if((m_MappingID == MS_CLAMPL ||
333  m_MappingID == MS_CLAMPU ||
334  m_MappingID == MS_GAUSSNORM ||
335  m_MappingID == MS_MGAUSSNORM ||
336  m_MappingID == MS_MCLAMPU ||
337  m_MappingID == MS_BIAS)
338  && psize<1)
339  {
340  m_MappingID = MS_IDENTITY;
341  return false;
342  }
343  if(m_MappingID == MS_CLAMPLU && psize<2)
344  {
345  m_MappingID = MS_IDENTITY; return false;
346  }
347  return true;
348 }
349 
351  if(!isModified()) return false;
352  if(source->getDim1Size()>0) {
353  bool doanalysis = true;
354  switch(m_MappingID) {
355  case MS_MCLAMPU:
356  case MS_GAUSSNORM:
357  case MS_MGAUSSNORM:
358  case MS_BIAS:
359  if(m_Param.size() < 4) m_Param.resize(4);
360  m_Param[1] = m_Param[2] = m_Param[3] = 0.f;
361  break;
362  default:
363  doanalysis = false;
364  }
365  if(doanalysis) {
366  int i,j;
367  for(j=0; j<source->getDim2Size(); j++) {
368  for(i=0; i<source->getDim1Size(); i++)
369  {
370  float v = source->getValue(i,j);
371  switch(m_MappingID) {
372  case MS_BIAS:
373  case MS_GAUSSNORM:
374  m_Param[1] += v;
375  m_Param[2] += v*v;
376  m_Param[3]++;
377  break;
378  case MS_MCLAMPU:
379  case MS_MGAUSSNORM:
380  if(v>0) {
381  m_Param[1] += v;
382  m_Param[2] += v*v;
383  m_Param[3]++;
384  }
385  break;
386  }
387  }
388  }
389  switch(m_MappingID) {
390  case MS_MCLAMPU:
391  m_Param[1] /= m_Param[3];
392  m_Param[2] /= m_Param[3];
393  m_Param[2] = sqrt(m_Param[2]-m_Param[1]*m_Param[1]);
394  m_Param[1] = m_Param[1]+m_Param[2]*m_Param[0];
395  break;
396  case MS_BIAS:
397  case MS_GAUSSNORM:
398  m_Param[1] /= m_Param[3];
399  m_Param[2] /= m_Param[3];
400  m_Param[2] = sqrt(m_Param[2]-m_Param[1]*m_Param[1]);
401  m_Param[2] = 1/(m_Param[2]*m_Param[0]);
402  break;
403  case MS_MGAUSSNORM:
404  m_Param[1] /= m_Param[3];
405  m_Param[2] /= m_Param[3];
406  m_Param[2] = sqrt(m_Param[2]-m_Param[1]*m_Param[1]);
407  m_Param[2] = 1/(m_Param[2]*m_Param[0]);
408  m_Param[1] = m_Param[1] - (m_Param[1]/m_Param[2]);
409  break;
410  }
411  }
412  }
413  return PPSensor::performUpdate();
414 }
415 
416 //----------------------------------------------------------------------------
417 static
419  float clampd, float cx, float cy)
420 {
421  clampd = clampd*clampd;
422  int i,j;
423  double sum=0;
424  double* pixel = flt.getData();
425  int xsize=flt.getSizeX(), ysize=flt.getSizeY();
426  TRACE("creating filter " << xsize << " " << ysize);
427  for(j=0; j<ysize; j++)
428  for(i=0; i<xsize; i++, pixel++) {
429  float ii = (float)i-cx;
430  float jj = (float)j-cy;
431  float d2 = ii*ii+jj*jj;
432  if(d2<clampd) {
433  double value = gaussd2(d2, stdev);
434  *pixel = value;
435  sum += value;
436  }
437  }
438  flt *= (1.f/sum);
439  return flt;
440 }
void clearSources()
Definition: SensorSet.cpp:111
dword m_MappingID
Definition: SensorSet.h:420
int getSize() const
Definition: Image.h:44
std::ostream & hprint(std::ostream &os, SensorCollection *sc) const
Definition: SensorSet.cpp:222
bool isModified(dword mask=UPD_ALL) const
Definition: Sensor.h:108
Sensor & assign(const Sensor &rhs)
Definition: SensorSet.cpp:284
std::vector< sensor_ptr > sources
Definition: SensorSet.h:287
float gaussd2(float x2, double stdev)
Definition: mathutil.h:77
bool m_NormalizeInput
Definition: SensorSet.h:288
CombiSensor(int nchannels=0)
Definition: SensorSet.cpp:94
static Image< double > & create2DGaussian(Image< double > &flt, double stdev, float clampd, float cx, float cy)
Definition: SensorSet.cpp:418
virtual void changeSource(sensor_cptr _source)
Definition: Sensor.cpp:96
std::ostream & print(std::ostream &os) const
Definition: SensorSet.cpp:207
#define TRACE(msg)
Definition: common.h:14
STL namespace.
int getSizeX() const
Definition: Image.h:42
std::vector< float > cweights
multi-channel weights (&#39;color&#39;)
Definition: Sensor.h:174
bool readParams(std::istream &is)
Definition: SensorSet.cpp:321
Definition: Sensor.h:21
virtual void calcAllValues()
Definition: Sensor.cpp:262
bool performUpdate()
Definition: SensorSet.cpp:350
std::shared_ptr< Sensor > sensor_ptr
Definition: types_fwd.h:15
Sensor & assign(const Sensor &rhs)
Definition: SensorSet.cpp:188
virtual ~CombiSensor()
Definition: SensorSet.cpp:102
sensor_ptr getZeroSensor()
Definition: Sensor.cpp:234
const std::vector< float > & getCWeights() const
Definition: Sensor.h:97
std::ostream & print(std::ostream &os) const
Definition: SensorSet.cpp:297
void setNSources(int n)
Definition: SensorSet.cpp:123
bool isUpdate(dword udMask) const
Definition: Sensor.h:112
void setPrinted(const std::string &id)
Definition: SensorColl.cpp:80
static const char * s_MappingNames[]
Definition: SensorSet.h:383
void enableUpdate(dword udMask)
Definition: Sensor.h:113
bool saveConfig(const std::string &fname="") const
Definition: SensorSet.cpp:267
DMatrix< T > sum(const DMatrix< T > &mat)
Definition: DMatrixUtil.h:59
Sensor & assign(const Sensor &rhs)
Definition: Sensor.cpp:324
DMatrix< float > icov
Definition: SensorSet.h:355
unsigned long dword
Definition: simpletypes.h:6
dword setMapping(const std::string &mname)
Definition: SensorSet.cpp:314
SmoothIntensitySensor(float _scale=0)
Definition: SensorSet.cpp:20
virtual bool performUpdate()
Definition: Sensor.cpp:306
bool isPrinted(const std::string &id) const
Definition: SensorColl.cpp:75
std::string m_Filename
Definition: SensorSet.h:356
void changeSource(sensor_cptr _source)
Definition: SensorSet.cpp:154
const T * getData() const
Definition: Image.h:39
bool loadConfig(const std::string &fname="")
Definition: SensorSet.cpp:250
float mean
Definition: Sensor.h:177
std::shared_ptr< const Sensor > sensor_cptr
Definition: types_fwd.h:17
int complexX() const
Definition: Fourier.h:15
DMatrix< T > stdev(const DMatrix< T > &mat)
Definition: DMatrixUtil.h:106
std::string m_ID
Definition: Sensor.h:181
DMatrix< float > m
Definition: SensorSet.h:355
std::vector< float > m_Param
Definition: SensorSet.h:421
Sensor & assign(const Sensor &rhs)
Definition: SensorSet.cpp:236
void setSource(sensor_ptr _source, float weight, int id)
Definition: SensorSet.cpp:133
const std::string & getID() const
Definition: Sensor.h:128
sensor_cptr source
Definition: Sensor.h:170
float stdev
overall mean and stdev
Definition: Sensor.h:177
dword setMappingID(dword id)
Definition: SensorSet.cpp:308
void setModified(dword mask=UPD_ALL)
Definition: Sensor.h:110
virtual std::ostream & print(std::ostream &os) const
Definition: Sensor.cpp:213
DMatrix< T > & sqrt(DMatrix< T > &mat)
Definition: DMatrixUtil.h:81
int getSizeY() const
Definition: Image.h:43