MachineIntelligenceCore:Visualization
WindowGrayscaleBatch.hpp
Go to the documentation of this file.
1 
25 #ifndef WINDOWGRAYSCALEBATCH_H_
26 #define WINDOWGRAYSCALEBATCH_H_
27 
30 
31 // Dependencies on core types.
32 #include <types/MNISTTypes.hpp>
33 
34 namespace mic {
35 namespace opengl {
36 namespace visualization {
37 
42 class Grayscale {
43 public:
44 
49  Norm_None, //< Display original image(s), without any normalization (negative values simply won't be visible).
50  Norm_Positive, //< Display image(s) normalized to <0,1>.
51  Norm_HotCold, //< Display image(s) in a hot-cold normalization <-1,1> i.e. red are positive and blue are negative values.
52  Norm_TensorFLow //< Display image(s) in a inverted hot-cold normalization <-1,1> i.e. red are negative and blue are positive values.
53  };
54 
58  std::string norm2str(Normalization norm_)
59  {
60  switch(norm_) {
61  case(Norm_None):
62  return "Display original image(s), without any normalization";
63  case(Norm_Positive):
64  return "Display image(s) normalized to <0,1>";
65  case(Norm_HotCold):
66  return "Display image(s) in a hot-cold normalization <-1,1> i.e. red are positive and blue are negative";
67  case(Norm_TensorFLow):
68  return "Display inverted hot-cold normalization <-1,1> i.e. red are negative and blue are positive";
69  }
70  return "UNDEFINED";
71  }
72 
76  enum Grid {
77  Grid_None, //< No grid
78  Grid_Sample, //< Display only grid dividing sample cells.
79  Grid_Batch, //< Display grid dividing samples.
80  Grid_Both //< Display both sample and batch grids.
81  };
82 
86  std::string grid2str(Grid grid_)
87  {
88  switch(grid_) {
89  case(Grid_None):
90  return "Display no grid";
91  case(Grid_Sample):
92  return "Display only grid dividing sample cells";
93  case(Grid_Batch):
94  return "Display grid dividing samples";
95  case(Grid_Both):
96  return "Display both sample and batch grids";
97  }
98  return "UNDEFINED";
99  }
100 
101 };
102 
108 template <typename eT=float>
109 class WindowGrayscaleBatch: public Window, public Grayscale {
110 public:
111 
115  WindowGrayscaleBatch(std::string name_ = "WindowGrayscaleBatch",
116  Normalization normalization_ = Norm_None, Grid grid_ = Grid_Batch,
117  unsigned int position_x_ = 0, unsigned int position_y_ = 0,
118  unsigned int width_ = 512,unsigned int height_ = 512,
119  bool draw_batch_grid_ = true, bool draw_sample_grid_ = false) :
120  Window(name_, position_x_, position_y_, width_, height_),
121  normalization(normalization_ ),
122  grid(grid_)
123  {
124  // Register additional key handler.
125  REGISTER_KEY_HANDLER('n', "n - toggles normalization mode", &WindowGrayscaleBatch<eT>::keyhandlerToggleNormalizationMode);
126  REGISTER_KEY_HANDLER('g', "g - toggles grid mode", &WindowGrayscaleBatch<eT>::keyhandlerGridMode);
127  }
128 
132  virtual ~WindowGrayscaleBatch() { }
133 
138  // Enter critical section.
139  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
141  LOG(LINFO) << norm2str(normalization);
142  // End of critical section.
143  }
144 
148  void keyhandlerGridMode(void) {
149  // Enter critical section.
150  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
151  grid = (Grid)((grid + 1) % 4);
152  LOG(LINFO) << grid2str(grid);
153  // End of critical section.
154  }
155 
159  void displayHandler(void){
160  LOG(LTRACE) << "WindowGrayscaleBatch::Display handler of window " << glutGetWindow();
161  // Enter critical section.
162  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
163 
164  // Clear buffer.
165  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
166  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
167 
168  // Draw batch - vector of 2d matrices.
169  if (batch_data.size() > 0){
170  // Calculate batch "dimensions".
171  size_t batch_width = ceil(sqrt(batch_data.size()));
172  size_t batch_height = ceil((eT)batch_data.size()/batch_width);
173 
174  // Get vector.
175  //auto batch_data = batch_ptr->data();
176 
177  // Get image sizes.
178  size_t rows = batch_data[0]->rows();
179  size_t cols = batch_data[0]->cols();
180 
181  // Set opengl scale related variables.
182  eT scale_x = (eT)glutGet(GLUT_WINDOW_WIDTH)/(eT)(cols * batch_width);
183  eT scale_y = (eT)glutGet(GLUT_WINDOW_HEIGHT)/(eT)(rows * batch_height);
184 
185  // Iterate through batch elements.
186  for (size_t by=0; by < batch_height; by++)
187  for (size_t bx=0; bx < batch_width; bx++) {
188  // Check if we do not excess size.
189  if ((by*batch_width + bx) >= batch_data.size())
190  break;
191  // Get pointer to a given image.
192  eT* data_ptr = batch_data[by*batch_width + bx]->data();
193 
194  // Calculate mins and max - for visualization.
195  eT min = std::numeric_limits<double>::max();
196  eT max = std::numeric_limits<double>::min();
197  // Find min and max.
198  for(size_t i=0; i< rows*cols; i++) {
199  min = (min > data_ptr[i]) ? data_ptr[i] : min;
200  max = (max < data_ptr[i]) ? data_ptr[i] : max;
201  }//: for
202  // Check whether we can normalize.
203  eT diff = max - min;
204  if (diff == 0.0f) {
205  min = max = 0.0;
206  diff = 1.0f;
207  }
208 
209  //eT ultimate_max= (max > -min) ? max : -min;
210 
211  // Iterate through matrix elements.
212  for (size_t y = 0; y < rows; y++) {
213  for (size_t x = 0; x < cols; x++) {
214  // Get value - REVERSED! as Eigen::Matrix by default is column-major!!
215  eT val = data_ptr[x*rows + y];
216  eT red, green, blue, alpha;
217 
218  // Color depending on the visualization.
219  switch(normalization) {
220  case Normalization::Norm_Positive:
221  red = green = blue = (val - min)/diff;
222  alpha = 1.0f;
223  break;
224  case Normalization::Norm_HotCold:
225  red = (val > 0.0) ? val/max : 0.0f;
226  green = 0.0f;
227  blue = (val < 0.0) ? val/min : 0.0f;
228  alpha = 1.0f;
229  break;
230  case Normalization::Norm_TensorFLow:
231  blue = (val > 0.0) ? val/max : 0.0f;
232  green = 0.0f;
233  red = (val < 0.0) ? val/min : 0.0f;
234  alpha = 1.0f;
235  break;
236  // None is default.
237  case Normalization::Norm_None:
238  default:
239  red = green = blue = alpha = val/diff;
240  break;
241  }//: switch
242 
243  // Draw rectangle - (x, y, height, width, color)!!
244  draw_filled_rectangle(eT(bx*cols+x) * scale_x, eT(by*rows+y) * scale_y, scale_y, scale_x,
245  red, green, blue, alpha);
246 
247  }//: for
248  }//: for
249 
250  }//: for images in batch
251 
252  // Draw grids dividing the cells and batch samples.
253  switch(grid) {
254  case Grid::Grid_Sample :
255  draw_grid(0.3f, 0.8f, 0.3f, 0.3f, batch_width * cols, batch_height * rows);
256  break;
257  case Grid::Grid_Batch:
258  draw_grid(0.3f, 0.8f, 0.3f, 0.3f, batch_width, batch_height, 4.0);
259  break;
260  case Grid::Grid_Both:
261  draw_grid(0.3f, 0.8f, 0.3f, 0.3f, batch_width * cols, batch_height * rows);
262  draw_grid(0.3f, 0.8f, 0.3f, 0.3f, batch_width, batch_height, 4.0);
263  break;
264  // None is default.
265  case Grid::Grid_None:
266  default:
267  break;
268  }//: switch
269  }//: if !null
270 
271  // Swap buffers.
272  glutSwapBuffers();
273 
274  // End of critical section.
275  }
276 
277 
282  void setSampleSynchronized(mic::types::MatrixPtr<eT> sample_ptr_) {
283  // Enter critical section.
284  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
285 
286  // Clear - just in case.
287  batch_data.clear();
288  // Add sample.
289  batch_data.push_back(sample_ptr_);
290 
291  // End of critical section.
292  }
293 
298  void setSampleUnsynchronized(mic::types::MatrixPtr<eT> sample_ptr_) {
299  // Clear - just in case.
300  batch_data.clear();
301  // Add sample.
302  batch_data.push_back(sample_ptr_);
303  }
308  void setBatchSynchronized(std::vector <std::shared_ptr<mic::types::Matrix<eT> > > & batch_data_) {
309  // Enter critical section.
310  APP_DATA_SYNCHRONIZATION_SCOPED_LOCK();
311 
312  batch_data = batch_data_;
313 
314  // End of critical section.
315  }
316 
321  void setBatchUnsynchronized(std::vector <std::shared_ptr<mic::types::Matrix<eT> > > & batch_data_) {
322  batch_data = batch_data_;
323  }
324 
325 
326 private:
327 
331  std::vector <std::shared_ptr<mic::types::Matrix<eT> > > batch_data;
332 
335 
338 };
339 
340 } /* namespace visualization */
341 } /* namespace opengl */
342 } /* namespace mic */
343 
344 #endif /* WINDOWGRAYSCALEBATCH_H_ */
Grid grid
Flag determining whether or what kind of grid to draw.
OpenGL-based window responsible for displaying grayscale (singlechannel) batch in a window...
void draw_filled_rectangle(float x, float y, float h, float w, float r, float g, float b, float a)
void setSampleUnsynchronized(mic::types::MatrixPtr< eT > sample_ptr_)
Normalization normalization
Flag determining whether or what kind of normalization to use.
void setBatchUnsynchronized(std::vector< std::shared_ptr< mic::types::Matrix< eT > > > &batch_data_)
std::string norm2str(Normalization norm_)
void setBatchSynchronized(std::vector< std::shared_ptr< mic::types::Matrix< eT > > > &batch_data_)
WindowGrayscaleBatch(std::string name_="WindowGrayscaleBatch", Normalization normalization_=Norm_None, Grid grid_=Grid_Batch, unsigned int position_x_=0, unsigned int position_y_=0, unsigned int width_=512, unsigned int height_=512, bool draw_batch_grid_=true, bool draw_sample_grid_=false)
Contains declaration of parent class of all OpenGL-based windows.
Parent class of all OpenGL-based windows (abstract).
Definition: Window.hpp:51
std::vector< std::shared_ptr< mic::types::Matrix< eT > > > batch_data
Class containing enumerators used in grayscale windows.
void draw_grid(float r, float g, float b, float a, float cells_h, float cells_v, float line_width_=1.0)
Declaration of WindowManager class along with a bunch of helpful types and macros.
void setSampleSynchronized(mic::types::MatrixPtr< eT > sample_ptr_)