ovpCBoxAlgorithmCommonClassifierListener.inl 16.4 KB
Newer Older
1
2
3
4
#ifndef __OpenViBEPlugins_BoxAlgorithm_CommonClassifierListener_INL__
#define __OpenViBEPlugins_BoxAlgorithm_CommonClassifierListener_INL__

#include "../ovp_defines.h"
5
#include "../algorithms/ovpCAlgorithmClassifierOneVsOne.h"
6
7
8
9
10
11
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
Serrière Guillaume's avatar
Serrière Guillaume committed
12
#include <iostream>
13

14
// #define OV_DEBUG_CLASSIFIER_LISTENER
15
16
17
18
19
20
21

#ifdef OV_DEBUG_CLASSIFIER_LISTENER
#define DEBUG_PRINT(x) x
#else
#define DEBUG_PRINT(x) 
#endif

22
23
24
25
26
27
28
29
30
namespace OpenViBEPlugins
{
	namespace Classification
	{
		class CBoxAlgorithmCommonClassifierListener : public OpenViBEToolkit::TBoxListener < OpenViBE::Plugins::IBoxListener >
		{
		public:

			CBoxAlgorithmCommonClassifierListener(const OpenViBE::uint32 ui32CustomSettingBase)
31
32
33
34
35
36
				:m_oClassifierClassIdentifier(OV_UndefinedIdentifier),
				  m_oStrategyClassIdentifier(0x0),//OV_UndefinedIdentifier is already use for the native, We initialize to an unused identifier in the strategy list
				  m_pClassifier(NULL),
				  m_pStrategy(NULL),
				  m_ui32CustomSettingBase(ui32CustomSettingBase),
				  m_i32StrategyAmountSettings(-1)
37
38
39
40
41
			{
			}

			virtual OpenViBE::boolean initialize(void)
			{
42
				//Even if everything should have been set in constructor, we still set everything in initialize (in case of)
43
44
				m_oClassifierClassIdentifier=OV_UndefinedIdentifier;
				m_pClassifier=NULL;
Serrière Guillaume's avatar
Serrière Guillaume committed
45

46
47
				//OV_UndefinedIdentifier is already use for the native, We initialize to an unused identifier in the strategy list
				m_oStrategyClassIdentifier=0x0;
Serrière Guillaume's avatar
Serrière Guillaume committed
48
49
				m_pStrategy = NULL;

Serrière Guillaume's avatar
Serrière Guillaume committed
50
51
				//This value means that we need to calculate it
				m_i32StrategyAmountSettings = -1;
52
53
54
55
56
57
58
59
60
61
62
				return true;
			}

			virtual OpenViBE::boolean uninitialize(void)
			{
				if(m_pClassifier)
				{
					m_pClassifier->uninitialize();
					this->getAlgorithmManager().releaseAlgorithm(*m_pClassifier);
					m_pClassifier=NULL;
				}
Serrière Guillaume's avatar
Serrière Guillaume committed
63
				if(m_pStrategy)
64
				{
Serrière Guillaume's avatar
Serrière Guillaume committed
65
66
67
					m_pStrategy->uninitialize();
					this->getAlgorithmManager().releaseAlgorithm(*m_pStrategy);
					m_pStrategy=NULL;
68
69
70
71
				}
				return true;
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
			virtual OpenViBE::boolean initializedStrategy(OpenViBE::Kernel::IBox& rBox)
			{
				OpenViBE::CString l_sStrategyName;
				rBox.getSettingName(getStrategyIndex()+1, l_sStrategyName);
				if(l_sStrategyName == OpenViBE::CString(c_sPairwiseStrategyEnumerationName))
				{
					m_i32StrategyAmountSettings = 1;
				}
				else
				{
					m_i32StrategyAmountSettings = 0;
				}

				return true;
			}

//			virtual OpenViBE::boolean onAlgorithmClassIdentifierChanged(OpenViBE::Kernel::IBox &rBox)
//			{
//				this->initializedStrategy(rBox);
//				return true;
//			}

			virtual OpenViBE::int32 getStrategySettingsCount(OpenViBE::Kernel::IBox& rBox)
			{
96
				if(m_i32StrategyAmountSettings < 0)//The value have never been initialized
Serrière Guillaume's avatar
Serrière Guillaume committed
97
98
99
100
101
102
				{
					initializedStrategy(rBox);
				}
				return m_i32StrategyAmountSettings;
			}

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
			virtual OpenViBE::boolean onInputAddedOrRemoved(OpenViBE::Kernel::IBox& rBox)
			{
				rBox.setInputType(0, OV_TypeId_Stimulations);
				rBox.setInputName(0, "Stimulations");
				for(OpenViBE::uint32 i=1; i<rBox.getInputCount(); i++)
				{
					char l_sBuffer[1024];
					sprintf(l_sBuffer, "Features for class %i", i);
					rBox.setInputName(i, l_sBuffer);
					rBox.setInputType(i, OV_TypeId_FeatureVector);
				}
				return true;
			}

			virtual OpenViBE::boolean onInputAdded(OpenViBE::Kernel::IBox& rBox, const OpenViBE::uint32 ui32Index)
			{
119
				//ui32Index represent the number of the class (because of rejected offset)
120
121
122
123
				char l_sBuffer[64];
				sprintf(l_sBuffer, "Class %d label", ui32Index);
				char l_sStimulation[64];
				sprintf(l_sStimulation, "OVTK_StimulationId_Label_%02X", ui32Index);
Serrière Guillaume's avatar
Serrière Guillaume committed
124
				rBox.addSetting(l_sBuffer, OV_TypeId_Stimulation, l_sStimulation, 3 - 1 + getStrategySettingsCount(rBox) + ui32Index);
125
126

				//Rename input
127
128
129
130
131
				return this->onInputAddedOrRemoved(rBox);
			}

			virtual OpenViBE::boolean onInputRemoved(OpenViBE::Kernel::IBox& rBox, const OpenViBE::uint32 ui32Index)
			{
132
				//First remove the removed input from settings
Serrière Guillaume's avatar
Serrière Guillaume committed
133
				rBox.removeSetting(3 - 1 + getStrategySettingsCount(rBox) + ui32Index);
134
135
136
137
138
139

				//Then rename the remains inputs in settings
				for(OpenViBE::uint32 i=1 ; i<rBox.getInputCount() ; ++i)
				{
					char l_sBuffer[64];
					sprintf(l_sBuffer, "Class %d label", i);
Serrière Guillaume's avatar
Serrière Guillaume committed
140
					rBox.setSettingName(3 - 1 + getStrategySettingsCount(rBox) + i, l_sBuffer);
141
142
143
				}

				//Then rename input
144
145
146
				return this->onInputAddedOrRemoved(rBox);
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
147
148


149
150
			virtual OpenViBE::boolean onInitialized(OpenViBE::Kernel::IBox& rBox)
			{
Serrière Guillaume's avatar
Serrière Guillaume committed
151
152
153
154
				//We need to know if the box is already initialized (can be called after a restore state)
				OpenViBE::CString l_sStrategyName;
				rBox.getSettingName(getStrategyIndex()+2, l_sStrategyName);//this one is a class label
				std::string l_sSettingName(l_sStrategyName.toASCIIString());
155

156
				if(l_sSettingName.find("Class ") == std::string::npos)//We haven't initialized the box so let's do it
157
				{
Serrière Guillaume's avatar
Serrière Guillaume committed
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
					//Now added Settings for classes
					for(OpenViBE::uint32 i = 1 ; i< rBox.getInputCount() ; ++i)
					{
						char l_sBuffer[64];
						sprintf(l_sBuffer, "Class %d label", i);
						char l_sStimulation[64];
						sprintf(l_sStimulation, "OVTK_StimulationId_Label_%02X", i);
						rBox.addSetting(l_sBuffer, OV_TypeId_Stimulation, l_sStimulation, 3 - 1 + getStrategySettingsCount(rBox) + i);
						DEBUG_PRINT(std::cout << "Add setting (type D) " << l_sBuffer << " " << l_sStimulation << "\n";)
					}
					return this->onAlgorithmClassifierChanged(rBox);
				}
				else
				{
					return true;
173
				}
Serrière Guillaume's avatar
Serrière Guillaume committed
174
175
176
				//return this->onAlgorithmClassifierChanged(rBox);
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
177
			//Return the index of the combo box used to select the strategy (native/ OnevsOne...)
Serrière Guillaume's avatar
Serrière Guillaume committed
178
179
180
181
182
			virtual OpenViBE::uint32 getStrategyIndex()
			{
				return 2;
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
183
			//Return the index of the combo box used to select the classification algorithm
Serrière Guillaume's avatar
Serrière Guillaume committed
184
185
186
			virtual OpenViBE::uint32 getClassifierIndex(OpenViBE::Kernel::IBox& rBox)
			{
				return getStrategySettingsCount(rBox) + 3 + rBox.getInputCount() - 1;
187
188
189
190
			}

			virtual OpenViBE::boolean onSettingValueChanged(OpenViBE::Kernel::IBox& rBox, const OpenViBE::uint32 ui32Index)
			{
Serrière Guillaume's avatar
Serrière Guillaume committed
191
				if(ui32Index == getClassifierIndex(rBox)){
192
193
					return this->onAlgorithmClassifierChanged(rBox);
				}
Serrière Guillaume's avatar
Serrière Guillaume committed
194
				else if(ui32Index == getStrategyIndex()){
Serrière Guillaume's avatar
Serrière Guillaume committed
195
196
					return this->onStrategyChanged(rBox);
				}
197
198
				else
					return true;
199
200
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
201

202
			virtual OpenViBE::boolean updateDecision(OpenViBE::Kernel::IBox& rBox){
Serrière Guillaume's avatar
Serrière Guillaume committed
203
				OpenViBE::uint32 i=getStrategyIndex() + 1;
204
205
206
				if(m_oStrategyClassIdentifier == OVP_ClassId_Algorithm_ClassifierOneVsOne){
					OpenViBE::CIdentifier l_oEnum = getAvailableDecisionEnumeration(m_oClassifierClassIdentifier);
					if(l_oEnum == OV_UndefinedIdentifier){
207
						this->getLogManager() << OpenViBE::Kernel::LogLevel_Error << "Unable to find Pairwise Decision for the algorithm" << m_oClassifierClassIdentifier.toString() << "\n";
208
209
210
211
212
213
214
						return false;
					}
					else
					{
						OpenViBE::Kernel::IParameter* l_pParameter=m_pStrategy->getInputParameter(OVP_Algorithm_OneVsOneStrategy_InputParameterId_DecisionType);
						OpenViBE::Kernel::TParameterHandler < OpenViBE::uint64 > ip_ui64Parameter(l_pParameter);

215
216
						OpenViBE::CString l_sEnumTypeName=this->getTypeManager().getTypeName(l_oEnum);
						OpenViBE::uint64 l_ui64EnumValue = ip_ui64Parameter;
217
						OpenViBE::uint64 l_ui64EnumIndex;
218
						OpenViBE::CString l_sEnumValue;
219
220
221
222

						rBox.getSettingValue(i, l_sEnumValue);

						OpenViBE::uint64 l_ui64OldId = this->getTypeManager().getEnumerationEntryValueFromName(l_oEnum, l_sEnumValue);
223
						if(l_ui64OldId == OV_UndefinedIdentifier)//The previous strategy does not exists in the new enum, let's switch to the default value (the first)
224
						{
225
							l_ui64EnumIndex = 0;
226
227
						}
						else
228
						{
229
							l_ui64EnumIndex = l_ui64OldId;
230
						}
231

232
233
234
						this->getTypeManager().getEnumerationEntry(l_oEnum, l_ui64EnumIndex, l_sEnumValue, l_ui64EnumValue);
						ip_ui64Parameter = l_ui64EnumValue;

235
236
237
						rBox.setSettingType(i, l_oEnum);
						rBox.setSettingName(i, l_sEnumTypeName);
						rBox.setSettingValue(i, l_sEnumValue);
238
239
240
241
242
					}
				}
				return true;
			}

Serrière Guillaume's avatar
Serrière Guillaume committed
243
244
245
246
			virtual OpenViBE::boolean onStrategyChanged(OpenViBE::Kernel::IBox& rBox)
			{
				OpenViBE::CString l_sStrategyName;
				OpenViBE::CIdentifier l_oStrategyIdentifier;
247
				// OpenViBE::CIdentifier l_oOldStrategyIdentifier=m_oStrategyClassIdentifier;
Serrière Guillaume's avatar
Serrière Guillaume committed
248

Serrière Guillaume's avatar
Serrière Guillaume committed
249
				rBox.getSettingValue(getStrategyIndex(), l_sStrategyName);
Serrière Guillaume's avatar
Serrière Guillaume committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

				l_oStrategyIdentifier=this->getTypeManager().getEnumerationEntryValueFromName(OVTK_TypeId_ClassificationStrategy, l_sStrategyName);
				if(l_oStrategyIdentifier != m_oStrategyClassIdentifier)
				{
					if(m_pStrategy)
					{
						m_pStrategy->uninitialize();
						this->getAlgorithmManager().releaseAlgorithm(*m_pStrategy);
						m_pStrategy=NULL;
						m_oStrategyClassIdentifier=OV_UndefinedIdentifier;
					}
					if(l_oStrategyIdentifier != OV_UndefinedIdentifier)
					{
						m_pStrategy=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(l_oStrategyIdentifier));
						m_pStrategy->initialize();
						m_oStrategyClassIdentifier=l_oStrategyIdentifier;
					}

268
269
					// std::cout << m_ui32StrategyAmountSettings << std::endl;
					for(OpenViBE::uint32 i = getStrategyIndex() + getStrategySettingsCount(rBox) ; i > getStrategyIndex() ; --i)
Serrière Guillaume's avatar
Serrière Guillaume committed
270
					{
271
272
						DEBUG_PRINT(std::cout << "Remove pairing strategy setting at idx " << i-1 << "\n";)
						rBox.removeSetting(i);
Serrière Guillaume's avatar
Serrière Guillaume committed
273
					}
Serrière Guillaume's avatar
Serrière Guillaume committed
274
					m_i32StrategyAmountSettings = 0;
Serrière Guillaume's avatar
Serrière Guillaume committed
275
276
277
278
279
280
281
282
				}
				else//If we don't change the strategy we just have to return
				{
					return true;
				}

				if(m_pStrategy)
				{
283
					OpenViBE::CString l_sClassifierName;
Serrière Guillaume's avatar
Serrière Guillaume committed
284
					rBox.getSettingValue(getClassifierIndex(rBox), l_sClassifierName);
285
286
					OpenViBE::CIdentifier l_oClassifierIdentifier=this->getTypeManager().getEnumerationEntryValueFromName(OVTK_TypeId_ClassificationAlgorithm, l_sClassifierName);

Serrière Guillaume's avatar
Serrière Guillaume committed
287
					OpenViBE::uint32 i=getStrategyIndex() + 1;
288
289
290
291
292
293
294
					if(m_oStrategyClassIdentifier == OVP_ClassId_Algorithm_ClassifierOneVsOne){
						OpenViBE::CIdentifier l_oEnum = getAvailableDecisionEnumeration(l_oClassifierIdentifier);
						if(l_oEnum == OV_UndefinedIdentifier){
							this->getLogManager() << OpenViBE::Kernel::LogLevel_Error << "Unable to find Pariwise Decision for the algorithm " << m_oClassifierClassIdentifier.toString() << "\n";
							return false;
						}
						else
Serrière Guillaume's avatar
Serrière Guillaume committed
295
						{
296
							//As we just switch to this strategy, we take the default value set in the strategy to initialize the value
297
							OpenViBE::Kernel::IParameter* l_pParameter=m_pStrategy->getInputParameter(OVP_Algorithm_OneVsOneStrategy_InputParameterId_DecisionType);
Serrière Guillaume's avatar
Serrière Guillaume committed
298
							OpenViBE::Kernel::TParameterHandler < OpenViBE::uint64 > ip_ui64Parameter(l_pParameter);
299
300
							OpenViBE::uint64 l_ui64EnumValue = ip_ui64Parameter;
							OpenViBE::CString l_sEnumName;
301
							l_sEnumName = this->getTypeManager().getEnumerationEntryNameFromValue(l_oEnum, l_ui64EnumValue);
302

303
							OpenViBE::CString l_sParameterName=this->getTypeManager().getTypeName(l_oEnum);
Serrière Guillaume's avatar
Serrière Guillaume committed
304

305
306
307
							DEBUG_PRINT(std::cout << "Adding setting (case C) " << l_sParameterName << " : '" << l_sEnumName << "' to index " << i << "\n";)
							rBox.addSetting(l_sParameterName, l_oEnum, l_sEnumName, i);

Serrière Guillaume's avatar
Serrière Guillaume committed
308
							m_i32StrategyAmountSettings = 1;
Serrière Guillaume's avatar
Serrière Guillaume committed
309
310
311
312
313
314
315
						}
					}
				}

				return true;
			}

316
317
318
319
320
321
			virtual OpenViBE::boolean onAlgorithmClassifierChanged(OpenViBE::Kernel::IBox& rBox)
			{
				OpenViBE::CString l_sClassifierName;
				OpenViBE::CIdentifier l_oClassifierIdentifier;
				OpenViBE::CIdentifier l_oIdentifier;

Serrière Guillaume's avatar
Serrière Guillaume committed
322
				rBox.getSettingValue(getClassifierIndex(rBox), l_sClassifierName);
323
				l_oClassifierIdentifier=this->getTypeManager().getEnumerationEntryValueFromName(OVTK_TypeId_ClassificationAlgorithm, l_sClassifierName);
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
				if(l_oClassifierIdentifier != m_oClassifierClassIdentifier)
				{
					if(m_pClassifier)
					{
						m_pClassifier->uninitialize();
						this->getAlgorithmManager().releaseAlgorithm(*m_pClassifier);
						m_pClassifier=NULL;
						m_oClassifierClassIdentifier=OV_UndefinedIdentifier;
					}
					if(l_oClassifierIdentifier != OV_UndefinedIdentifier)
					{
						m_pClassifier=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(l_oClassifierIdentifier));
						m_pClassifier->initialize();
						m_oClassifierClassIdentifier=l_oClassifierIdentifier;
					}

340
341
					//Disable the graphical refresh to avoid abusive redraw (not really a problem)
					while(rBox.getSettingCount()>=m_ui32CustomSettingBase+rBox.getInputCount() + getStrategySettingsCount(rBox))
342
					{
343
						rBox.removeSetting(getClassifierIndex(rBox)+1);
344
345
					}
				}
346
347
348
349
				else//If we don't change the algorithm we just have to return
				{
					return true;
				}
350
351
352

				if(m_pClassifier)
				{
Serrière Guillaume's avatar
Serrière Guillaume committed
353
					OpenViBE::uint32 i=getClassifierIndex(rBox) + 1;
354
					while((l_oIdentifier=m_pClassifier->getNextInputParameterIdentifier(l_oIdentifier))!=OV_UndefinedIdentifier)
355
					{
356
357
358
						if((l_oIdentifier!=OVTK_Algorithm_Classifier_InputParameterId_FeatureVector)
						&& (l_oIdentifier!=OVTK_Algorithm_Classifier_InputParameterId_FeatureVectorSet)
						&& (l_oIdentifier!=OVTK_Algorithm_Classifier_InputParameterId_Configuration)
359
						&& (l_oIdentifier!=OVTK_Algorithm_Classifier_InputParameterId_NumberOfClasses)
360
						&& (l_oIdentifier!=OVTK_Algorithm_Classifier_InputParameterId_ExtraParameter))
361
						{
362
363
364
365
366
367
368
369
370
371
372
							OpenViBE::CIdentifier l_oTypeIdentifier;
							OpenViBE::CString l_sParameterName=m_pClassifier->getInputParameterName(l_oIdentifier);
							OpenViBE::Kernel::IParameter* l_pParameter=m_pClassifier->getInputParameter(l_oIdentifier);
							OpenViBE::Kernel::TParameterHandler < OpenViBE::int64 > ip_i64Parameter(l_pParameter);
							OpenViBE::Kernel::TParameterHandler < OpenViBE::uint64 > ip_ui64Parameter(l_pParameter);
							OpenViBE::Kernel::TParameterHandler < OpenViBE::float64 > ip_f64Parameter(l_pParameter);
							OpenViBE::Kernel::TParameterHandler < OpenViBE::boolean > ip_bParameter(l_pParameter);
							OpenViBE::Kernel::TParameterHandler < OpenViBE::CString* > ip_sParameter(l_pParameter);
							char l_sBuffer[1024];
							bool l_bValid=true;
							switch(l_pParameter->getType())
373
							{
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
								case OpenViBE::Kernel::ParameterType_Enumeration:
									::strcpy(l_sBuffer, this->getTypeManager().getEnumerationEntryNameFromValue(l_pParameter->getSubTypeIdentifier(), ip_ui64Parameter).toASCIIString());
									l_oTypeIdentifier=l_pParameter->getSubTypeIdentifier();
									break;

								case OpenViBE::Kernel::ParameterType_Integer:
								case OpenViBE::Kernel::ParameterType_UInteger:
									::sprintf(l_sBuffer, "%lli", (OpenViBE::int64)ip_i64Parameter);
									l_oTypeIdentifier=OV_TypeId_Integer;
									break;

								case OpenViBE::Kernel::ParameterType_Boolean:
									::sprintf(l_sBuffer, "%s", ((OpenViBE::boolean)ip_bParameter)?"true":"false");
									l_oTypeIdentifier=OV_TypeId_Boolean;
									break;

								case OpenViBE::Kernel::ParameterType_Float:
									::sprintf(l_sBuffer, "%lf", (OpenViBE::float64)ip_f64Parameter);
									l_oTypeIdentifier=OV_TypeId_Float;
									break;
								case OpenViBE::Kernel::ParameterType_String:
									::sprintf(l_sBuffer, "%s", ((OpenViBE::CString*)ip_sParameter)->toASCIIString());
									l_oTypeIdentifier=OV_TypeId_String;
									break;
								default:
399
									std::cout << "Invalid parameter type " << l_pParameter->getType() << "\n";
400
401
									l_bValid=false;
									break;
402
							}
403
404

							if(l_bValid)
405
							{
406
407
408
								// @FIXME argh, the -2 is a hard coding that the classifier trainer has 2 settings after the classifier setting... ouch
								DEBUG_PRINT(std::cout << "Adding setting (case A) " << l_sParameterName << " : " << l_sBuffer << " to slot " << rBox.getSettingCount()-2 << "\n";)
								rBox.addSetting(l_sParameterName, l_oTypeIdentifier, l_sBuffer, rBox.getSettingCount()-2);
409
								i++;
410
411
412
413
							}
						}
					}
				}
414
415
416

				// This changes the pairwise strategy decision voting type of the box settings allowing
				// designer to list the correct choices in the combo box.
417
				updateDecision(rBox);
418

419
420
421
422
423
424
425
426
				return true;
			}

			_IsDerivedFromClass_Final_(OpenViBEToolkit::TBoxListener < OpenViBE::Plugins::IBoxListener >, OV_UndefinedIdentifier)

		protected:

			OpenViBE::CIdentifier m_oClassifierClassIdentifier;
Serrière Guillaume's avatar
Serrière Guillaume committed
427
			OpenViBE::CIdentifier m_oStrategyClassIdentifier;
428
			OpenViBE::Kernel::IAlgorithmProxy* m_pClassifier;
Serrière Guillaume's avatar
Serrière Guillaume committed
429
			OpenViBE::Kernel::IAlgorithmProxy* m_pStrategy;
430
			const OpenViBE::uint32 m_ui32CustomSettingBase;
Serrière Guillaume's avatar
Serrière Guillaume committed
431
			OpenViBE::int32 m_i32StrategyAmountSettings;
432
433
434
435
436
		};
	}
}

#endif // __OpenViBEPlugins_BoxAlgorithm_CommonClassifierListener_INL__