aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw')
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.cpp138
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.def4
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.h95
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.cpp1186
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.h194
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.cpp211
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.h161
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.cpp178
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.h139
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.cpp6257
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.h1203
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.cfg422
-rw-r--r--src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.pro27
13 files changed, 10215 insertions, 0 deletions
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.cpp b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.cpp
new file mode 100644
index 00000000..bdbec8c2
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.cpp
@@ -0,0 +1,138 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2011-01-18 15:41:43 +0530 (Tue, 18 Jan 2011) $
+* $Revision: 829 $
+* $Author: mnab $
+*
+************************************************************************/
+/************************************************************************
+* FILE DESCR: Defines the entry for ActiveDTW dll application
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+w
+* DATE: 3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+* Balaji MNA 18th Jan 2010 Receiving LTKShapeRecognizer as single pointer
+* instead of double pointer in deleteShapeRecognizer
+************************************************************************/
+
+
+#include "ActiveDTW.h"
+#include "LTKShapeRecognizer.h"
+#include "ActiveDTWShapeRecognizer.h"
+#include "LTKException.h"
+#include "LTKErrors.h"
+#include "LTKOSUtilFactory.h"
+#include "LTKOSUtil.h"
+
+#ifdef _WIN32
+#include <windows.h>
+
+BOOL APIENTRY DllMain( HANDLE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+#endif
+
+/** createShapeRecognizer **/
+
+int createShapeRecognizer(const LTKControlInfo& controlInfo,
+ LTKShapeRecognizer** ptrObj )
+{
+ try
+ {
+ *ptrObj = new ActiveDTWShapeRecognizer(controlInfo);
+ return SUCCESS;
+ }
+ catch(LTKException e)
+ {
+ LTKReturnError(e.getErrorCode());
+ }
+}
+
+
+/**deleteShapeRecognizer **/
+int deleteShapeRecognizer(LTKShapeRecognizer *obj)
+{
+ try
+ {
+ if (obj != NULL )
+ {
+ delete obj;
+ obj = NULL;
+
+ //unloadDLLs();
+ }
+ }
+ catch(LTKException e)
+ {
+ LTKReturnError(e.getErrorCode());
+ }
+
+
+ return SUCCESS;
+}
+
+/** unloadDLLs **/
+/*
+void unloadDLLs()
+{
+// Unload feature extractor DLL
+if(m_libHandlerFE != NULL)
+{
+//Unload the DLL
+LTKUnloadDLL(m_libHandlerFE);
+m_libHandlerFE = NULL;
+}
+}*/
+
+/** getTraceGroups **/
+int getTraceGroups(LTKShapeRecognizer *obj, int shapeId,
+ int numberOfTraceGroups,
+ vector<LTKTraceGroup> &outTraceGroups)
+{
+ int errorCode = ((ActiveDTWShapeRecognizer*)obj)->getTraceGroups(shapeId,
+ numberOfTraceGroups, outTraceGroups);
+
+ if ( errorCode != SUCCESS )
+ {
+ LTKReturnError(errorCode);
+ }
+
+ return SUCCESS;
+}
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.def b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.def
new file mode 100644
index 00000000..0a4f75c9
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.def
@@ -0,0 +1,4 @@
+EXPORTS
+ createShapeRecognizer @1
+ deleteShapeRecognizer @2
+ getTraceGroups @3 \ No newline at end of file
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.h b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.h
new file mode 100644
index 00000000..854dc6da
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTW.h
@@ -0,0 +1,95 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2011-01-18 15:41:43 +0530 (Tue, 18 Jan 2011) $
+* $Revision: 829 $
+* $Author: mnab $
+*
+************************************************************************/
+/************************************************************************
+* FILE DESCR: Declarations for ActiveDTW dll exporting functions.
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+w
+* DATE: 3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+* Balaji MNA 18th Jan 2010 Receiving LTKShapeRecognizer as single pointer
+* instead of double pointer in deleteShapeRecognizer
+************************************************************************/
+
+#ifndef __ACTIVEDTW_H__
+#define __ACTIVEDTW_H__
+
+#include "LTKInc.h"
+#include "LTKTypes.h"
+
+#ifdef _WIN32
+#ifdef ACTIVEDTW_EXPORTS
+#define ACTIVEDTW_API __declspec(dllexport)
+#else
+#define ACTIVEDTW_API __declspec(dllimport)
+#endif //#ifdef ACTIVEDTW_EXPORTS
+#else
+#define ACTIVEDTW_API
+#endif //#ifdef _WIN32
+
+class LTKTraceGroup;
+class LTKShapeRecognizer;
+
+
+/** @defgroup ActiveDTWShapeRecognizer ActiveDTWShapeRecognizer
+*@brief The ActiveDTWShapeRecognizer
+*/
+
+/**
+* @ingroup ActiveDTWShapeRecognizer
+* @file ActiveDTW.cpp
+*/
+
+/**
+* Crates instance of type ActiveDTWShapeRecognizer and returns of type
+* LTKShpeRecognizer. (Acts as a Factory Method).
+*
+* @param none
+*
+* @return LTKShapeRecognizer - an instance of type LTKShapeRecognizer.
+*/
+extern "C" ACTIVEDTW_API int createShapeRecognizer(const LTKControlInfo& controlInfo,
+ LTKShapeRecognizer** pReco );
+ /**
+ * Destroy the instance by taking the address as its argument.
+ *
+ * @param obj - Address of LTKShapeRecognizer instance.
+ *
+ * @return 0 on Success
+*/
+extern "C" ACTIVEDTW_API int deleteShapeRecognizer(LTKShapeRecognizer *obj);
+
+extern "C" ACTIVEDTW_API int getTraceGroups(LTKShapeRecognizer *obj, int shapeID, int numberOfTraceGroups,vector<LTKTraceGroup> &outTraceGroups);
+
+void unloadDLLs();
+
+#endif //#ifndef __NN_H__
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.cpp b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.cpp
new file mode 100644
index 00000000..e0c36e6b
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.cpp
@@ -0,0 +1,1186 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2009-04-06 11:55:15 +0530 (Mon, 06 Apr 2009) $
+* $Revision: 758 $
+* $Author: royva $
+*
+************************************************************************/
+/*********************************************************************************************
+* FILE DESCR: Definitions for ActiveDTW Adaptation module
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+w
+* DATE:3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+***********************************************************************************************/
+
+#include "ActiveDTWShapeRecognizer.h"
+#include "ActiveDTWAdapt.h"
+#include "LTKLoggerUtil.h"
+#include "LTKConfigFileReader.h"
+#include "LTKErrors.h"
+#include "LTKErrorsList.h"
+#include "LTKPreprocDefaults.h"
+
+LTKAdapt* LTKAdapt::adaptInstance = NULL;
+int LTKAdapt::m_count = 0;
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : Constructor
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+LTKAdapt::LTKAdapt(ActiveDTWShapeRecognizer* ptrActiveDTWShapeReco)
+{
+ m_activedtwShapeRecognizer = ptrActiveDTWShapeReco;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ << "Exit LTKAdapt::LTKAdapt()"<<endl;
+
+ //Assign Default Values
+
+ m_maxClusterSize = ADAPT_DEF_MAX_NUMBER_SAMPLES_PER_CLASS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : Destructor
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+LTKAdapt::~LTKAdapt()
+{
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : deleteInstance
+* DESCRIPTION : delete AdaptInstance
+* ARGUMENTS :
+* RETURNS : None
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void LTKAdapt::deleteInstance()
+{
+ m_count = 0;
+ if(adaptInstance)
+ {
+ delete adaptInstance;
+ adaptInstance = NULL;
+ }
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getInstance
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+LTKAdapt* LTKAdapt::getInstance(ActiveDTWShapeRecognizer* ptrActiveDTWShapeReco)
+{
+ if(adaptInstance == NULL)
+ {
+ adaptInstance = new LTKAdapt(ptrActiveDTWShapeReco);
+ }
+
+ return adaptInstance;
+
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : Process
+* DESCRIPTION : Performs adaptation
+* ARGUMENTS :
+* RETURNS : Success : If completed successfully
+* Failure : Error Code
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int LTKAdapt::adapt(int shapeId)
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ << "Enter LTKAdapt::adapt()"<<endl;
+
+ int iErrorCode;
+
+ //read config file values when first adapt sample is encountered
+ if(m_count==0)
+ {
+ m_count = 1;
+
+ iErrorCode = readAdaptConfig();
+ if(iErrorCode !=0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during LTKAdapt::readAdaptConfig()"<<endl;
+ LTKReturnError(FAILURE);
+ }
+ }
+
+
+ //Check if Cached variables are valid
+ if(m_activedtwShapeRecognizer->m_neighborInfoVec.size()==0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ <<"DistanceIndexPair is empty"<<endl;
+
+ LTKReturnError(ENEIGHBOR_INFO_VECTOR_EMPTY );
+ }
+
+ //check if test featureVector is empty
+ if(m_activedtwShapeRecognizer->m_cachedShapeFeature.size() <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ <<"Features of input TraceGroup is empty"<<endl;
+
+ LTKReturnError(ESHAPE_SAMPLE_FEATURES_EMPTY);
+ }
+
+ //find out whether the test sample is close to a singleton or cluster
+
+ //case of incorrect classification
+ if(m_activedtwShapeRecognizer->m_vecRecoResult.size() == 0 ||
+ m_activedtwShapeRecognizer->m_vecRecoResult.at(0).getShapeId() != shapeId)
+ {
+
+ int index = 0;
+ //iterating through neighborInfoVec to retrieve information about the true
+ //shape model of class
+ while(shapeId != m_activedtwShapeRecognizer->m_neighborInfoVec[index].classId )
+ index++;
+
+ if(m_activedtwShapeRecognizer->m_neighborInfoVec[index].typeId == CLUSTER)
+ {
+ int clusterId = m_activedtwShapeRecognizer->m_neighborInfoVec[index].sampleId;
+
+ //adapting the cluster
+ iErrorCode = adaptCluster(m_activedtwShapeRecognizer->m_cachedShapeFeature,clusterId,shapeId);
+
+ if(iErrorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<iErrorCode<<
+ " LTKAdapt::adapt" << endl;
+ LTKReturnError(iErrorCode);
+ }
+ }
+ else
+ {
+ //adapting the singleton set
+ iErrorCode = adaptSingleton(m_activedtwShapeRecognizer->m_cachedShapeFeature,shapeId);
+ if(iErrorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<iErrorCode<<
+ " LTKAdapt::adapt" << endl;
+ LTKReturnError(iErrorCode);
+ }
+ }
+ }
+ else
+ {
+ //case of correct classification
+ if(m_activedtwShapeRecognizer->m_neighborInfoVec[0].typeId == CLUSTER)
+ {
+ int clusterId = m_activedtwShapeRecognizer->m_neighborInfoVec[0].sampleId;
+ int iterator = 0;
+ while(m_activedtwShapeRecognizer->m_prototypeShapes[iterator].getShapeId() != shapeId)
+ iterator++;
+
+ ActiveDTWShapeModel shapeModelToAdapt = m_activedtwShapeRecognizer->m_prototypeShapes[iterator];
+
+ vector<ActiveDTWClusterModel> currentClusterModelVector = shapeModelToAdapt.getClusterModelVector();
+
+ //adapt the model only if number of samples seen by the model is less than the threshold m_maxClustersize
+ if(currentClusterModelVector[clusterId].getNumSamples() < m_maxClusterSize)
+ {
+ iErrorCode = adaptCluster(m_activedtwShapeRecognizer->m_cachedShapeFeature,clusterId,shapeId);
+
+ if(iErrorCode != SUCCESS)
+ {
+ currentClusterModelVector.clear();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<iErrorCode<<
+ " LTKAdapt::adapt" << endl;
+ LTKReturnError(iErrorCode);
+ }
+ }
+ currentClusterModelVector.clear();
+ }
+ else
+ {
+ //adapt singleton set
+ iErrorCode = adaptSingleton(m_activedtwShapeRecognizer->m_cachedShapeFeature,shapeId);
+ if(iErrorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<iErrorCode<<
+ " LTKAdapt::adapt" << endl;
+ LTKReturnError(iErrorCode);
+ }
+ }
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ << "Exit LTKAdapt::adapt()"<<endl;
+
+ return(SUCCESS);
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : readAdaptConfig
+* DESCRIPTION : Reads configuration info for adaptation
+* ARGUMENTS : NONE
+* RETURNS : NONE
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int LTKAdapt::readAdaptConfig()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Enter Adapt::readAdaptConfig"
+ <<endl;
+
+
+ LTKConfigFileReader *adaptConfigReader = NULL;
+
+ adaptConfigReader = new LTKConfigFileReader(m_activedtwShapeRecognizer->m_activedtwCfgFilePath);
+
+
+ //Don't throw Error as ShapeRecognizer might not support ADAPT
+ string tempStringVar = "";
+ int tempIntegerVar;
+
+ int errorCode = adaptConfigReader->getConfigValue(MAXCLUSTERSIZE,tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ if(LTKStringUtil::isInteger(tempStringVar))
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+
+ if(tempIntegerVar > 1)
+ {
+ if(tempIntegerVar < m_activedtwShapeRecognizer->m_minClusterSize)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << m_maxClusterSize <<
+ " is out of permitted range MAXCUSTERSIZE < MINCLUSTERSIZE" <<
+ " LTKAdapt::readAdaptConfig"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ else
+ {
+ m_maxClusterSize = tempIntegerVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ MAXCLUSTERSIZE << " = " <<m_maxClusterSize<<endl;
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << m_maxClusterSize <<
+ " is out of permitted range" <<
+ " LTKAdapt::readAdaptConfig"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << MAXCLUSTERSIZE <<
+ " is out of permitted range" <<
+ " LTKAdapt::readAdaptConfig"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << MAXCLUSTERSIZE << " : " << m_maxClusterSize << endl;
+ }
+
+
+ if(adaptConfigReader)
+ delete adaptConfigReader;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Exit LTKAdapt::readAdaptConfig"
+ <<endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : adaptCluster
+* DESCRIPTION : This method adapts the cluster with the new featureVector. Implementation of method described in paper:
+"Incremental eigenanalysis for classifiation, published in British Machine Vision Conference-2008"
+*
+* ARGUMENTS : INPUT
+featureVecToAdapt shapeFeature
+clusterId int
+shapeId int
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int LTKAdapt::adaptCluster(shapeFeature& featureVecToAdapt,int clusterId,int shapeId)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "LTKAdapt::adaptCluster()" << endl;
+
+ int errorCode;
+
+ //validating input arguments
+ if(m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.find(shapeId) == m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.end())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_SHAPEID << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ //finding the prototypeShape
+ int index = 0;
+
+ int i = 0;
+ int j = 0;
+
+ while(m_activedtwShapeRecognizer->m_prototypeShapes[index].getShapeId() != shapeId)
+ index++;
+
+ ActiveDTWShapeModel shapeModelToAdapt = m_activedtwShapeRecognizer->m_prototypeShapes[index];
+
+ vector<ActiveDTWClusterModel> currentClusterModelVector = shapeModelToAdapt.getClusterModelVector();
+
+ if(clusterId < 0 || clusterId >= currentClusterModelVector.size())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_CLUSTER_ID << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+
+ LTKReturnError(EINVALID_CLUSTER_ID);
+ }
+
+
+ ActiveDTWClusterModel clusterToAdapt = currentClusterModelVector[clusterId];
+
+ //obtaining data of cluster
+ doubleVector oldEigenValues = clusterToAdapt.getEigenValues();
+
+ double2DVector oldEigenVectors = clusterToAdapt.getEigenVectors();
+
+ doubleVector oldClusterMean = clusterToAdapt.getClusterMean();
+
+ int numClusterSamples = clusterToAdapt.getNumSamples();
+
+ //convert the shapefeature to double vector
+ floatVector floatFeatureVector;
+
+ doubleVector doubleFeatureVector;
+
+ errorCode = m_activedtwShapeRecognizer->m_shapeRecUtil.shapeFeatureVectorToFloatVector(featureVecToAdapt,floatFeatureVector);
+
+ if( errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ "LTKAdapt::adaptCluster" <<endl;
+ LTKReturnError(errorCode);
+ }
+
+ int featureSize = floatFeatureVector.size();
+
+ for(i = 0; i < featureSize; i++)
+ doubleFeatureVector.push_back(floatFeatureVector[i]);
+
+ floatFeatureVector.clear();
+
+ //the difference vector
+ //refers to y - x(mean)
+ doubleVector diffVector;
+
+ //refers to g in the paper (Eqn 2)
+ //g = unp*(y - x(mean))
+ doubleVector projectedTestSample;
+
+ //refers to h in the paper (Eqn 3)
+ //h = (y - x(mean)) - (unp * g)
+ doubleVector residueVector;
+
+ //refers to unp*g
+ doubleVector reverseProjection;
+
+ int numEigenVectors = oldEigenVectors.size();
+
+ //calculating diffVector
+ for(i = 0; i < featureSize; i++)
+ diffVector.push_back(doubleFeatureVector[i] - oldClusterMean[i]);
+
+ //constructing the projected test sample i.e g
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ double tempValue = 0;
+ for(j = 0; j < featureSize; j++)
+ {
+ tempValue += (oldEigenVectors[i][j] * diffVector[j]);
+ }
+ projectedTestSample.push_back(tempValue);
+ }
+
+ //constructing reverse projection
+ for(i = 0; i < featureSize; i++)
+ {
+ double tempValue = 0;
+ for(j = 0; j < numEigenVectors;j++)
+ {
+ tempValue += oldEigenVectors[j][i] * projectedTestSample[j];
+ }
+ reverseProjection.push_back(tempValue);
+ }
+
+ //construct residue vector
+ for(i = 0; i < featureSize; i++)
+ residueVector.push_back(diffVector[i] - reverseProjection[i]);
+
+ //magnitude of residue vector
+ double residueMagnitude = 0;
+
+ for(i = 0; i < featureSize; i++)
+ residueMagnitude = residueMagnitude + (residueVector[i] * residueVector[i]);
+
+ residueMagnitude = sqrt(residueMagnitude);
+
+ //determining the recomputed eigenValues and eigenVectors
+ //case 1 residueMagnitude is 0
+ if(residueMagnitude == 0)
+ {
+ //construct the matrix whose eigen values and eigen vectors are to be calculated
+ doubleVector tempVector;
+
+ //corresponds to matrix in eqn 10
+ double2DVector coeff1;
+
+ tempVector.assign(numEigenVectors,0.0);
+
+ coeff1.assign(numEigenVectors,tempVector);
+
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ {
+ if(i == j)
+ coeff1[i][j] = oldEigenValues[j];
+ }
+ }
+
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ coeff1[i][j] = (coeff1[i][j] * numClusterSamples)/(numClusterSamples + 1);
+ }
+
+ //refers to eqn 11 in paper
+ double2DVector coeff2;
+
+ coeff2.assign(numEigenVectors,tempVector);
+
+ //constructing g*g(transpose)
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ coeff2[i][j] = projectedTestSample[i] * projectedTestSample[j];
+ }
+
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ coeff2[i][j] = (coeff2[i][j] * numClusterSamples) / ((numClusterSamples + 1) * (numClusterSamples + 1));
+ }
+
+ //final matrix
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ coeff1[i][j] += coeff2[i][j];
+ }
+
+ //solving the intermediate eigen value problem
+ //refers to eigenValue problem in eqn 12
+ double2DVector intermediateEigenVectors;
+ doubleVector eigenValues;
+ int nrot = 0;
+
+ intermediateEigenVectors.assign(numEigenVectors,tempVector);
+
+ errorCode = m_activedtwShapeRecognizer->computeEigenVectors(coeff1,coeff1.size(),eigenValues,intermediateEigenVectors,nrot);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ //the new eigen vectors
+ double2DVector eigenVectors;
+
+ eigenVectors.assign(featureSize,tempVector);
+
+ tempVector.clear();
+
+ //calculating the new eigen vectors from the intermediateEigenVectors and oldEigenVectors
+ //refers to eqn 8
+ for( i = 0; i < featureSize; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ {
+ for(int k = 0; k < numEigenVectors;k++)
+ {
+ eigenVectors[i][j] += (oldEigenVectors[k][i] * intermediateEigenVectors[k][j]);
+ }
+ }
+ }
+
+ //now converting the eigen vectors to row format
+ //this makes it easy to write the eigen vectors to the mdt file and read from it
+ double2DVector newEigenVectors;
+
+ tempVector.assign(featureSize,0.0);
+
+ newEigenVectors.assign(numEigenVectors,tempVector);
+
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < featureSize; j++)
+ newEigenVectors[i][j] = eigenVectors[j][i];
+ }
+
+ numEigenVectors = 0;
+ double eigenEnergy = 0;
+ for( i = 0; i < eigenValues.size(); i++)
+ {
+ eigenEnergy += eigenValues[i];
+ }
+
+ double tempEigenEnergy = 0;
+
+ while(tempEigenEnergy <= ((m_activedtwShapeRecognizer->m_percentEigenEnergy * eigenEnergy)/100))
+ tempEigenEnergy += eigenValues[numEigenVectors++];
+
+ doubleVector selectedEigenValues;
+ double2DVector selectedEigenVectors;
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ selectedEigenValues.push_back(eigenValues[i]);
+ selectedEigenVectors.push_back(newEigenVectors[i]);
+ }
+
+ doubleVector newClusterMean;
+
+ for( i = 0; i < featureSize; i++)
+ {
+ double tempValue = ((numClusterSamples * oldClusterMean[i]) + doubleFeatureVector[i])/(numClusterSamples + 1);
+ newClusterMean.push_back(tempValue);
+ }
+
+ //updating the cluster model
+ errorCode = clusterToAdapt.setNumSamples(numClusterSamples + 1);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+
+ clusterToAdapt.setEigenValues(selectedEigenValues);
+ selectedEigenValues.clear();
+
+ clusterToAdapt.setEigenVectors(selectedEigenVectors);
+ selectedEigenVectors.clear();
+
+ clusterToAdapt.setClusterMean(newClusterMean);
+
+ currentClusterModelVector[clusterId] = clusterToAdapt;
+
+ shapeModelToAdapt.setClusterModelVector(currentClusterModelVector);
+
+ m_activedtwShapeRecognizer->m_prototypeShapes[index] = shapeModelToAdapt;
+
+ //clearing vectors
+ tempVector.clear();
+ coeff1.clear();
+ coeff2.clear();
+ eigenValues.clear();
+ newEigenVectors.clear();
+ intermediateEigenVectors.clear();
+ newClusterMean.clear();
+ eigenVectors.clear();
+ }
+ else
+ {
+ //case residueMagnitude is not 0;
+ doubleVector unitResidueVector;
+
+ for(i = 0; i < featureSize; i++)
+ unitResidueVector.push_back(residueVector[i]/residueMagnitude);
+
+ //construct the matrix whose eigen values and eigen vectors are to be calculated
+ doubleVector tempVector;
+
+ //refer to eqn 10
+ double2DVector coeff1;
+
+ tempVector.assign(numEigenVectors + 1,0.0);
+
+ coeff1.assign(numEigenVectors + 1,tempVector);
+
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ {
+ if(i == j)
+ {
+ coeff1[i][j] = oldEigenValues[j];
+ }
+ }
+ }
+
+ for( i = 0; i < (numEigenVectors + 1 ); i++)
+ {
+ for(j = 0; j < (numEigenVectors + 1); j++)
+ coeff1[i][j] = (coeff1[i][j] * numClusterSamples)/(numClusterSamples + 1);
+ }
+
+ //refers to unith(transpose)*diffVector
+ double gamma = 0;
+
+ for( i = 0; i < featureSize; i++)
+ gamma = gamma + (unitResidueVector[i] * diffVector[i]);
+
+ //refers to eqn 11
+ double2DVector coeff2;
+
+ coeff2.assign(numEigenVectors + 1,tempVector);
+
+ //constructing g*g(transpose)
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < numEigenVectors; j++)
+ coeff2[i][j] = projectedTestSample[i] * projectedTestSample[j];
+ }
+
+ //calculating gamma * projectedTestSample i.e gamma * g
+ doubleVector gammaProjTestSample;
+
+ for( i = 0; i < numEigenVectors; i++)
+ gammaProjTestSample.push_back(projectedTestSample[i]*gamma);
+
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ coeff2[i][numEigenVectors] = gammaProjTestSample[i];
+ coeff2[numEigenVectors][i] = gammaProjTestSample[i];
+ }
+
+ coeff2[numEigenVectors][numEigenVectors] = gamma * gamma;
+
+ for( i = 0; i < numEigenVectors + 1; i++)
+ {
+ for(j = 0; j < numEigenVectors + 1; j++)
+ coeff2[i][j] = (coeff2[i][j] * numClusterSamples) / ((numClusterSamples + 1) * (numClusterSamples + 1));
+ }
+
+ //final matrix
+ for( i = 0; i < numEigenVectors + 1; i++)
+ {
+ for(j = 0; j < numEigenVectors + 1; j++)
+ coeff1[i][j] = coeff1[i][j] + coeff2[i][j];
+ }
+
+ //solving the intermediate eigen value problem
+ //refers to eqn 12
+ double2DVector intermediateEigenVectors;
+ doubleVector eigenValues;
+ int nrot = 0;
+
+ intermediateEigenVectors.assign(numEigenVectors + 1,tempVector);
+
+ errorCode = m_activedtwShapeRecognizer->computeEigenVectors(coeff1,coeff1.size(),eigenValues,intermediateEigenVectors,nrot);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ //the new eigen vectors
+ double2DVector eigenVectors;
+
+ //adding unith to the old set of eigen vectors
+ oldEigenVectors.push_back(unitResidueVector);
+
+ eigenVectors.assign(featureSize,tempVector);
+
+ tempVector.clear();
+
+ //calculating the new eigen vectors from the oldEigenVectors
+ //refers to eqn 8
+ for( i = 0; i < featureSize; i++)
+ {
+ for(j = 0; j < (numEigenVectors + 1); j++)
+ {
+ for(int k = 0; k < (numEigenVectors + 1);k++)
+ {
+ eigenVectors[i][j] = eigenVectors[i][j] + (oldEigenVectors[k][i] * intermediateEigenVectors[k][j]);
+ }
+ }
+ }
+
+ //now converting the eigen vectors to row format
+ //this makes it easy to write the eigen vectors to the mdt file and read from it
+ double2DVector newEigenVectors;
+
+ tempVector.assign(featureSize,0.0);
+
+ newEigenVectors.assign(numEigenVectors + 1,tempVector);
+
+ for( i = 0; i < numEigenVectors + 1; i++)
+ {
+ for(j = 0; j < featureSize; j++)
+ newEigenVectors[i][j] = eigenVectors[j][i];
+ }
+
+ doubleVector newClusterMean;
+
+ for( i = 0; i < featureSize; i++)
+ {
+ double tempValue = ((numClusterSamples * oldClusterMean[i]) + doubleFeatureVector[i])/(numClusterSamples + 1);
+ newClusterMean.push_back(tempValue);
+ }
+
+ numEigenVectors = 0;
+ double eigenEnergy = 0;
+ for( i = 0; i < eigenValues.size(); i++)
+ {
+ eigenEnergy += eigenValues[i];
+ }
+
+ double tempEigenEnergy = 0;
+
+ while(tempEigenEnergy <= ((m_activedtwShapeRecognizer->m_percentEigenEnergy * eigenEnergy)/100))
+ tempEigenEnergy += eigenValues[numEigenVectors++];
+
+
+ doubleVector selectedEigenValues;
+ double2DVector selectedEigenVectors;
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ selectedEigenValues.push_back(eigenValues[i]);
+ selectedEigenVectors.push_back(newEigenVectors[i]);
+ }
+
+ //updating the cluster model
+
+ errorCode = clusterToAdapt.setNumSamples(numClusterSamples + 1);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ clusterToAdapt.setEigenValues(selectedEigenValues);
+ selectedEigenValues.clear();
+ clusterToAdapt.setEigenVectors(selectedEigenVectors);
+ selectedEigenVectors.clear();
+
+ clusterToAdapt.setClusterMean(newClusterMean);
+
+ currentClusterModelVector[clusterId] = clusterToAdapt;
+
+ shapeModelToAdapt.setClusterModelVector(currentClusterModelVector);
+
+ m_activedtwShapeRecognizer->m_prototypeShapes[index] = shapeModelToAdapt;
+
+ //clearing vectors
+ tempVector.clear();
+ coeff1.clear();
+ coeff2.clear();
+ gammaProjTestSample.clear();
+ eigenValues.clear();
+ newEigenVectors.clear();
+ intermediateEigenVectors.clear();
+ newClusterMean.clear();
+ eigenVectors.clear();
+ unitResidueVector.clear();
+ }
+
+ //clearing vectors
+ oldEigenValues.clear();
+ oldEigenVectors.clear();
+ oldClusterMean.clear();
+ doubleFeatureVector.clear();
+ projectedTestSample.clear();
+ residueVector.clear();
+ reverseProjection.clear();
+ diffVector.clear();
+ currentClusterModelVector.clear();
+
+ errorCode = m_activedtwShapeRecognizer->writePrototypeShapesToMDTFile();
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "LTKAdapt::adaptCluster()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : adaptSingleton
+* DESCRIPTION : This method adapts the singleton sey with the
+new featureVector and trains the singleton set if the
+number of singletons exceeds a certain number
+* ARGUMENTS : INPUT
+featureVecToAdapt shapeFeature
+shapeId int
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int LTKAdapt::adaptSingleton(shapeFeature& featureVecToAdapt,int shapeId)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "LTKAdapt::adaptSingleton()" << endl;
+
+ //validating input parameters
+ if(m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.find(shapeId) == m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.end())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_SHAPEID << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ int errorCode;
+
+ int index = 0;
+
+ //iterating prototypeShapes to find the shapeModel To Adapt
+ while(m_activedtwShapeRecognizer->m_prototypeShapes[index].getShapeId() != shapeId)
+ index++;
+
+ shapeMatrix currentSingletonVectors = m_activedtwShapeRecognizer->m_prototypeShapes[index].getSingletonVector();
+
+ currentSingletonVectors.push_back(featureVecToAdapt);
+
+ m_activedtwShapeRecognizer->m_prototypeShapes[index].setSingletonVector(currentSingletonVectors);
+
+ int singletonSize = currentSingletonVectors.size();
+
+ //train the singletons only if their number is above some threshold
+ if(singletonSize > (TRAINSINGLETONFACTOR * m_activedtwShapeRecognizer->m_minClusterSize) )
+ {
+ errorCode = trainSingletons(currentSingletonVectors,shapeId,index);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptSingleton()" << endl;
+ LTKReturnError(errorCode);
+ }
+ }
+
+ currentSingletonVectors.clear();
+
+ //updating the mdt file
+ errorCode = m_activedtwShapeRecognizer->writePrototypeShapesToMDTFile();
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "LTKAdapt::adaptSingleton()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : trainSingletons
+* DESCRIPTION : This method trains the featureVectors in the singleton set
+* ARGUMENTS : INPUT
+singletons shapeMatrix
+shapeId int
+index int
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int LTKAdapt::trainSingletons(const shapeMatrix &singletons,int shapeId,int index)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "LTKAdapt::trainSingletons()" << endl;
+
+ //validating input arguments
+ if(m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.find(shapeId) == m_activedtwShapeRecognizer->m_shapeIDNumPrototypesMap.end())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_SHAPEID << " " <<
+ " LTKAdapt::adaptCluster()" << endl;
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ if(index < 0 || index >= m_activedtwShapeRecognizer->m_prototypeShapes.size())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EPROTOYPESHAPE_INDEX_OUT_OF_BOUND << " " <<
+ " LTKAdapt::adaptSingleton()" << endl;
+
+ LTKReturnError(EPROTOYPESHAPE_INDEX_OUT_OF_BOUND);
+ }
+
+ int errorCode;
+
+ LTKShapeSample tempShape;
+
+ vector<LTKShapeSample> shapesToTrain;
+
+ int singletonSize = singletons.size();
+
+ int2DVector clusterOutput;
+
+ shapeMatrix newSingletons;
+
+ vector<ActiveDTWClusterModel> currentClusterModelVector = m_activedtwShapeRecognizer->m_prototypeShapes[index].getClusterModelVector();
+
+ int i = 0;
+
+ for(i = 0; i < singletonSize; i++)
+ {
+ tempShape.setFeatureVector(singletons[i]);
+ shapesToTrain.push_back(tempShape);
+ }
+
+ //perform clustering
+ errorCode = m_activedtwShapeRecognizer->performClustering(shapesToTrain,clusterOutput);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainSingletons()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ int2DVector::iterator iter = clusterOutput.begin();
+ int2DVector::iterator iEnd = clusterOutput.end();
+ intVector cluster;
+
+ /**ITERATING THROUGH THE VARIOUS CLUSTERS **/
+ for(;iter != iEnd; ++iter)
+ {
+ cluster = (*iter);
+
+ /** SINGLETON VECTORS **/
+ if(cluster.size() < m_activedtwShapeRecognizer->m_minClusterSize)
+ {
+ for(i = 0; i < cluster.size(); i++)
+ newSingletons.push_back(shapesToTrain[cluster[i]].getFeatureVector());
+ }
+
+ /** CLUSTER PROCESSING **/
+ else
+ {
+ //creating new clusters
+ doubleVector tempFeature;
+
+ double2DVector featureMatrix;
+
+ double2DVector covarianceMatrix;
+
+ doubleVector clusterMean;
+
+ double2DVector intermediateEigenVectors;
+
+ double2DVector eigenVectors;
+
+ doubleVector eigenValues;
+
+ ActiveDTWClusterModel clusterModel;
+
+ //gather all the shape samples pertaining to a particular cluster
+ int clusterSize = cluster.size();
+ for(i = 0; i < clusterSize; i++)
+ {
+ floatVector floatFeatureVector;
+
+ errorCode = m_activedtwShapeRecognizer->m_shapeRecUtil.shapeFeatureVectorToFloatVector(shapesToTrain[cluster[i]].getFeatureVector(),
+ floatFeatureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ int floatFeatureVectorSize = floatFeatureVector.size();
+ for(int i = 0; i < floatFeatureVectorSize; i++)
+ tempFeature.push_back(floatFeatureVector[i]);
+
+ featureMatrix.push_back(tempFeature);
+ tempFeature.clear();
+ floatFeatureVector.clear();
+ }
+
+ /** COMPUTING COVARIANCE MATRIX **/
+ errorCode = m_activedtwShapeRecognizer->computeCovarianceMatrix(featureMatrix,covarianceMatrix,clusterMean);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ clusterModel.setClusterMean(clusterMean);
+
+ errorCode = m_activedtwShapeRecognizer->computeEigenVectorsForLargeDimension(featureMatrix,covarianceMatrix,intermediateEigenVectors,eigenValues);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ doubleVector tempEigenVector;
+ int eigenVectorDimension = intermediateEigenVectors.size();
+ if(eigenVectorDimension <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EEMPTY_EIGENVECTORS << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(EEMPTY_EIGENVECTORS);
+ }
+
+ int numEigenVectors = intermediateEigenVectors[0].size();
+
+ if(numEigenVectors <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_NUM_OF_EIGENVECTORS << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(EINVALID_NUM_OF_EIGENVECTORS);
+ }
+
+ for(i = 0; i < numEigenVectors; i++)
+ {
+ for(int j = 0; j < eigenVectorDimension; j++)
+ tempEigenVector.push_back(intermediateEigenVectors[j][i]);
+
+ eigenVectors.push_back(tempEigenVector);
+ tempEigenVector.clear();
+ }
+
+ /**CONSTRUCTING CLUSTER MODEL **/
+
+ errorCode = clusterModel.setNumSamples(cluster.size());
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " LTKAdapt::trainSingletons()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ clusterModel.setEigenValues(eigenValues);
+
+ clusterModel.setEigenVectors(eigenVectors);
+
+ currentClusterModelVector.push_back(clusterModel);
+
+ //clearing vectors
+ featureMatrix.clear();
+ covarianceMatrix.clear();
+ clusterMean.clear();
+ intermediateEigenVectors.clear();
+ eigenVectors.clear();
+ eigenValues.clear();
+
+ }
+ }
+
+ //updating the shape model
+ (m_activedtwShapeRecognizer->m_prototypeShapes[index]).setClusterModelVector(currentClusterModelVector);
+ m_activedtwShapeRecognizer->m_prototypeShapes[index].setSingletonVector(newSingletons);
+
+ //clearing vectors
+ currentClusterModelVector.clear();
+ clusterOutput.clear();
+ shapesToTrain.clear();
+ newSingletons.clear();
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "LTKAdapt::trainSingletons()" << endl;
+
+ return SUCCESS;
+}
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.h b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.h
new file mode 100644
index 00000000..276eeb24
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWAdapt.h
@@ -0,0 +1,194 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2009-04-06 11:55:15 +0530 (Mon, 06 Apr 2009) $
+* $Revision: 758 $
+* $Author: royva $
+*
+************************************************************************/
+
+/************************************************************************
+* FILE DESCR: Implements ActiveDTWShapeRecognizer::Adapt
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+* DATE: 3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description
+************************************************************************/
+#pragma once
+
+#include "ActiveDTWShapeRecognizer.h"
+#include "LTKLoggerUtil.h"
+#include "LTKConfigFileReader.h"
+#include "LTKErrors.h"
+#include "LTKErrorsList.h"
+#include "LTKPreprocDefaults.h"
+
+#define TRAINSINGLETONFACTOR 2
+
+class ActiveDTWShapeRecognizer;
+
+class LTKAdapt
+{
+private:
+ /** @name Constructor */
+ LTKAdapt(ActiveDTWShapeRecognizer* ptrActiveDTWShapeReco);
+
+
+ static LTKAdapt* adaptInstance;
+
+ static int m_count;
+ /**< @brief
+ * <p>
+ * Initially m_count = 0, when adapt is called on first sample
+ * it checks if m_count = 0, if yes it calls readAdaptConfig and then increments m_count to 1
+ * Thus readAdaptConfig is called only once
+ * </p>
+ */
+
+public:
+ static LTKAdapt* getInstance(ActiveDTWShapeRecognizer* ptrActiveDTWShapeReco);
+
+ /**
+ * Adapts the shapeId
+ *
+ * Semantics
+ *
+ * - Reads the internal classifier config information incase of first sample to be adapted
+
+ - Checks if the sample to be adapted was correctly classified or incorrectly classified
+
+ - Incase of correct classification
+ --Check if the shape was closest to the cluster or singletons
+ --If sample to be adapted was closest to the clusters, and cluster size does not exceed
+ m_maxClusterSize, then call adaptCluster
+ --It sample to be adapted was closest to the singleton, call adaptSingleton
+
+ -Incase of incorrect classification
+ --If the sample to be adapted was closest to a cluster, call adaptCluster
+ --If the sample to be adapted was closest to a singleton, call adaptSingleton
+ *
+ * @param shapeId : shape to be adapted
+ * @return SUCCESS : if the shapeId was adapted successfully
+ * ErrorCode: if some error occurs
+ * @exception ENEIGHBOR_INFO_VECTOR_EMPTY : ActiveDTWShapeRecognizer::m_neighbofInfoVec is empty
+ * @exception ESHAPE_SAMPLE_FEATURES_EMPTY : ActiveDTWShapeRecognizer::m_cachedShapeFeature is empty
+ */
+ int adapt(int shapeId);
+
+ /** @name Destructor */
+ ~LTKAdapt();
+
+ void deleteInstance();
+
+private:
+
+/**< @brief Pointer to ActiveDTWShapeRecognizer
+* <p>
+*
+* </p>
+ */
+ ActiveDTWShapeRecognizer* m_activedtwShapeRecognizer;
+
+ //the maximum number of samples in a cluster
+ int m_maxClusterSize;
+ /**< @brief Maximum Cluster Size
+ * <p>
+ * Specifies the maximum number of samples that can be present in a cluster
+ * It must be >= the ActiveDTWShapeRecognizer::m_minClusterSize
+ * </p>
+ */
+
+
+ /**
+ * This method reads Config variables related to Adapt from CFG
+ *
+ * Semantics
+ *
+ *
+ * @param none
+ *
+ * @return SUCCESS:
+ * FAILURE: return ErrorCode
+ * @exception none
+ */
+ int readAdaptConfig();
+
+ /**
+ * Adapts the cluster with the new shapeFeature
+ *
+ * Semantics
+ *
+ * - Recomputes the eigen values, eigen vectors and cluster mean,
+ * using the old values and the new shape feature
+ *
+ * @param featureVecToAdapt : shapeFeature
+ * @param clusterId : cluster to be adapted
+ * @param shapeId : shape to be adapted
+ * @return SUCCESS : if the shapeId was adapted successfully
+ * ErrorCode: if some error occurs
+ * @exception EINVALID_SHAPEID
+ * @exception EINVALID_CLUSTER_ID
+ */
+ int adaptCluster(shapeFeature& featureVecToAdapt,int clusterId,int shapeId);
+
+ /**
+ * Adapts the set of singletons with the new shapeFeature
+ *
+ * Semantics
+ *
+ * - Adds the new shapeFeature to the current set of singletons
+ *
+ * - If the number of singletons exceeds a certain threshold train the singletons
+ *
+ * @param featureVecToAdapt : shapeFeature
+ * @param shapeId : shape to be adapted
+ * @return SUCCESS : if the shapeId was adapted successfully
+ * ErrorCode: if some error occurs
+ * @exception EINVALID_SHAPEID
+ */
+ int adaptSingleton(shapeFeature& featureVecToAdapt,int shapeId);
+
+ /**
+ * Performs training on the set of singletons
+ *
+ * Semantics
+ *
+ * - performs clustering on the singletons, resulting in new clusters and singleton set
+ *
+ * - cluster and singleton information are added to the shape model
+ *
+ * @param singletons : shapeMatrix
+ * @param shapeId : shape to be adapted
+ * @param index : index in ActiveDTWShapeRecognizer::m_prototypeShapes which holds the shapeModel information
+ * @return SUCCESS : if the shapeId was adapted successfully
+ * ErrorCode: if some error occurs
+ * @exception EINVALID_SHAPEID : shapeId specified is Invalid
+ * @exception EPROTOYPESHAPE_INDEX_OUT_OF_BOUND ; index value specified is Invalid
+ * @exception EEMPTY_EIGENVECTORS ; eigen vector dimension is < 0
+ * @exception EINVALID_NUM_OF_EIGENVECTORS : number of eigen vectors < 0
+ */
+ int trainSingletons(const shapeMatrix &singletons,int shapeId,int index);
+};
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.cpp b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.cpp
new file mode 100644
index 00000000..34886d32
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.cpp
@@ -0,0 +1,211 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2009-04-06 11:55:15 +0530 (Mon, 06 Apr 2009) $
+* $Revision: 758 $
+* $Author: royva $
+*
+************************************************************************/
+/*********************************************************************************************
+* FILE DESCR: Implementation for ActiveDTW Cluster Model. Used to store cluster model information
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+w
+* DATE:3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+***********************************************************************************************/
+
+#include "ActiveDTWClusterModel.h"
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ActiveDTWClusterModel
+* DESCRIPTION : Default Constructor
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWClusterModel::ActiveDTWClusterModel()
+{
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setNumSamples
+* DESCRIPTION : sets the number of samples in the cluster
+* ARGUMENTS : INPUT: numSamples
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWClusterModel::setNumSamples(int numSamples)
+{
+ if(numSamples > 0)
+ {
+ m_numberOfSamples = numSamples;
+ }
+ else
+ {
+ LTKReturnError(EINVALID_NUM_SAMPLES);
+ }
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getNumSamples
+* DESCRIPTION : returns the number of samples in a cluster
+* ARGUMENTS : none
+* RETURNS : number of samples
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWClusterModel::getNumSamples() const
+{
+ return m_numberOfSamples;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setEigenValues
+* DESCRIPTION : sets the eigen values of the cluster
+* ARGUMENTS : INPUT: eigen values
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void ActiveDTWClusterModel::setEigenValues(const doubleVector& eigVal)
+{
+ m_eigenValues = eigVal;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setClusterMean
+* DESCRIPTION : sets the cluster mean of the cluster
+* ARGUMENTS : INPUT: clusterMean
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void ActiveDTWClusterModel::setClusterMean(const doubleVector& clusterMean)
+{
+ m_clusterMean = clusterMean;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getEigenValues
+* DESCRIPTION : returns the eigen values of the cluster
+* ARGUMENTS : none
+* RETURNS : eigen values
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+const doubleVector& ActiveDTWClusterModel::getEigenValues() const
+{
+ return m_eigenValues;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setEigenVectors
+* DESCRIPTION : sets the eigen vectors of the cluster
+* ARGUMENTS : eigen vectors
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void ActiveDTWClusterModel::setEigenVectors(const double2DVector& eigVec)
+{
+ m_eigenVectors = eigVec;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getEigenVectors
+* DESCRIPTION : returns the eigen vectors of the cluster
+* ARGUMENTS : none
+* RETURNS : eigen vectors
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+const double2DVector& ActiveDTWClusterModel::getEigenVectors() const
+{
+ return m_eigenVectors;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getClusterMean
+* DESCRIPTION : returns the cluster mean of the cluster
+* ARGUMENTS : none
+* RETURNS : cluster mean
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+const doubleVector& ActiveDTWClusterModel::getClusterMean() const
+{
+ return m_clusterMean;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ~ActiveDTWClusterModel
+* DESCRIPTION : Default Destructor
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWClusterModel::~ActiveDTWClusterModel()
+{
+
+}
+
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.h b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.h
new file mode 100644
index 00000000..4d183487
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWClusterModel.h
@@ -0,0 +1,161 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2011-01-11 13:48:17 +0530 (Tue, 11 Jan 2011) $
+* $Revision: 827 $
+* $Author: mnab $
+*
+************************************************************************/
+/*********************************************************************************************
+* FILE DESCR: Definitions for ActiveDTWClusterModel Class
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+* DATE:3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+***********************************************************************************************/
+
+
+#ifndef ACTIVEDTWCLUSTERMODEL_H
+#define ACTIVEDTWCLUSTERMODEL_H
+
+#include <iostream>
+#include "LTKTypes.h"
+#include "LTKInc.h"
+#include "LTKMacros.h"
+#include "LTKErrors.h"
+#include "LTKErrorsList.h"
+
+using namespace std;
+
+typedef vector<double> doubleVector;
+typedef vector<doubleVector> double2DVector;
+
+/**
+* @ingroup ActiveDTWShapeModel.h
+* @brief The Header file for the ActiveDTWShapeModel
+* @class ActiveDTWShapeModel
+*<p> <p>
+*/
+class ActiveDTWClusterModel
+{
+private:
+ int m_numberOfSamples;
+ /** @brief Number of samples in the cluster
+ * <p>
+ * Specifies the number of samples in the cluster
+ * </p>
+ */
+
+ doubleVector m_eigenValues;
+ /** @brief Eigen Values
+ * <p>
+ * Eigen values of the cluster covariance matrix
+ * </p>
+ */
+
+ double2DVector m_eigenVectors;
+ /** @brief Eigen Vectors
+ * <p>
+ * Eigen vectors of the cluster covariance matrix
+ * </p>
+ */
+
+ doubleVector m_clusterMean;
+ /** @brief Cluster mean
+ * <p>
+ * Mean of all the samples forming the cluster
+ * </p>
+ */
+
+public:
+
+ /** @name Constructors and Destructor */
+ ActiveDTWClusterModel();
+
+ ~ActiveDTWClusterModel();
+
+ /**
+ * Sets the number of samples in the cluster
+ * @param numSamples
+ * @return SUCCESS : if the number of samples was set successfully
+ * @exception EINVALID_SHAPEID
+ */
+ int setNumSamples(int numSamples);
+
+ /**
+ * Sets the eigen values of the cluser
+ * @param eigVal
+ * @return SUCCESS : if the number of samples was set successfully
+ * @exception EINVALID_SHAPEID
+ */
+ void setEigenValues(const doubleVector& eigVal);
+
+ /**
+ * Sets the eigen vectors of the cluster
+ * @param eigVec
+ * @return SUCCESS : if the number of samples was set successfully
+ * @exception EINVALID_SHAPEID
+ */
+ void setEigenVectors(const double2DVector& eigVec);
+
+ /**
+ * Sets the mean of the cluster
+ * @param clusterMean
+ * @return SUCCESS : if the number of samples was set successfully
+ * @exception EINVALID_SHAPEID
+ */
+ void setClusterMean(const doubleVector& clusterMean);
+
+ /**
+ * Returns the number of samples in the cluster
+ * @return number of samples
+ * @exception EINVALID_SHAPEID
+ */
+ int getNumSamples() const;
+
+ /**
+ * Returns the eigen values of the cluster
+ * @return eigen values
+ * @exception EINVALID_SHAPEID
+ */
+ const doubleVector& getEigenValues() const;
+
+ /**
+ * Returns the eigen vectors of the cluster
+ * @return eigen vectors
+ * @exception EINVALID_SHAPEID
+ */
+ const double2DVector& getEigenVectors() const;
+
+ /**
+ * Returns the mean of the cluster
+ * @return cluster mean
+ * @exception EINVALID_SHAPEID
+ */
+ const doubleVector& getClusterMean() const;
+
+
+};
+#endif
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.cpp b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.cpp
new file mode 100644
index 00000000..2514a626
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.cpp
@@ -0,0 +1,178 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2009-04-06 11:55:15 +0530 (Mon, 06 Apr 2009) $
+* $Revision: 758 $
+* $Author: royva $
+*
+************************************************************************/
+/*********************************************************************************************
+* FILE DESCR: Implementation for ActiveDTW Shape Model. Used to store shape model information
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+* DATE:3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+***********************************************************************************************/
+
+#include "ActiveDTWShapeModel.h"
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ActiveDTWShapeModel
+* DESCRIPTION : Default Constructor
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWShapeModel::ActiveDTWShapeModel()
+{
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setShapeId
+* DESCRIPTION : sets the shape id for the shape model
+* ARGUMENTS : INPUT: shapeId
+* RETURNS : SUCCESS - on successfully setting the shape id
+: ErrorCode - otherwise
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeModel::setShapeId(const int shapeId)
+{
+ if(shapeId >= 0)
+ {
+ m_shapeId = shapeId;
+ }
+ else
+ {
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setClusterModelVector
+* DESCRIPTION : sets the vector of clusters for the ActiveDTWShapeModel
+* ARGUMENTS : INPUT: clusterModelVector
+* RETURNS : NONE
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void ActiveDTWShapeModel::setClusterModelVector(const vector<ActiveDTWClusterModel>& clusterModelVector)
+{
+ m_clusterModelVector = clusterModelVector;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setSingletonVector
+* DESCRIPTION : sets the vector of singletons for the shape model
+* ARGUMENTS : INPUT: shapeId
+* RETURNS : NONE
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+void ActiveDTWShapeModel::setSingletonVector(const shapeMatrix& singletonVector)
+{
+ m_singletonVector = singletonVector;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getShapeId
+* DESCRIPTION : returns the shapeId of the model
+* ARGUMENTS : INPUT: NULL
+* RETURNS : shapeId
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeModel::getShapeId() const
+{
+ return m_shapeId;
+}
+
+/*************************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getClusterModelVector
+* DESCRIPTION : returns the clusters model vector
+* ARGUMENTS : INPUT: NULL
+* RETURNS : clusterModelVector
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+const vector<ActiveDTWClusterModel>& ActiveDTWShapeModel::getClusterModelVector() const
+{
+ return m_clusterModelVector;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getSingletonVector
+* DESCRIPTION : returns the set of singleton vectors
+* ARGUMENTS : INPUT: NULL
+* RETURNS : shapeMatrix
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+const shapeMatrix& ActiveDTWShapeModel::getSingletonVector() const
+{
+ return m_singletonVector;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ~ActiveDTWShapeModel
+* DESCRIPTION : Destructor
+* ARGUMENTS : NONE
+* RETURNS : NONE
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWShapeModel::~ActiveDTWShapeModel()
+{
+
+}
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.h b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.h
new file mode 100644
index 00000000..f79182ea
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeModel.h
@@ -0,0 +1,139 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2009-04-06 11:55:15 +0530 (Mon, 06 Apr 2009) $
+* $Revision: 758 $
+* $Author: royva $
+*
+************************************************************************/
+/************************************************************************
+* FILE DESCR: Definitions for ActiveDTW Shape Recognition module
+*
+* CONTENTS:
+*
+* AUTHOR:
+*
+* DATE:
+* CHANGE HISTORY:
+* Author Date Description of change
+************************************************************************/
+#ifndef ACTIVEDTWSHAPEMODEL_H
+#define ACTIVEDTWSHAPEMODEL_H
+#include <iostream>
+#include "LTKTypes.h"
+#include "ActiveDTWClusterModel.h"
+#include "LTKShapeFeatureMacros.h"
+#include "LTKShapeFeature.h"
+#include "LTKInc.h"
+
+using namespace std;
+
+typedef vector<LTKShapeFeaturePtr> shapeFeature;
+typedef vector<shapeFeature> shapeMatrix;
+
+/**
+* @ingroup ActiveDTWShapeModel.h
+* @brief The Header file for the ActiveDTWShapeModel
+* @class ActiveDTWShapeModel
+*<p> <p>
+*/
+class ActiveDTWShapeModel
+{
+private:
+ int m_shapeId;
+ /** @brief shape id of the class
+ * <p>
+ * It specifies a specific shape id to each shape model
+ * </p>
+ */
+
+ vector<ActiveDTWClusterModel> m_clusterModelVector;
+ /**< @brief vector of cluster models
+ * <p>
+ * Contains the information of all the clusters of the class
+ * </p>
+ */
+
+ shapeMatrix m_singletonVector;
+ /**< @brief singletons /free samples of the class
+ * <p>
+ * Contains all the singleton vectors of the class
+ * </p>
+ */
+
+public:
+
+ /** @name Constructors and Destructor */
+ ActiveDTWShapeModel();
+
+ ~ActiveDTWShapeModel();
+
+ /**
+ * Sets the shapeId of the class
+ * @param shapeId
+ * @return SUCCESS : if the shapeId was set successfully
+ * @exception EINVALID_SHAPEID
+ */
+ int setShapeId(const int shapeId);
+
+ /**
+ * Sets the clusterModelVector of the class
+ * @param clusterModelVector : vector<ActiveDTWClusterModel>
+ * @return NULL
+ * @exception None
+ */
+ void setClusterModelVector(const vector<ActiveDTWClusterModel>& clusterModelVector);
+
+ /**
+ * Sets the singleton vector of the class
+ * @param singletonVector : shapeMatrix
+ * @return NULL
+ * @exception None
+ */
+ void setSingletonVector(const shapeMatrix& singletonVector);
+
+ /**
+ * Returns the shapeId of the class
+ * @param None
+ * @return shapeId
+ * @exception None
+ */
+ int getShapeId() const;
+
+ /**
+ * Returns the clusterModelVector of the class
+ * @param None
+ * @return vector<ActiveDTWClusterModel>
+ * @exception None
+ */
+ const vector<ActiveDTWClusterModel>& getClusterModelVector() const;
+
+ /**
+ * Returns the singletonVector of the class
+ * @param None
+ * @return shapeMatrix
+ * @exception None
+ */
+ const shapeMatrix& getSingletonVector() const ;
+};
+
+#endif
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.cpp b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.cpp
new file mode 100644
index 00000000..247f5f98
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.cpp
@@ -0,0 +1,6257 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2011-02-08 16:57:52 +0530 (Tue, 08 Feb 2011) $
+* $Revision: 834 $
+* $Author: mnab $
+*
+************************************************************************/
+/************************************************************************
+* FILE DESCR: Implementation for ActiveDTW Shape Recognition module
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+w
+* DATE: 3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+************************************************************************/
+
+#include "LTKConfigFileReader.h"
+
+#include "ActiveDTWShapeRecognizer.h"
+
+#include "LTKPreprocDefaults.h"
+
+#include "LTKHierarchicalClustering.h"
+
+#include "LTKPreprocessorInterface.h"
+
+#include "LTKShapeFeatureExtractorFactory.h"
+
+#include "LTKShapeFeatureExtractor.h"
+
+#include "LTKShapeFeature.h"
+
+#include "LTKVersionCompatibilityCheck.h"
+
+#include "LTKInkFileWriter.h"
+#include "LTKOSUtil.h"
+#include "LTKOSUtilFactory.h"
+#include "LTKClassifierDefaults.h"
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ActiveDTWShapeRecognizer
+* DESCRIPTION : Default Constructor that initializes all data members
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+
+void ActiveDTWShapeRecognizer::assignDefaultValues()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::assignDefaultValues()" << endl;
+
+ m_numShapes = 0;
+ m_activedtwCfgFilePath = "";
+ m_activedtwMDTFilePath = "";
+ m_ptrPreproc = NULL;
+ m_projectTypeDynamic=false;
+ m_prototypeSelection=NN_DEF_PROTOTYPESELECTION;
+ m_prototypeReductionFactor=NN_DEF_PROTOTYPEREDUCTIONFACTOR;
+ m_nearestNeighbors=NN_DEF_NEARESTNEIGHBORS;
+ m_dtwBanding=NN_DEF_BANDING;
+ m_dtwEuclideanFilter= ACTIVEDTW_DEF_DTWEUCLIDEANFILTER;
+ m_preProcSeqn=NN_DEF_PREPROC_SEQ;
+ m_ptrFeatureExtractor=NULL;
+ m_featureExtractorName=NN_DEF_FEATURE_EXTRACTOR;
+ m_numClusters=NN_NUM_CLUST_INITIAL;
+ m_MDTUpdateFreq=NN_DEF_MDT_UPDATE_FREQ;
+ m_prototypeSetModifyCount=0;
+ m_rejectThreshold=NN_DEF_REJECT_THRESHOLD;
+ m_adaptivekNN=false;
+ m_deleteLTKLipiPreProcessor=NULL;
+ m_minClusterSize = ADAPT_DEF_MIN_NUMBER_SAMPLES_PER_CLASS;
+ m_percentEigenEnergy = ACTIVEDTW_DEF_PERCENTEIGENENERGY;
+ m_eigenSpreadValue = ACTIVEDTW_DEF_EIGENSPREADVALUE;
+ m_useSingleton = ACTIVEDTW_DEF_USESINGLETON;
+ m_MDTFileOpenMode = NN_MDT_OPEN_MODE_ASCII;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::assignDefaultValues()" << endl;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : initialize
+* DESCRIPTION : This method initializes the ActiveDTW shape recognizer
+* ARGUMENTS : string Holds the Project Name
+* string Holds the Profile Name
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no erros
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer(const LTKControlInfo& controlInfo):
+m_OSUtilPtr(LTKOSUtilFactory::getInstance()),
+m_libHandler(NULL),
+m_libHandlerFE(NULL)
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" << endl;
+
+ try
+ {
+ LTKControlInfo tmpControlInfo=controlInfo;
+
+ string strProjectName = "";
+ string strProfileName = "";
+
+
+ if( (tmpControlInfo.projectName).empty() )
+ {
+ throw LTKException(EINVALID_PROJECT_NAME);
+ }
+ if( (tmpControlInfo.lipiRoot).empty() )
+ {
+ throw LTKException(ELIPI_ROOT_PATH_NOT_SET);
+ }
+
+ if( (tmpControlInfo.profileName).empty() )
+ {
+ strProfileName = DEFAULT_PROFILE;
+ tmpControlInfo.profileName = strProfileName;
+ }
+
+ if ( tmpControlInfo.toolkitVersion.empty() )
+ {
+ throw LTKException(ENO_TOOLKIT_VERSION);
+ }
+
+ assignDefaultValues();
+
+ m_lipiRootPath = tmpControlInfo.lipiRoot;
+ m_lipiLibPath = tmpControlInfo.lipiLib;
+ m_currentVersion = tmpControlInfo.toolkitVersion;
+ strProjectName = tmpControlInfo.projectName;
+ strProfileName = tmpControlInfo.profileName;
+
+
+ //Model Data file Header Information
+ m_headerInfo[PROJNAME] = strProjectName;
+
+ //Holds the value of Number of Shapes in string format
+ string strNumShapes = "";
+
+ string strProfileDirectory = m_lipiRootPath + PROJECTS_PATH_STRING +
+ strProjectName + PROFILE_PATH_STRING;
+
+ //Holds the path of the Preproc.dll
+
+ //Holds the path of the Project.cfg
+ string projectCFGPath = strProfileDirectory + PROJECT_CFG_STRING;
+
+ // Config file
+
+ m_activedtwCfgFilePath = m_lipiRootPath + PROJECTS_PATH_STRING +
+ (tmpControlInfo.projectName) + PROFILE_PATH_STRING +
+ (tmpControlInfo.profileName) + SEPARATOR +
+ ACTIVEDTW + CONFIGFILEEXT;
+
+
+ //Set the path for activedtw.mdt
+ m_activedtwMDTFilePath = strProfileDirectory + strProfileName + SEPARATOR + ACTIVEDTW + DATFILEEXT;
+
+
+ //To find whether the project was dynamic or not andto read read number of shapes from project.cfg
+ int errorCode = m_shapeRecUtil.isProjectDynamic(projectCFGPath,
+ m_numShapes, strNumShapes, m_projectTypeDynamic);
+
+ if( errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" <<endl;
+ throw LTKException(errorCode);
+ }
+
+ //Set the NumShapes to the m_headerInfo
+ m_headerInfo[NUMSHAPES] = strNumShapes;
+
+ //Currently preproc cfg also present in ActiveDTW
+ tmpControlInfo.cfgFileName = ACTIVEDTW;
+ errorCode = initializePreprocessor(tmpControlInfo,&m_ptrPreproc);
+
+
+ if( errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" <<endl;
+ throw LTKException(errorCode);
+ }
+
+ //Reading ActiveDTW configuration file
+ errorCode = readClassifierConfig();
+
+
+ if( errorCode != SUCCESS)
+ {
+
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" <<endl;
+ throw LTKException(errorCode);
+ }
+
+ //Writing Feature extractor name and version into the header
+ m_headerInfo[FE_NAME] = m_featureExtractorName;
+ //FE version
+ m_headerInfo[FE_VER] = SUPPORTED_MIN_VERSION;
+
+ //Writing mdt file open mode to the mdt header
+ m_headerInfo[MDT_FOPEN_MODE] = m_MDTFileOpenMode;
+
+ errorCode = initializeFeatureExtractorInstance(tmpControlInfo);
+
+
+ if( errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" <<endl;
+ throw LTKException(errorCode);
+ }
+ }
+ catch(LTKException e)
+ {
+ deletePreprocessor();
+ m_prototypeShapes.clear();
+
+ m_cachedShapeFeature.clear();
+
+ //Unloading the feature Extractor instance
+ deleteFeatureExtractorInstance();
+
+ delete m_OSUtilPtr;
+ throw e;
+ }
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::ActiveDTWShapeRecognizer()" << endl;
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : readClassifierConfig
+* DESCRIPTION : Reads the ActiveDTW.cfg and initializes the data members of the class
+* ARGUMENTS : none
+* RETURNS : SUCCESS - If config file read successfully
+* errorCode - If failure
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::readClassifierConfig()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::readClassifierConfig()" << endl;
+ string tempStringVar = "";
+ int tempIntegerVar = 0;
+ float tempFloatVar = 0.0;
+ LTKConfigFileReader *shapeRecognizerProperties = NULL;
+ int errorCode = FAILURE;
+
+ try
+ {
+ shapeRecognizerProperties = new LTKConfigFileReader(m_activedtwCfgFilePath);
+ }
+ catch(LTKException e)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)<< "Info: " <<
+ "Config file not found, using default values of the parameters" <<
+ "ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ delete shapeRecognizerProperties;
+
+ return FAILURE;
+ }
+
+ //Pre-processing sequence
+ errorCode = shapeRecognizerProperties->getConfigValue(PREPROCSEQUENCE, m_preProcSeqn);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO) << "Info: " <<
+ "Using default value of prerocessing sequence: "<< m_preProcSeqn <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ m_preProcSeqn = NN_DEF_PREPROC_SEQ;
+ }
+ else
+ {
+ m_headerInfo[PREPROC_SEQ] = m_preProcSeqn;
+ }
+
+
+ if((errorCode = mapPreprocFunctions()) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<" Error: " << errorCode << " " <<
+ "ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ delete shapeRecognizerProperties;
+
+ LTKReturnError(errorCode);
+ }
+
+ //reading percent of eigen energy
+ tempStringVar = "";
+
+ errorCode = shapeRecognizerProperties->getConfigValue(RETAINPERCENTEIGENENERGY,
+ tempStringVar);
+ if(errorCode == SUCCESS )
+ {
+ if (LTKStringUtil::isFloat(tempStringVar))
+ {
+ tempFloatVar = LTKStringUtil::convertStringToFloat(tempStringVar);
+
+ if(tempFloatVar >= MIN_PERCENT_EIGEN_ENERGY && tempFloatVar <= MAX_PERCENT_EIGEN_ENERGY)
+ {
+ m_percentEigenEnergy = tempFloatVar;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ RETAINPERCENTEIGENENERGY " = " << m_percentEigenEnergy<< endl;
+
+
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE << " " << RETAINPERCENTEIGENENERGY
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE << " " << RETAINPERCENTEIGENENERGY
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()" << endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) <<
+ "Using default value for " << RETAINPERCENTEIGENENERGY << ": " <<
+ m_percentEigenEnergy << " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ }
+
+ //reading method of prototype selection
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(PROTOTYPESELECTION,
+ tempStringVar);
+
+ if (errorCode == SUCCESS)
+ {
+ if( (LTKSTRCMP(tempStringVar.c_str(), PROTOTYPE_SELECTION_CLUSTERING) == 0))
+ {
+ m_prototypeSelection = tempStringVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) <<
+ PROTOTYPESELECTION << " = " << tempStringVar <<
+ "ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE << " " <<
+ PROTOTYPESELECTION << " : " << tempStringVar
+ << " method is not supported" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << PROTOTYPESELECTION << " : " << m_prototypeSelection <<
+ " ActiveDTwShapeRecognizer::readClassifierConfig()"<<endl;
+ }
+
+ //reading prototype reduction factor
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(PROTOREDFACTOR,
+ tempStringVar);
+
+ string tempStringVar1 = "";
+ int errorCode1 = shapeRecognizerProperties->getConfigValue(NUMCLUSTERS,
+ tempStringVar1);
+
+ //prototype reduction factor
+ if(errorCode1 == SUCCESS && errorCode == SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE
+ << " Cannot use both config parameters " <<
+ PROTOREDFACTOR << " and " << NUMCLUSTERS << " at the same time "<<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+
+ if(tempStringVar != "")
+ {
+ if(LTKSTRCMP(tempStringVar.c_str(), PROTO_RED_FACTOR_AUTOMATIC)==0)
+ {
+ //DEFINE MACRO DEF_PROTO_RED_FACTOR
+ m_prototypeReductionFactor = -1;
+ }
+ else if(LTKSTRCMP(tempStringVar.c_str(), PROTO_RED_FACTOR_NONE)==0)
+ {
+ m_prototypeReductionFactor = 0;
+ }
+ else if(LTKSTRCMP(tempStringVar.c_str(), PROTO_RED_FACTOR_COMPLETE) == 0)
+ {
+ m_prototypeReductionFactor = 100;
+ }
+ else
+ {
+ if ( LTKStringUtil::isInteger(tempStringVar) )
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+ if(tempIntegerVar >= 0 && tempIntegerVar <=100)
+ {
+ m_prototypeReductionFactor = tempIntegerVar;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ << PROTOREDFACTOR << " is =" << tempStringVar<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE <<
+ PROTOREDFACTOR << " is out of permitted range " <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: " << ECONFIG_FILE_RANGE <<
+ PROTOREDFACTOR << " is out of permitted range"<<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+
+ }
+ }
+ else if(tempStringVar1 != "")
+ {
+ if(LTKSTRCMP(tempStringVar1.c_str(), PROTO_RED_FACTOR_AUTOMATIC) == 0)
+ {
+ m_prototypeReductionFactor = -1;
+ }
+ else
+ {
+ if ( LTKStringUtil::isInteger(tempStringVar1) )
+ {
+ tempIntegerVar = atoi((tempStringVar1).c_str());
+ if(tempIntegerVar > 0)
+ {
+ m_numClusters = tempIntegerVar;
+
+ // m_numClusters is used in this case
+ m_prototypeReductionFactor = NN_NUM_CLUST_INITIAL;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ NUMCLUSTERS << " is = " << tempStringVar << endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE <<
+ NUMCLUSTERS << " is out of permitted range "<<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ " Error: " << ECONFIG_FILE_RANGE <<
+ NUMCLUSTERS << " is out of permitted range"<<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Assuming default value of " NUMCLUSTERS << " : " << m_numClusters << endl;
+ }
+
+ //reading adaptive kNN
+ tempStringVar = "";
+ shapeRecognizerProperties->getConfigValue(ADAPTIVE_kNN, tempStringVar);
+ if(LTKSTRCMP(tempStringVar.c_str(), "true") ==0)
+ {
+ m_adaptivekNN = true;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Confidence computation method: " << ADAPTIVE_kNN << endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << ADAPTIVE_kNN << " : " <<
+ m_adaptivekNN << endl;
+ }
+
+ //reading nearest neighbors
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(NEARESTNEIGHBORS,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ if ( LTKStringUtil::isInteger(tempStringVar) )
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+
+ //Valid values of nearest neighbors: 1 or greater than MIN_NEARESTNEIGHBORS
+ if(tempIntegerVar > 0)
+ {
+ // If the value of NearestNeighbors = 1, ActiveDTW recognizer is used
+ if(tempIntegerVar == 1)
+ {
+ m_adaptivekNN = false;
+ }
+
+ // If AdaptivekNN is set to false, simply assign the value to m_nearestNeighbors
+ // If AdaptivekNN is set, NearestNeighbors should be greater than than the
+ // minimum no.of nearest neighbors allowed (MIN_NEARESTNEIGHBORS defined as macro)
+ if(!m_adaptivekNN || (m_adaptivekNN && tempIntegerVar >= MIN_NEARESTNEIGHBORS))
+ {
+ m_nearestNeighbors = tempIntegerVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ NEARESTNEIGHBORS << " = " <<m_nearestNeighbors<<endl;
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << NEARESTNEIGHBORS <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << NEARESTNEIGHBORS <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Debug: " << "Using default value for " << NEARESTNEIGHBORS <<
+ " : " << m_nearestNeighbors << endl;
+ }
+
+ //reading reject threshold
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(REJECT_THRESHOLD,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ if ( LTKStringUtil::isFloat(tempStringVar) )
+ {
+ tempFloatVar = LTKStringUtil::convertStringToFloat(tempStringVar);
+
+ if(tempFloatVar > 0 && tempFloatVar < 1)
+ {
+ m_rejectThreshold = tempFloatVar;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ REJECT_THRESHOLD << " = " <<tempStringVar <<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << REJECT_THRESHOLD <<
+ " should be in the range (0-1)" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << REJECT_THRESHOLD <<
+ " should be in the range (0-1)" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << REJECT_THRESHOLD <<
+ " : " << m_rejectThreshold << endl;
+ }
+
+ //reading min cluster Size
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(MINCLUSTERSIZE,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ if(LTKStringUtil::isInteger(tempStringVar))
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+
+ if(tempIntegerVar > 1)
+ {
+ m_minClusterSize = tempIntegerVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ MINCLUSTERSIZE << " = " <<m_minClusterSize<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << m_minClusterSize <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << MINCLUSTERSIZE <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << MINCLUSTERSIZE << " : " << m_minClusterSize << endl;
+ }
+
+ //reading eigen spread value
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(EIGENSPREADVALUE,
+ tempStringVar);
+
+
+
+ if(errorCode == SUCCESS)
+ {
+ if(LTKStringUtil::isInteger(tempStringVar))
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+
+ if(tempIntegerVar > 0)
+ {
+ m_eigenSpreadValue = tempIntegerVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ EIGENSPREADVALUE << " = " <<m_eigenSpreadValue<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << EIGENSPREADVALUE <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << EIGENSPREADVALUE <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << EIGENSPREADVALUE << " : " << m_eigenSpreadValue << endl;
+ }
+
+ //reading use singleton
+ tempStringVar = "";
+ shapeRecognizerProperties->getConfigValue(USESINGLETON, tempStringVar);
+ if(LTKSTRCMP(tempStringVar.c_str(), "false") ==0)
+ {
+ m_useSingleton = false;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Use Singleton: " << USESINGLETON << endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << USESINGLETON << " : " <<
+ m_useSingleton << endl;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(DTWBANDING,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ if ( LTKStringUtil::isFloat(tempStringVar) )
+ {
+ tempFloatVar = LTKStringUtil::convertStringToFloat(tempStringVar);
+
+ if(tempFloatVar > 0 && tempFloatVar <= 1)
+ {
+ m_dtwBanding = tempFloatVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ DTWBANDING << " = " <<m_dtwBanding<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE << DTWBANDING <<
+ " is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: "<< ECONFIG_FILE_RANGE <<
+ " DTWBANDING is out of permitted range" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << DTWBANDING << " : " << m_dtwBanding << endl;
+ }
+
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(DTWEUCLIDEANFILTER,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ if(LTKSTRCMP(tempStringVar.c_str(), DTW_EU_FILTER_ALL) == 0)
+ {
+ m_dtwEuclideanFilter = EUCLIDEAN_FILTER_OFF;
+ }
+
+ else
+ {
+ if ( LTKStringUtil::isInteger(tempStringVar) )
+ {
+ tempIntegerVar = atoi((tempStringVar).c_str());
+
+ if(tempIntegerVar > 0 && tempIntegerVar <= 100)
+ {
+ if(tempIntegerVar == 100 )
+ m_dtwEuclideanFilter = EUCLIDEAN_FILTER_OFF;
+ else
+ m_dtwEuclideanFilter = tempIntegerVar;
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ DTWEUCLIDEANFILTER << " is = "<<
+ m_dtwEuclideanFilter<<endl;
+ }
+ else
+ {
+
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE <<
+ DTWEUCLIDEANFILTER << " is out of permitted range " <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ delete shapeRecognizerProperties;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << DTWEUCLIDEANFILTER <<
+ " is out of permitted range"<<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << DTWEUCLIDEANFILTER <<
+ " : " << m_dtwEuclideanFilter << endl;
+ }
+
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(FEATUREEXTRACTOR,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ m_featureExtractorName = tempStringVar;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ FEATUREEXTRACTOR << " = "<<tempStringVar<<endl;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << FEATUREEXTRACTOR << " : " <<
+ m_featureExtractorName << endl;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(MDTFILEUPDATEFREQ,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ if ( LTKStringUtil::isInteger(tempStringVar) )
+ {
+ m_MDTUpdateFreq = atoi(tempStringVar.c_str());
+ if(m_MDTUpdateFreq <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << MDTFILEUPDATEFREQ <<
+ " should be zero or a positive integer" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << MDTFILEUPDATEFREQ <<
+ " should be zero or a positive integer" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << MDT_UPDATE_FREQUENCY <<
+ " : " << m_MDTUpdateFreq << endl;
+ }
+
+
+
+ //reading mdt file open mode
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(MDT_FILE_OPEN_MODE,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ if ( tempStringVar == NN_MDT_OPEN_MODE_ASCII ||
+ tempStringVar == NN_MDT_OPEN_MODE_BINARY )
+ {
+ m_MDTFileOpenMode = tempStringVar;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<
+ "Error: " << ECONFIG_FILE_RANGE << MDT_FILE_OPEN_MODE <<
+ " should be ascii or binary" <<
+ " ActiveDTWShapeRecognizer::readClassifierConfig()"<<endl;
+
+ delete shapeRecognizerProperties;
+
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<
+ "Using default value for " << MDT_FILE_OPEN_MODE <<
+ " : " << m_MDTFileOpenMode << endl;
+ }
+
+
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(SIZETHRESHOLD,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[DOT_SIZE_THRES] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(ASPECTRATIOTHRESHOLD,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[ASP_RATIO_THRES] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(DOTTHRESHOLD,
+ tempStringVar);
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[DOT_THRES] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(PRESERVERELATIVEYPOSITION,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[PRESER_REL_Y_POS] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(PRESERVEASPECTRATIO,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[PRESER_ASP_RATIO] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(SIZETHRESHOLD,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[NORM_LN_WID_THRES] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(RESAMPLINGMETHOD,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[RESAMP_POINT_ALLOC] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ errorCode = shapeRecognizerProperties->getConfigValue(SMOOTHFILTERLENGTH,
+ tempStringVar);
+
+ if(errorCode == SUCCESS)
+ {
+ m_headerInfo[SMOOTH_WIND_SIZE] = tempStringVar;
+ }
+
+ tempStringVar = "";
+ LTKStringUtil::convertIntegerToString(m_ptrPreproc->getTraceDimension(),
+ tempStringVar);
+
+
+ m_headerInfo[TRACE_DIM] = tempStringVar;
+
+ delete shapeRecognizerProperties;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::readClassifierConfig()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : mapPreprocFunctions
+* DESCRIPTION : Maps the module name and its function names in the preprocessing
+sequence.
+* ARGUMENTS : none
+* RETURNS : SUCCESS on successful,
+* errorNumbers on Failure.
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::mapPreprocFunctions()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::mapPreprocFunctions()" << endl;
+
+ stringStringMap preProcSequence;
+
+ stringStringPair tmpPair;
+
+ stringVector moduleFuncNames;
+ stringVector modFuncs;
+ stringVector funcNameTokens;
+
+ string module = "", funName = "", sequence = "";
+ string::size_type indx;
+
+ LTKTraceGroup local_inTraceGroup;
+
+ LTKStringUtil::tokenizeString(m_preProcSeqn, DELEMITER_SEQUENCE, funcNameTokens);
+
+ int numFunctions = funcNameTokens.size();
+
+ if(numFunctions == 0)
+ {
+ LOG( LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<
+ "Wrong preprocessor sequence in cfg file : " + m_preProcSeqn <<
+ " ActiveDTWShapeRecognizer::mapPreprocFunctions()"<<endl;
+
+ LTKReturnError(EINVALID_PREPROC_SEQUENCE);
+ }
+
+ for (indx = 0; indx < numFunctions ; indx++)
+ {
+ moduleFuncNames.push_back(funcNameTokens[indx]);
+ }
+
+ int numModuleFunctions = moduleFuncNames.size();
+
+ for(indx=0; indx < numModuleFunctions ; indx++)
+ {
+ sequence = moduleFuncNames[indx];
+
+ LTKStringUtil::tokenizeString(sequence, DELEMITER_FUNC, modFuncs);
+
+ if(modFuncs.size() >= 2)
+ {
+ module = modFuncs.at(0);
+
+ funName = modFuncs.at(1);
+
+ if(!module.compare("CommonPreProc"))
+ {
+ FN_PTR_PREPROCESSOR pPreprocFunc = NULL;
+ pPreprocFunc = m_ptrPreproc->getPreprocptr(funName);
+ if(pPreprocFunc!= NULL)
+ {
+ tmpPair.first = module;
+ tmpPair.second = funName;
+ m_preprocSequence.push_back(tmpPair);
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_PREPROC_SEQUENCE << " " <<
+ "Wrong preprocessor sequence entry in cfg file : " <<funName<<
+ " ActiveDTWShapeRecognizer::mapPreprocFunctions()"<<endl;
+ LTKReturnError(EINVALID_PREPROC_SEQUENCE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_PREPROC_SEQUENCE << " " <<
+ "Wrong preprocessor sequence entry in cfg file : " << module<<
+ " ActiveDTWShapeRecognizer::mapPreprocFunctions()"<<endl;
+ LTKReturnError(EINVALID_PREPROC_SEQUENCE);
+ }
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_PREPROC_SEQUENCE << " " <<
+ "Wrong preprocessor sequence entry in cfg file : "<<module<<
+ " ActiveDTWShapeRecognizer::mapPreprocFunctions()"<<endl;
+ LTKReturnError(EINVALID_PREPROC_SEQUENCE);
+ }
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::mapPreprocFunctions()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : ~ActiveDTWShapeRecognizer
+* DESCRIPTION : destructor
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()" << endl;
+
+ int returnStatus = SUCCESS;
+
+ if(LTKAdapt::getInstance(this))
+ deleteAdaptInstance();
+
+ if(m_prototypeSetModifyCount >0)
+ {
+ m_prototypeSetModifyCount = m_MDTUpdateFreq-1;
+
+ returnStatus = writePrototypeShapesToMDTFile();
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()" << endl;
+ throw LTKException(returnStatus);
+ }
+ }
+
+ m_neighborInfoVec.clear();
+
+ returnStatus = deletePreprocessor();
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()" << endl;
+ throw LTKException(returnStatus);
+ }
+
+ m_prototypeShapes.clear();
+ m_cachedShapeFeature.clear();
+
+ //Unloading the feature Extractor instance
+ returnStatus = deleteFeatureExtractorInstance();
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()" << endl;
+ throw LTKException(returnStatus);
+ }
+
+ delete m_OSUtilPtr;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::~ActiveDTWShapeRecognizer()" << endl;
+}
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : train
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::train(const string& trainingInputFilePath,
+ const string& mdtHeaderFilePath,
+ const string &comment,const string &dataset,
+ const string &trainFileType)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::train()" << endl;
+
+
+
+ int returnStatus = SUCCESS;
+
+
+ if(comment.empty() != true)
+ {
+ m_headerInfo[COMMENT] = comment;
+ }
+
+ if(dataset.empty() != true)
+ {
+ m_headerInfo[DATASET] = dataset;
+ }
+
+
+ if(LTKSTRCMP(m_prototypeSelection.c_str(), PROTOTYPE_SELECTION_CLUSTERING) == 0)
+ {
+ returnStatus = trainClustering(trainingInputFilePath,
+ mdtHeaderFilePath,
+ trainFileType);
+
+ if(returnStatus != SUCCESS)
+ {
+ LTKReturnError(returnStatus);
+ }
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::train()" << endl;
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : trainClustering
+* DESCRIPTION : This function is the train method using Clustering prototype
+* selection technique.
+* ARGUMENTS :
+* RETURNS : SUCCESS : if training done successfully
+* errorCode : if traininhas some errors
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::trainClustering(const string& trainingInputFilePath,
+ const string &mdtHeaderFilePath,
+ const string& inFileType)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::trainClustering()" << endl;
+
+
+ //Time at the beginning of Train Clustering
+ m_OSUtilPtr->recordStartTime();
+
+ int returnStatus = SUCCESS;
+
+ if(LTKSTRCMP(inFileType.c_str(), INK_FILE) == 0)
+ {
+ //If the Input file is UNIPEN Ink file
+ returnStatus = trainFromListFile(trainingInputFilePath);
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Error: " <<
+ getErrorMessage(returnStatus) <<
+ " ActiveDTWShapeRecognizer::trainClustering()" << endl;
+ LTKReturnError(returnStatus);
+ }
+ }
+
+
+ //Updating the Header Information
+ updateHeaderWithAlgoInfo();
+
+ //Adding header information and checksum generation
+ LTKCheckSumGenerate cheSumGen;
+
+ returnStatus = cheSumGen.addHeaderInfo(mdtHeaderFilePath,
+ m_activedtwMDTFilePath,
+ m_headerInfo);
+
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Error: " <<
+ getErrorMessage(returnStatus) <<
+ " ActiveDTWShapeRecognizer::trainClustering()" << endl;
+
+ LTKReturnError(returnStatus);
+ }
+
+ //Time at the end of Train Clustering
+ m_OSUtilPtr->recordEndTime();
+
+ string timeTaken = "";
+ m_OSUtilPtr->diffTime(timeTaken);
+
+ cout << "Time Taken = " << timeTaken << endl;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::trainClustering()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : appendShapeModelToMDTFile
+* DESCRIPTION : This method is called after performing clustering on each class
+It writes the class information to the activedtw.mdt file
+* ARGUMENTS : INPUT
+shapeModel struct ActiveDTWShapeModel (class training data)
+mdtFileHandle ofstream (mdt File handle)
+
+ * RETURNS : integer Holds error value if occurs
+ * Holds SUCCESS if no erros
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::appendShapeModelToMDTFile(const ActiveDTWShapeModel& shapeModel,ofstream& mdtFileHandle)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::appendShapeModelToMDTFile()" << endl;
+
+
+ //used to temporarily store the size of a vector
+ int vecSize;
+ if(!mdtFileHandle)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_FILE_HANDLE << " " <<
+ "Invalid file handle for MDT file"<<
+ " ActiveDTWShapeRecognizer::appendShapeModelToMDTFile()" << endl;
+ LTKReturnError(EINVALID_FILE_HANDLE);
+ }
+
+ string strFeature;
+
+ vector<ActiveDTWClusterModel> clusterModelVector = shapeModel.getClusterModelVector();
+ vector<ActiveDTWClusterModel>::iterator iStart = clusterModelVector.begin();
+ vector<ActiveDTWClusterModel>::iterator iEnd = clusterModelVector.end();
+ double2DVector eigenVectors;
+ doubleVector eigenValues;
+ doubleVector clusterMean;
+ shapeMatrix singletonVector = shapeModel.getSingletonVector();
+ ActiveDTWClusterModel clusterModel;
+
+ /**APPENDING CLASS INFORMATION**/
+ //APPENDING CLASSID NUMCLUSTERS NUMSINGLETONS
+ if(m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII)
+ {
+ mdtFileHandle<<shapeModel.getShapeId()<<" "<<clusterModelVector.size()<<" "<<singletonVector.size()<<endl;
+ }
+ else
+ {
+ int clusterSize = clusterModelVector.size();
+ int singletonSize = singletonVector.size();
+ int shapeId = shapeModel.getShapeId();
+ int numFeatures;
+ int featureDimension;
+ int clusterMeanDimension;
+ mdtFileHandle.write((char*) &shapeId,sizeof(int));
+ mdtFileHandle.write((char*) &clusterSize,sizeof(int));
+ mdtFileHandle.write((char*) &singletonSize,sizeof(int));
+
+ if(clusterSize != 0)
+ {
+ clusterMean = clusterModelVector[0].getClusterMean();
+ clusterMeanDimension = clusterMean.size();
+ mdtFileHandle.write((char*) &clusterMeanDimension,sizeof(int));
+ }
+ else
+ {
+ clusterMeanDimension = 0;
+ mdtFileHandle.write((char*) &clusterMeanDimension,sizeof(int));
+ }
+
+ //writing number of features and feature dimension
+ if(singletonSize != 0)
+ {
+ numFeatures = singletonVector[0].size();
+ mdtFileHandle.write((char*) &numFeatures,sizeof(int));
+ featureDimension = singletonVector[0][0]->getFeatureDimension();
+ mdtFileHandle.write((char*) &featureDimension,sizeof(int));
+ }
+ else
+ {
+ numFeatures = 0;
+ mdtFileHandle.write((char*) &numFeatures,sizeof(int));
+ featureDimension = 0;
+ mdtFileHandle.write((char*) &featureDimension,sizeof(int));
+ }
+
+ }
+
+ /**APPENDING CLUSTER DATA**/
+ //iterating through the cluster models
+
+ for(;iStart != iEnd; ++iStart)
+ {
+
+ clusterModel = *iStart;
+
+
+ //appending number of clusters in each sample
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle<<clusterModel.getNumSamples()<<" ";
+ }
+ else
+ {
+ int numSamples = clusterModel.getNumSamples();
+ mdtFileHandle.write((char*) &numSamples,sizeof(int));
+ }
+
+
+ eigenValues = clusterModel.getEigenValues();
+ vecSize = eigenValues.size();
+
+ /**WRITING EIGEN VALUES**/
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ for(int i = 0; i < vecSize; i++)
+ {
+ mdtFileHandle<<eigenValues[i];
+ if(i != (vecSize - 1))
+ {
+ mdtFileHandle<<",";
+ }
+ }
+ mdtFileHandle<<FEATURE_EXTRACTOR_DELIMITER;
+ }
+ else
+ {
+ //writing number of eigen values
+ mdtFileHandle.write((char*) &vecSize,sizeof(int));
+
+ //writing eigenValues
+ for(int i = 0; i < vecSize; i++)
+ {
+ mdtFileHandle.write((char*) &(eigenValues[i]),sizeof(double));
+ }
+ }
+
+ /**WRITING EIGEN VECTORS**/
+
+ eigenVectors = clusterModel.getEigenVectors();
+ vecSize = eigenVectors[0].size();
+ int eigVecSize = eigenVectors.size();
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ for(int i = 0; i < eigVecSize; i++)
+ {
+ for(int j = 0; j < vecSize; j++)
+ {
+ mdtFileHandle<<eigenVectors[i][j];
+ if(j != (vecSize - 1))
+ {
+ mdtFileHandle<<",";
+ }
+ }
+ mdtFileHandle<<FEATURE_EXTRACTOR_DELIMITER;
+ }
+ }
+ else
+ {
+ for(int i = 0; i < eigVecSize; i++)
+ {
+ for(int j = 0; j < vecSize; j++)
+ {
+ mdtFileHandle.write((char*) &(eigenVectors[i][j]),sizeof(double));
+ }
+ }
+ }
+
+ /**APPENDING CLUSTER MEAN**/
+
+ clusterMean = clusterModel.getClusterMean();
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ for(int i = 0; i < vecSize; i++)
+ {
+ mdtFileHandle<<clusterMean[i];
+ if(i != (vecSize - 1))
+ {
+ mdtFileHandle<<",";
+ }
+
+ }
+ mdtFileHandle<<FEATURE_EXTRACTOR_DELIMITER<<endl;
+ }
+ else
+ {
+ for(int i = 0; i < vecSize; i++)
+ {
+ mdtFileHandle.write((char*) &(clusterMean[i]),sizeof(double));
+ }
+ }
+
+ eigenVectors.clear();
+ eigenValues.clear();
+ clusterMean.clear();
+
+ }
+ clusterModelVector.clear();
+
+ /**WRITING SINGLETON VECTORS**/
+ shapeMatrix::iterator iterStart = singletonVector.begin();
+ shapeMatrix::iterator iterEnd = singletonVector.end();
+ shapeFeature singleton;
+
+ for(; iterStart != iterEnd; ++iterStart )
+ {
+
+ singleton = *iterStart;
+
+ vecSize = singleton.size();
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ vector<LTKShapeFeaturePtr>::const_iterator shapeFeatureIter = singleton.begin();
+ vector<LTKShapeFeaturePtr>::const_iterator shapeFeatureIterEnd = singleton.end();
+
+ for(; shapeFeatureIter != shapeFeatureIterEnd; ++shapeFeatureIter)
+ {
+ (*shapeFeatureIter)->toString(strFeature);
+ mdtFileHandle << strFeature << FEATURE_EXTRACTOR_DELIMITER;
+ }
+ mdtFileHandle<<endl;
+
+ }
+ else
+ {
+
+ //converting the singleton vector to float and writing it
+ floatVector floatFeatureVector;
+ int errorCode = m_shapeRecUtil.shapeFeatureVectorToFloatVector(singleton,
+ floatFeatureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<errorCode<<
+ " ActiveDTWShapeRecognizer::appendShapeModelToMDTFile" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ vecSize = floatFeatureVector.size();
+
+
+ for (int i=0; i< vecSize; i++)
+ {
+ float floatValue = floatFeatureVector[i];
+ mdtFileHandle.write((char *)(&floatValue), sizeof(float));
+ }
+ }
+ }
+
+ singletonVector.clear();
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::appendShapeModelToMDTFile()" << endl;
+
+ return SUCCESS;
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : preprocess
+* DESCRIPTION : calls the required pre-processing functions from the LTKPreprocessor library
+* ARGUMENTS : inTraceGroup - reference to the input trace group
+* outPreprocessedTraceGroup - pre-processed inTraceGroup
+* RETURNS : SUCCESS on successful pre-processing operation
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::preprocess (const LTKTraceGroup& inTraceGroup,
+ LTKTraceGroup& outPreprocessedTraceGroup)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::preprocess()" << endl;
+
+ int indx = 0;
+ int errorCode = -1;
+
+ string module = "";
+ string funName = "" ;
+
+ LTKTraceGroup local_inTraceGroup;
+
+ local_inTraceGroup = inTraceGroup;
+
+ if(m_preprocSequence.size() != 0)
+ {
+ while(indx < m_preprocSequence.size())
+ {
+ module = m_preprocSequence.at(indx).first;
+ funName = m_preprocSequence.at(indx).second;
+
+ FN_PTR_PREPROCESSOR pPreprocFunc = NULL;
+ pPreprocFunc = m_ptrPreproc->getPreprocptr(funName);
+
+ if(pPreprocFunc!= NULL)
+ {
+ outPreprocessedTraceGroup.emptyAllTraces();
+
+
+ if((errorCode = (m_ptrPreproc->*(pPreprocFunc))
+ (local_inTraceGroup,outPreprocessedTraceGroup)) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::preprocess()" << endl;
+ LTKReturnError(errorCode);
+ }
+ local_inTraceGroup = outPreprocessedTraceGroup;
+ }
+ indx++;
+ }
+ }
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Exiting ActiveDTWShapeRecognizer::preprocess()"<<endl;
+ return SUCCESS;
+}
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computerDTWDistanceClusteringWrapper
+* DESCRIPTION : Wrapper function to the function whichcomputes DTW distance between
+two characters
+* ARGUMENTS : train character, test character
+* RETURNS : DTWDistance
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::computeDTWDistance(
+ const LTKShapeSample& inFirstShapeSampleFeatures,
+ const LTKShapeSample& inSecondShapeSampleFeatures,
+ float& outDTWDistance)
+
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+
+ const vector<LTKShapeFeaturePtr>& firstFeatureVec = inFirstShapeSampleFeatures.getFeatureVector();
+ const vector<LTKShapeFeaturePtr>& secondFeatureVec = inSecondShapeSampleFeatures.getFeatureVector();
+
+ int errorCode = m_dtwObj.computeDTW(firstFeatureVec, secondFeatureVec, getDistance,outDTWDistance,
+ m_dtwBanding, FLT_MAX, FLT_MAX);
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "DTWDistance: " <<
+ outDTWDistance << endl;
+
+ if (errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Error: "<<
+ getErrorMessage(errorCode) <<
+ " ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computeDTWDistance
+* DESCRIPTION : This method computes the dtw distance between two shape features
+* ARGUMENTS : INPUT
+inFirstFeatureVector vector<LTKShapeFeaturePtr>
+inSecondFeatureVector vector<LTKShapeFeaturePtr>
+: OUTPUT
+outDTWDistance float
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::computeDTWDistance(
+ const vector<LTKShapeFeaturePtr>& inFirstFeatureVector,
+ const vector<LTKShapeFeaturePtr>& inSecondFeatureVector,
+ float& outDTWDistance)
+
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+
+ int errorCode = m_dtwObj.computeDTW(inFirstFeatureVector, inSecondFeatureVector, getDistance,outDTWDistance,
+ m_dtwBanding, FLT_MAX, FLT_MAX);
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "DTWDistance: " <<
+ outDTWDistance << endl;
+
+ if (errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Error: "<<
+ getErrorMessage(errorCode) <<
+ " ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeDTWDistance()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computeEuclideanDistance
+* DESCRIPTION : This computes the euclideanDistance between two shapeFeatures
+* ARGUMENTS : INPUT
+inFirstFeature shapeFeature
+inSecondFeature shapeFeature
+:OUTPUT
+outEuclideanDistance floats
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::computeEuclideanDistance(
+ const shapeFeature& inFirstFeature,
+ const shapeFeature& inSecondFeature,
+ float& outEuclideanDistance)
+{
+ int firstFeatureVectorSize = inFirstFeature.size();
+ int secondFeatureVectorSize = inSecondFeature.size();
+
+ if(firstFeatureVectorSize != secondFeatureVectorSize)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EUNEQUAL_LENGTH_VECTORS << " " <<
+ getErrorMessage(EUNEQUAL_LENGTH_VECTORS) <<
+ " ActiveDTWShapeRecognizer::computeEuclideanDistance()" << endl;
+
+ LTKReturnError(EUNEQUAL_LENGTH_VECTORS);
+ }
+
+ for(int i = 0; i < firstFeatureVectorSize; ++i)
+ {
+ float tempDistance = 0.0;
+ getDistance(inFirstFeature[i],
+ inSecondFeature[i],
+ tempDistance);
+
+ outEuclideanDistance += tempDistance;
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeEuclideanDistance()" << endl;
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : loadModelData
+* DESCRIPTION : loads the reference model file into memory
+* ARGUMENTS :
+* RETURNS : SUCCESS on successful loading of the reference model file
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::loadModelData()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::loadModelData()" << endl;
+
+ int errorCode = -1;
+
+ int numofShapes = 0;
+
+ // variable for shape Id
+ int classId = -1;
+ int i = 0;
+
+ //Algorithm version
+ string algoVersionReadFromMDT = "";
+
+ stringStringMap headerSequence;
+ LTKCheckSumGenerate cheSumGen;
+
+ if(errorCode = cheSumGen.readMDTHeader(m_activedtwMDTFilePath,headerSequence))
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ // printing the headerseqn
+ stringStringMap::const_iterator iter = headerSequence.begin();
+ stringStringMap::const_iterator endIter = headerSequence.end();
+
+ for(; iter != endIter; iter++)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"Debug: header seqn"<<
+ iter->first << " : " <<
+ iter->second << endl;
+ }
+
+ string featureExtractor = headerSequence[FE_NAME];
+
+ if(LTKSTRCMP(m_featureExtractorName.c_str(), featureExtractor.c_str()) != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of FeatureExtractor parameter in config file ("<<
+ m_featureExtractorName<<") does not match with the value in MDT file ("<<
+ featureExtractor<<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+ string feVersion = headerSequence[FE_VER];
+
+ // comparing the mdt open mode read from cfg file with value in the mdt header
+ string mdtOpenMode = headerSequence[MDT_FOPEN_MODE];
+
+ if (LTKSTRCMP(m_MDTFileOpenMode.c_str(), mdtOpenMode.c_str()) != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of ActiveDTWMDTFileOpenMode parameter in config file ("<<
+ m_MDTFileOpenMode <<") does not match with the value in MDT file ("<<
+ mdtOpenMode<<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+ // validating preproc parameters
+ int iErrorCode = validatePreprocParameters(headerSequence);
+ if (iErrorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Values of ActiveMDTMDTFileOpenMode parameter in config file does not match with "
+ <<"the values in MDT file " << "ActiveDTWShapeRecognizer::loadModelData()" << endl;
+
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+ // Version comparison START
+ algoVersionReadFromMDT = headerSequence[RECVERSION].c_str();
+
+ LTKVersionCompatibilityCheck verTempObj;
+ string supportedMinVersion(SUPPORTED_MIN_VERSION);
+ string currentVersionStr(m_currentVersion);
+
+ bool compatibilityResults = verTempObj.checkCompatibility(supportedMinVersion,
+ currentVersionStr,
+ algoVersionReadFromMDT);
+
+ if(compatibilityResults == false)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINCOMPATIBLE_VERSION << " " <<
+ " Incompatible version"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(EINCOMPATIBLE_VERSION);
+ }
+
+ // Version comparison END
+
+ //Input Stream for Model Data file
+ ifstream mdtFileHandle;
+
+ if (m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(), ios::in);
+ }
+ else
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(), ios::in | ios::binary);
+ }
+
+ //If error while opening, return an error
+ if(!mdtFileHandle)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EMODEL_DATA_FILE_OPEN << " " <<
+ " Unable to open model data file : " <<m_activedtwMDTFilePath<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(EMODEL_DATA_FILE_OPEN);
+ }
+
+ mdtFileHandle.seekg(atoi(headerSequence[HEADERLEN].c_str()),ios::beg);
+
+ //Read the number of shapes
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle >> numofShapes;
+ }
+ else
+ {
+ mdtFileHandle.read((char*) &numofShapes,
+ atoi(headerSequence[SIZEOFSHORTINT].c_str()));
+ }
+
+ if(!m_projectTypeDynamic && m_numShapes != numofShapes)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< ECONFIG_MDT_MISMATCH << " " <<
+ " Value of NumShapes parameter in config file ("<<m_numShapes<<
+ ") does not match with the value in MDT file ("<<numofShapes<<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+ if(m_projectTypeDynamic)
+ {
+ m_numShapes = numofShapes;
+ }
+
+ stringVector tokens;
+
+ stringVector subTokens;
+
+ string strFeatureVector = "";
+
+ //number of samples in each cluster
+ int numSamples;
+
+ //keeps count of number of clusters
+ // and singletons while reading from
+ //mdt file
+ int tempCount;
+
+ //number of clusters in a class
+ int numClusters;
+
+ //number of singletons in a class
+ int numSingletons;
+
+ //dimension of cluster mean
+ int clusterMeanDimension;
+
+ //number of features in a feature vector
+ int numFeatures;
+
+ //dimension of the featureVector
+ int featureDimension;
+
+
+ shapeMatrix singletonVector;
+ shapeFeature singleton;
+ doubleVector eigenValues;
+ double2DVector eigenVectors;
+ doubleVector clusterMean;
+ ActiveDTWClusterModel clusterModel;
+ ActiveDTWShapeModel shapeModel;
+ vector<ActiveDTWClusterModel> clusterModelVector;
+ doubleVector tempVector;
+
+ int floatSize = atoi(headerSequence[SIZEOFFLOAT].c_str());
+
+ int intSize = atoi(headerSequence[SIZEOFINT].c_str());
+
+ int doubleSize = sizeof(double);
+
+ //Each pass over the loop reads data corresponding to one class
+ //includes reading all the cluster data
+ //all singleton vectors
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle >> classId;
+ }
+ else
+ {
+ mdtFileHandle.read((char*) &classId, intSize);
+
+ }
+
+ while(!mdtFileHandle.eof())
+ {
+
+ /**READING CLASS INFORMATION**/
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle >> numClusters;
+
+ mdtFileHandle >> numSingletons;
+ }
+ else
+ {
+ //reading number of clusters, singletons, clusterMeanDimension,
+ //number of Features, and featureDimension
+ mdtFileHandle.read((char*) &numClusters,intSize);
+
+ mdtFileHandle.read((char*) &numSingletons,intSize);
+
+ mdtFileHandle.read((char*) &clusterMeanDimension,intSize);
+
+ mdtFileHandle.read((char*) &numFeatures,intSize);
+
+
+ mdtFileHandle.read((char*) &featureDimension,intSize);
+
+
+
+ }
+
+ tempCount = 0;
+
+ /**READING CLUSTER DATA**/
+
+ for(int clustersCount = 0 ; clustersCount < numClusters; clustersCount++)
+ {
+ //reading number of samples in a cluster
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle >> numSamples;
+ }
+ else
+ {
+ mdtFileHandle.read((char*) &numSamples,intSize);
+ }
+
+ iErrorCode = clusterModel.setNumSamples(numSamples);
+ if(iErrorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< iErrorCode << " " <<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(iErrorCode);
+ }
+
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ strFeatureVector = "";
+ mdtFileHandle >> strFeatureVector;
+
+ LTKStringUtil::tokenizeString(strFeatureVector,FEATURE_EXTRACTOR_DELIMITER,tokens);
+
+
+ //first token contains eigen values
+ LTKStringUtil::tokenizeString(tokens[0],",",subTokens);
+
+ //extracting eigen values
+ int i = 0;
+ for(i = 0; i < subTokens.size(); i++)
+ {
+
+ eigenValues.push_back(LTKStringUtil::convertStringToFloat(subTokens[i]));
+
+ }
+
+ clusterModel.setEigenValues(eigenValues);
+
+ subTokens.clear();
+
+ //extracting eigen vectors
+
+ for( i = 1; i < (eigenValues.size() + 1); i++)
+ {
+ LTKStringUtil::tokenizeString(tokens[i],",",subTokens);
+
+ for(int j = 0; j < subTokens.size(); j++)
+ {
+ tempVector.push_back(LTKStringUtil::convertStringToFloat(subTokens[j]));
+ }
+
+
+ eigenVectors.push_back(tempVector);
+ tempVector.clear();
+ subTokens.clear();
+ }
+
+ clusterModel.setEigenVectors(eigenVectors);
+
+
+ //extracting cluster mean
+
+ LTKStringUtil::tokenizeString(tokens[(eigenValues.size() + 1)],",",subTokens);
+
+ for( i = 0; i < subTokens.size(); i++)
+ {
+
+ clusterMean.push_back(LTKStringUtil::convertStringToFloat(subTokens[i]));
+ }
+
+ clusterModel.setClusterMean(clusterMean);
+
+ subTokens.clear();
+
+ clusterModelVector.push_back(clusterModel);
+ }
+ else
+ {
+ //reading number of eigenValues
+ int numEigenValues;
+ mdtFileHandle.read((char*) &numEigenValues,intSize);
+
+ //reading eigen values
+ int i = 0;
+ for(i = 0; i < numEigenValues; i++)
+ {
+ double eigenValue;
+ mdtFileHandle.read((char*) &eigenValue,doubleSize );
+
+ eigenValues.push_back(eigenValue);
+
+ if ( mdtFileHandle.fail() )
+ {
+ break;
+ }
+ }
+
+ clusterModel.setEigenValues(eigenValues);
+
+
+ //reading eigenVectors
+ for( i = 0; i < numEigenValues; i++)
+ {
+ for(int j = 0; j < clusterMeanDimension; j++)
+ {
+ double eigenVectorValue;
+ mdtFileHandle.read((char*) &eigenVectorValue,doubleSize);
+ tempVector.push_back(eigenVectorValue);
+
+ if ( mdtFileHandle.fail() )
+ {
+ break;
+ }
+ }
+
+ eigenVectors.push_back(tempVector);
+ tempVector.clear();
+ }
+
+ clusterModel.setEigenVectors(eigenVectors);
+
+
+ //reading cluster mean
+ for( i = 0; i < clusterMeanDimension; i++)
+ {
+ double clusterMeanValue;
+ mdtFileHandle.read((char*) &clusterMeanValue,doubleSize);
+
+ clusterMean.push_back(clusterMeanValue);
+
+ if ( mdtFileHandle.fail() )
+ {
+ break;
+ }
+ }
+
+ clusterModel.setClusterMean(clusterMean);
+
+
+ clusterModelVector.push_back(clusterModel);
+ }
+
+ //clearing vectors
+
+ eigenValues.clear();
+
+ eigenVectors.clear();
+
+ clusterMean.clear();
+
+ tempVector.clear();
+ tokens.clear();
+
+ }
+
+ /**READING SINGLETON VECTORS**/
+ tempCount = 0;
+
+ for(int singletonCount = 0; singletonCount < numSingletons; singletonCount++)
+ {
+ LTKShapeFeaturePtr feature;
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ strFeatureVector = "";
+ mdtFileHandle >> strFeatureVector;
+
+ //parsing the singleton vector
+ LTKStringUtil::tokenizeString(strFeatureVector, FEATURE_EXTRACTOR_DELIMITER, tokens);
+
+ for(int i = 0; i < tokens.size(); ++i)
+ {
+ feature = m_ptrFeatureExtractor->getShapeFeatureInstance();
+
+ if (feature->initialize(tokens[i]) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_INPUT_FORMAT << " " <<
+ "Number of features extracted from a trace is not correct"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+
+ LTKReturnError(EINVALID_INPUT_FORMAT);
+ }
+
+ singleton.push_back(feature);
+ }
+
+ singletonVector.push_back(singleton);
+
+ singleton.clear();
+ tokens.clear();
+ }
+ else
+ {
+ int featureIndex = 0;
+
+ for ( ; featureIndex < numFeatures ; featureIndex++)
+ {
+ floatVector floatFeatureVector;
+ int featureValueIndex = 0;
+
+ feature = m_ptrFeatureExtractor->getShapeFeatureInstance();
+
+ for(; featureValueIndex < featureDimension ; featureValueIndex++)
+ {
+ float featureValue = 0.0f;
+
+ mdtFileHandle.read((char*) &featureValue, floatSize);
+
+ floatFeatureVector.push_back(featureValue);
+
+ if ( mdtFileHandle.fail() )
+ {
+ break;
+ }
+ }
+
+ if (feature->initialize(floatFeatureVector) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<
+ EINVALID_INPUT_FORMAT << " " <<
+ "Number of features extracted from a trace is not correct"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+
+ LTKReturnError(EINVALID_INPUT_FORMAT);
+ }
+
+
+ singleton.push_back(feature);
+
+ }
+
+ singletonVector.push_back(singleton);
+
+ singleton.clear();
+ }
+ }
+
+ /**CONSTRUCTING SHAPE MODEL**/
+
+
+ iErrorCode = shapeModel.setShapeId(classId);
+ if(iErrorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< iErrorCode << " "<< endl;
+ LTKReturnError(iErrorCode);
+ }
+
+ shapeModel.setClusterModelVector(clusterModelVector);
+
+ shapeModel.setSingletonVector(singletonVector);
+
+
+
+
+ /**APPENDING THE SHAPE MODEL TO PROTOTYPE VECTOR**/
+
+ m_prototypeShapes.push_back(shapeModel);
+
+
+ m_shapeIDNumPrototypesMap[classId] = clusterModelVector.size();
+
+
+ if(m_useSingleton == true || clusterModelVector.size() == 0)
+ m_shapeIDNumPrototypesMap[classId] += singletonVector.size();
+
+
+
+
+
+ clusterModelVector.clear();
+
+ singletonVector.clear();
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle >> classId;
+ }
+ else
+ {
+ mdtFileHandle.read((char*) &classId, intSize);
+
+ if ( mdtFileHandle.fail() )
+ {
+ break;
+ }
+ }
+
+
+ }
+
+
+
+ mdtFileHandle.close();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::loadModelData()" << endl;
+
+ return SUCCESS;
+}
+
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : recognize
+* DESCRIsPTION : recognizes the incoming tracegroup
+* ARGUMENTS : inTraceGroup - trace group to be recognized
+* screenContext - screen context
+* subSetOfClasses - subset of classes whose samples will be compared with traceGroup
+* confThreshold - classes with confidence below this threshold are not returned, valid range of confThreshold: (0,1)
+* numChoices - maximum number of choices to be returned
+* outResultVector - result of recognition
+* RETURNS : SUCCESS on successful running of the code
+* NOTES :
+* CHANGE HISTROY
+* Author : Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::recognize(const LTKTraceGroup& traceGroup,
+ const LTKScreenContext& screenContext,
+ const vector<int>& subSetOfClasses,
+ float confThreshold,
+ int numChoices,
+ vector<LTKShapeRecoResult>& outResultVector)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::recognize()" << endl;
+
+
+ //Check for empty traces in traceGroup
+
+ if(traceGroup.containsAnyEmptyTrace())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<EEMPTY_TRACE << " " <<
+ " Input trace is empty"<<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(EEMPTY_TRACE);
+ }
+
+
+ //Contains TraceGroup after Preprocessing is done
+ LTKTraceGroup preprocessedTraceGroup;
+
+
+ //Preprocess the traceGroup
+ int errorCode = preprocess(traceGroup, preprocessedTraceGroup);
+ if( errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ getErrorMessage(errorCode)<<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ //Extract the shapeSample from preprocessedTraceGroup
+ if(!m_ptrFeatureExtractor)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< ENULL_POINTER << " " <<
+ " m_ptrFeatureExtractor is NULL"<<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(ENULL_POINTER);
+ }
+
+ vector<LTKShapeFeaturePtr> shapeFeatureVec;
+ errorCode = m_ptrFeatureExtractor->extractFeatures(preprocessedTraceGroup,
+ shapeFeatureVec);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ // call recognize with featureVector
+
+ if(recognize( shapeFeatureVec, subSetOfClasses, confThreshold,
+ numChoices, outResultVector) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ getErrorMessage(errorCode)<<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(errorCode);
+
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ return SUCCESS;
+
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : recognize
+* DESCRIsPTION : recognizes the incoming tracegroup
+* ARGUMENTS : shapeFeatureVec - feature vector to be recognized
+* screenContext - screen context
+* subSetOfClasses - subset of classes whose samples will be compared with traceGroup
+* confThreshold - classes with confidence below this threshold are not returned, valid range of confThreshold: (0,1)
+* numChoices - maximum number of choices to be returned
+* outResultVector - result of recognition
+* RETURNS : SUCCESS on successful running of the code
+* NOTES :
+* CHANGE HISTROY
+* Author : Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::recognize(const vector<LTKShapeFeaturePtr>& shapeFeatureVec,
+ const vector<int>& inSubSetOfClasses,
+ float confThreshold,
+ int numChoices,
+ vector<LTKShapeRecoResult>& outResultVector)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ m_cachedShapeFeature = shapeFeatureVec;
+
+ //Creating a local copy of input inSubSetOfClasses, as it is const, STL's unique function modifies it
+ vector<int> subSetOfClasses = inSubSetOfClasses;
+
+ int numPrototypeShapes = m_prototypeShapes.size();
+
+ /*********Validation for m_prototypeShapes ***************************/
+ if ( numPrototypeShapes == 0 )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EPROTOTYPE_SET_EMPTY << " " <<
+ " getErrorMessage(EPROTOTYPE_SET_EMPTY) "<<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(EPROTOTYPE_SET_EMPTY);
+ }
+
+ /******************************************************************/
+ /*******************VALIDATING INPUT ARGUMENTS*********************/
+ /******************************************************************/
+
+ // Validating numChoices: valid values: {-1, (0,m_numShapes]}
+ if(numChoices <= 0 && numChoices != NUM_CHOICES_FILTER_OFF)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)<<
+ "numChoices ("<<numChoices<<")<=0, setting it to off (-1)"<<endl;
+ numChoices = -1;
+ }
+
+ if(!m_projectTypeDynamic && numChoices > m_numShapes)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)<<
+ "numChoices ("<<numChoices<<") > numShapes ("<<
+ m_numShapes<<"), using numShapes "<<m_numShapes<<" instead"<<endl;
+ numChoices = m_numShapes;
+ }
+
+
+ //Validating confThreshold: valid values: [0,1]
+ if(confThreshold > 1 || confThreshold < 0)
+ {
+
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)<<
+ "Invalid value of confThreshold, valid values are: [0,1]"<<endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+
+ // Clearing cached Variables
+ m_vecRecoResult.clear();
+ m_neighborInfoVec.clear();
+
+ //Temporary variable to be used to populate distIndexPairVector
+ struct NeighborInfo tempPair;
+
+ struct NeighborInfo tempDist;
+
+ int i = 0;
+ int j = 0;
+
+ //Variable to store the DTW distance.
+ float dtwDistance = 0.0f;
+
+ //Variable to store the Euclidean distance.
+ float euclideanDistance = 0.0f;
+
+
+ /***************End of declarations and initializations of variables**************/
+
+
+
+ /**CONVERTING THE FEATURE VECTOR TO DOUBLE***/
+
+ doubleVector featureVector;
+ floatVector floatFeatureVector;
+ int errorCode = m_shapeRecUtil.shapeFeatureVectorToFloatVector(shapeFeatureVec,floatFeatureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ int floatFeatureVectorSize = floatFeatureVector.size();
+
+
+ for(i = 0; i < floatFeatureVectorSize; i++)
+ featureVector.push_back(floatFeatureVector[i]);
+ floatFeatureVector.clear();
+
+
+
+
+ ActiveDTWShapeModel evalShapeModel;
+ //current shape model evaluated against test Sample
+
+
+ ActiveDTWClusterModel evalClusterModel;
+ //currently evaluated cluster model
+
+
+ vector<ActiveDTWClusterModel> clusterVector;
+ //vector of cluster models of current shape model
+
+
+ shapeMatrix evalSingletonVector;
+ //vector of all singletonVectors of current shape model
+
+ doubleVector eigenValues;
+ //eigen values of cluster model
+
+ double2DVector eigenVector;
+ //eigen vectors of cluster model
+
+ doubleVector clusterMean;
+ //cluster mean of cluster model
+
+ doubleVector deformationParameters;
+ //paramters required to construct optimal Deformation
+
+ doubleVector reconstructedSample;
+ //double vector form of optima lDeformation
+
+ shapeMatrix optimalDeformations;
+ //vector of all optimalDeformations of a class
+
+ vector<bool> clusterFilter;
+ //indicates which cluster are to be considered for computing DTW DISTANCE
+
+ vector<bool> singletonFilter;
+ //indicates which singletons are to be considered for computing DTW DISTANCE
+
+ vector<struct NeighborInfo> distInfo;
+ //used in dtwEuclidean filter
+
+ vector<LTKShapeFeaturePtr> shapeFeatureVector;
+
+
+ /*****************COMPUTING DISTANCE******************************/
+ if(subSetOfClasses.size() == 0)
+ {
+ for(i = 0; i < m_prototypeShapes.size(); i++)
+ {
+ evalShapeModel = m_prototypeShapes[i];
+ clusterVector = evalShapeModel.getClusterModelVector();
+
+
+ evalSingletonVector = evalShapeModel.getSingletonVector();
+
+
+ int singletonSize = evalSingletonVector.size();
+ int clusterVectorSize = clusterVector.size();
+
+
+
+ //computing the optimalDeformations
+ for(j = 0; j < clusterVectorSize; j++)
+ {
+ evalClusterModel = clusterVector[j];
+
+ eigenVector = evalClusterModel.getEigenVectors();
+
+ eigenValues = evalClusterModel.getEigenValues();
+
+ clusterMean = evalClusterModel.getClusterMean();
+
+ deformationParameters.assign(eigenVector.size(),0.0);
+
+
+ int errorCode = findOptimalDeformation(deformationParameters,eigenValues,eigenVector,
+ clusterMean,featureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ //reconstruct the sample
+ double tempCoordinate = 0.0;
+ int clusterMeanSize = clusterMean.size();
+ int deformationParametersSize = deformationParameters.size();
+
+ for(int k = 0; k < clusterMeanSize; k++)
+ {
+ tempCoordinate = clusterMean[k];
+
+ for(int l = 0; l < deformationParametersSize; l++)
+ tempCoordinate += deformationParameters[l]*eigenVector[l][k];
+
+ reconstructedSample.push_back(tempCoordinate);
+ }
+
+ //converting the reconstructed Sample to a featureVector
+ errorCode = convertDoubleToFeatureVector(shapeFeatureVector,reconstructedSample);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ optimalDeformations.push_back(shapeFeatureVector);
+
+ //clearing vectors
+ eigenValues.clear();
+ eigenVector.clear();
+ clusterMean.clear();
+ reconstructedSample.clear();
+ shapeFeatureVector.clear();
+ deformationParameters.clear();
+ }
+
+
+ //setting up dtweuclidean filter for the class
+ if(m_dtwEuclideanFilter != EUCLIDEAN_FILTER_OFF)
+ {
+ //calculating euclidean distance to clusters
+ for( j = 0; j < clusterVectorSize; j++)
+ {
+
+ euclideanDistance = 0.0;
+
+ errorCode = computeEuclideanDistance(shapeFeatureVec,optimalDeformations[j],euclideanDistance);
+
+
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ tempDist.typeId = CLUSTER;
+ tempDist.sampleId = j;
+ tempDist.distance = euclideanDistance;
+
+ distInfo.push_back(tempDist);
+ }
+
+ //calcualting euclidean distances to singletons
+ if(m_useSingleton == true || clusterVectorSize == 0)
+ {
+
+ for(j = 0; j < singletonSize; j++)
+ {
+
+ euclideanDistance = 0.0;
+ //computing euclidean distance between test sample
+ //and singleton vectors
+
+ errorCode = computeEuclideanDistance(shapeFeatureVec,evalSingletonVector[j],
+ euclideanDistance);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ tempDist.typeId = SINGLETON;
+ tempDist.sampleId = j;
+ tempDist.distance = euclideanDistance;
+
+ distInfo.push_back(tempDist);
+
+
+ }
+ }
+
+
+ //sorting the euclidean distances in ascending order
+ sort(distInfo.begin(), distInfo.end(), sortDist);
+
+
+ //choose the top n
+ int numTopChoices = (int)(distInfo.size() * m_dtwEuclideanFilter)/100;
+ if(numTopChoices == 0)
+ {
+ numTopChoices = distInfo.size();
+ }
+
+ //setting the filter
+ clusterFilter.assign(clusterVectorSize,false);
+
+ if(m_useSingleton == true || clusterVectorSize == 0)
+ singletonFilter.assign(singletonSize,false);
+
+
+ for( j = 0; j < numTopChoices; j++)
+ {
+ if(distInfo[j].typeId == 0)
+ clusterFilter[distInfo[j].sampleId] = true;
+
+ if(distInfo[j].typeId == 1)
+ singletonFilter[distInfo[j].sampleId] = true;
+ }
+
+ //clearing distInfo
+ distInfo.clear();
+ }
+ else
+ {
+ clusterFilter.assign(clusterVectorSize,true);
+
+ if(m_useSingleton == true || clusterVectorSize == 0)
+ singletonFilter.assign(singletonSize,true);
+ }
+
+
+ /*****DETERMINING THE MINIMUM CLUSTER DISTANCE***************/
+ float minDistance = FLT_MAX;
+ float minClusterDistance;
+ float minSingletonDistance;
+
+ int clusterId;
+ int singletonId;
+
+ for( j = 0; j < clusterVectorSize; j++)
+ {
+
+ if(clusterFilter[j])
+ {
+ float tempDistance = 0.0;
+ errorCode = computeDTWDistance(shapeFeatureVec,optimalDeformations[j],tempDistance);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ if(tempDistance < minDistance)
+ {
+ minDistance = tempDistance;
+ clusterId = j;
+ }
+
+
+
+ }
+
+ }
+
+ clusterVector.clear();
+ clusterFilter.clear();
+ optimalDeformations.clear();
+
+ minClusterDistance = minDistance;
+
+ /***DETERMINE THE MINIMUM DISTANCE FROM CLUSTERS ONLY IF THE
+ USE SINGLETON SWITCH IS TURNED ON. IF THE NUMBER OF CLUSTERS
+ IN A CLASS IS 0 THEN AUTOMATICALLY TURN ON THE SINGLETON SWITCH
+ FOR THAT CLASS ALONE ***/
+
+ if(m_useSingleton == false && clusterVectorSize == 0)
+ m_useSingleton = true;
+
+ /***************DETERMINING MINIMUM DISTANCE FROM SINGLETON VECTORS*********/
+ if(m_useSingleton == true)
+ {
+ evalSingletonVector = evalShapeModel.getSingletonVector();
+
+ int evalSingletonVectorSize = evalSingletonVector.size();
+
+ for(int j = 0; j < evalSingletonVectorSize; j++)
+ {
+ if(singletonFilter[j])
+ {
+
+ //calculate the dtw distance between testsamples and every singleton vector
+ float tempDistance = 0.0;
+
+ errorCode = computeDTWDistance(shapeFeatureVec,evalSingletonVector[j],tempDistance);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ if(tempDistance < minDistance)
+ {
+ minDistance = tempDistance;
+ singletonId = j;
+ }
+
+ }
+ }
+ singletonFilter.clear();
+ }
+
+ //clearing vectors
+ evalSingletonVector.clear();
+
+ minSingletonDistance = minDistance;
+
+ //choosing the minimum distance
+ if(m_useSingleton == false)
+ {
+ tempPair.distance = minClusterDistance;
+ tempPair.typeId = CLUSTER;
+ tempPair.sampleId = clusterId;
+ }
+ else
+ {
+ if(clusterVectorSize == 0)
+ {
+ tempPair.distance = minSingletonDistance;
+ tempPair.typeId = SINGLETON;
+ tempPair.sampleId = singletonId;
+ }
+ else
+ {
+ if(minClusterDistance < minSingletonDistance)
+ {
+ tempPair.distance = minClusterDistance;
+ tempPair.typeId = CLUSTER;
+ tempPair.sampleId = clusterId;
+ }
+ else
+ {
+ tempPair.distance = minSingletonDistance;
+ tempPair.typeId = SINGLETON;
+ tempPair.sampleId = singletonId;
+ }
+ }
+ }
+
+ //turning off the singleton switch in case it was turned on automatically
+ if(m_useSingleton == true && clusterVectorSize == 0)
+ m_useSingleton = false;
+
+
+ tempPair.classId = evalShapeModel.getShapeId();
+ m_neighborInfoVec.push_back(tempPair);
+ }
+ }
+ else
+ {
+ /*****EVALUATE TEST SAMPLES ONLY AGAINST CLASSES SPECIFIED BY SUBSETOFCLASSES***/
+ intVector::iterator subSetStart = subSetOfClasses.begin();
+ intVector::iterator subSetEnd = subSetOfClasses.end();
+
+ for(;subSetStart != subSetEnd; ++subSetStart)
+ {
+ evalShapeModel = m_prototypeShapes[(*subSetStart)];
+
+ clusterVector = evalShapeModel.getClusterModelVector();
+
+ evalSingletonVector = evalShapeModel.getSingletonVector();
+
+ int clusterVectorSize = clusterVector.size();
+ int singletonSize = evalSingletonVector.size();
+
+ //computing the optimalDeformations
+ for( j = 0; j < clusterVectorSize; j++)
+ {
+ evalClusterModel = clusterVector[j];
+
+ eigenVector = evalClusterModel.getEigenVectors();
+
+ eigenValues = evalClusterModel.getEigenValues();
+
+ clusterMean = evalClusterModel.getClusterMean();
+
+ deformationParameters.assign(eigenVector.size(),0.0);
+
+ int errorCode = findOptimalDeformation(deformationParameters,eigenValues,eigenVector,
+ clusterMean,featureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ //reconstruct the sample
+ double tempCoordinate = 0.0;
+ int clusterMeanSize = clusterMean.size();
+ int deformationParametersSize = deformationParameters.size();
+
+ for(int k = 0; k < clusterMeanSize; k++)
+ {
+ tempCoordinate = clusterMean[k];
+
+ for(int l = 0; l < deformationParametersSize; l++)
+ tempCoordinate += deformationParameters[l]*eigenVector[l][k];
+
+ reconstructedSample.push_back(tempCoordinate);
+ }
+
+ //converting the reconstructed Sample to a featureVector
+ errorCode = convertDoubleToFeatureVector(shapeFeatureVector,reconstructedSample);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ optimalDeformations.push_back(shapeFeatureVector);
+
+ //clearing vectors
+ eigenValues.clear();
+ eigenVector.clear();
+ clusterMean.clear();
+ reconstructedSample.clear();
+ shapeFeatureVector.clear();
+ deformationParameters.clear();
+ }
+
+ //setting up dtweuclidean filter for the class
+ if(m_dtwEuclideanFilter != EUCLIDEAN_FILTER_OFF)
+ {
+ //calculating euclidean distance to clusters
+ for(j = 0; j < clusterVectorSize; j++)
+ {
+ euclideanDistance = 0.0;
+
+ errorCode = computeEuclideanDistance(shapeFeatureVec,optimalDeformations[j],euclideanDistance);
+
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ tempDist.typeId = CLUSTER;
+ tempDist.sampleId = j;
+ tempDist.distance = euclideanDistance;
+
+ distInfo.push_back(tempDist);
+ }
+
+ //calcualting euclidean distances to singletons
+ if(m_useSingleton == true || clusterVectorSize == 0)
+ {
+ for(j = 0; j < singletonSize; j++)
+ {
+ euclideanDistance = 0.0;
+ //computing euclidean distance between test sample
+ //and singleton vectors
+
+ errorCode = computeEuclideanDistance(shapeFeatureVec,evalSingletonVector[j],
+ euclideanDistance);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ tempDist.typeId = SINGLETON;
+ tempDist.sampleId = j;
+ tempDist.distance = euclideanDistance;
+
+ distInfo.push_back(tempDist);
+ }
+ }
+
+ //sorting the euclidean distances in ascending order
+
+ sort(distInfo.begin(), distInfo.end(), sortDist);
+
+
+ //choose the top n
+ int numTopChoices = (int)(distInfo.size() * m_dtwEuclideanFilter)/100;
+
+ if(numTopChoices == 0)
+ {
+ numTopChoices = distInfo.size();
+ }
+
+ //setting the filter
+ clusterFilter.assign(clusterVectorSize,false);
+
+ if(m_useSingleton == true || clusterVectorSize == 0)
+ singletonFilter.assign(singletonSize,false);
+
+ for( j = 0; j < numTopChoices; j++)
+ {
+ if(distInfo[j].typeId == 0)
+ clusterFilter[distInfo[j].sampleId] = true;
+
+ if(distInfo[j].typeId == 1)
+ singletonFilter[distInfo[j].sampleId] = true;
+ }
+
+ //clearing distInfo
+ distInfo.clear();
+ }
+
+ /*****DETERMINING THE MINIMUM CLUSTER DISTANCE***************/
+ float minDistance = FLT_MAX;
+ float minClusterDistance;
+ float minSingletonDistance;
+
+ int clusterId;
+ int singletonId;
+
+ for( j = 0; j < clusterVectorSize; j++)
+ {
+ if(clusterFilter[j])
+ {
+ float tempDistance = 0.0;
+ errorCode = computeDTWDistance(shapeFeatureVec,optimalDeformations[j],tempDistance);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ if(tempDistance < minDistance)
+ {
+ minDistance = tempDistance;
+ clusterId = j;
+ }
+ }
+ }
+
+ clusterVector.clear();
+ clusterFilter.clear();
+ optimalDeformations.clear();
+
+ minClusterDistance = minDistance;
+
+ /***DETERMINE THE MINIMUM DISTANCE FROM CLUSTERS ONLY IF THE
+ USE SINGLETON SWITCH IS TURNED ON. IF THE NUMBER OF CLUSTERS
+ IN A CLASS IS 0 THEN AUTOMATICALLY TURN ON THE SINGLETON SWITCH
+ FOR THAT CLASS ALONE ***/
+
+ if(m_useSingleton == false && clusterVectorSize == 0)
+ m_useSingleton = true;
+
+ /***************DETERMINING MINIMUM DISTANCE FROM SINGLETON VECTORS*********/
+ if(m_useSingleton == true)
+ {
+
+ evalSingletonVector = evalShapeModel.getSingletonVector();
+ int evalSingletonVectorSize = evalSingletonVector.size();
+
+ for(j = 0; j < evalSingletonVectorSize; j++)
+ {
+ if(singletonFilter[j])
+ {
+ //calculate the dtw distance between testsamples and every singleton vector
+ float tempDistance = 0.0;
+
+ errorCode = computeDTWDistance(shapeFeatureVec,evalSingletonVector[j],tempDistance);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+
+ if(tempDistance < minDistance)
+ {
+ minDistance = tempDistance;
+ singletonId = j;
+ }
+
+
+ }
+ }
+
+ singletonFilter.clear();
+ }
+
+ //clearing vectors
+ evalSingletonVector.clear();
+
+ minSingletonDistance = minDistance;
+
+ //choosing the minimum distance
+ if(m_useSingleton == false)
+ {
+ tempPair.distance = minClusterDistance;
+ tempPair.typeId = CLUSTER;
+ tempPair.sampleId = clusterId;
+ }
+ else
+ {
+ if(clusterVectorSize == 0)
+ {
+ tempPair.distance = minSingletonDistance;
+ tempPair.typeId = SINGLETON;
+ tempPair.sampleId = singletonId;
+ }
+ else
+ {
+ if(minClusterDistance < minSingletonDistance)
+ {
+ tempPair.distance = minClusterDistance;
+ tempPair.typeId = CLUSTER;
+ tempPair.sampleId = clusterId;
+ }
+ else
+ {
+ tempPair.distance = minSingletonDistance;
+ tempPair.typeId = SINGLETON;
+ tempPair.sampleId = singletonId;
+ }
+ }
+ }
+
+ //turning off the singleton switch in case it was turned on automatically
+ if(m_useSingleton == true && clusterVectorSize == 0)
+ m_useSingleton = false;
+
+
+ tempPair.classId = evalShapeModel.getShapeId();
+
+
+ m_neighborInfoVec.push_back(tempPair);
+ }
+ }
+
+ featureVector.clear();
+
+
+ //Sort the distIndexPairVector based on distances, in ascending order.
+ sort(m_neighborInfoVec.begin(), m_neighborInfoVec.end(), sortDist);
+
+ //Reject the sample if the similarity of the nearest sample is lower than m_rejectThreshold specified by the user.
+ if(SIMILARITY(m_neighborInfoVec[0].distance) <= m_rejectThreshold)
+ {
+ m_vecRecoResult.clear();
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)<<"Test sample too distinct, rejecting the sample"<<endl;
+ return SUCCESS;
+ }
+
+ //compute confidence
+ if((errorCode = computeConfidence()) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::recognize()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ // Temporary result vector to store the results based on confThreshold and numChoices specified by the user.
+ vector<LTKShapeRecoResult> tempResultVector;
+
+ //If confThreshold is specified, get the entries from resultVector with confidence >= confThreshold
+ if(confThreshold != CONF_THRESHOLD_FILTER_OFF)
+ {
+ for(i = 0 ; i < m_vecRecoResult.size() ; i++)
+ {
+ if( m_vecRecoResult[i].getConfidence() >= confThreshold)
+ {
+ tempResultVector.push_back(m_vecRecoResult[i]);
+ }
+ }
+ m_vecRecoResult.clear();
+ m_vecRecoResult = tempResultVector;
+ tempResultVector.clear();
+ }
+ //Check if outResultVector is empty, if so, log
+ if(m_vecRecoResult.size() == 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO) <<
+ "Size of the result vector is empty, could not satisfy confThreshold criteria"<<endl;
+ }
+
+ //If numChoices is specified, get the top numChoices entries from outResultVector
+ if(numChoices != NUM_CHOICES_FILTER_OFF)
+ {
+ //Get the entries from outResultVector only if size of resultVector > numChoices
+ if(m_vecRecoResult.size() > numChoices)
+ {
+ for( i = 0 ; i < numChoices ; ++i)
+ tempResultVector.push_back(m_vecRecoResult[i]);
+ m_vecRecoResult.clear();
+ m_vecRecoResult = tempResultVector;
+ tempResultVector.clear();
+ }
+
+ }
+
+ outResultVector = m_vecRecoResult;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::recognize()" << endl;
+
+ return SUCCESS;
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : sortDist
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+bool ActiveDTWShapeRecognizer::sortDist(const NeighborInfo& x, const NeighborInfo& y)
+{
+ return (x.distance) < (y.distance);
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computeConfidence
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int ActiveDTWShapeRecognizer::computeConfidence()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeConfidence()" << endl;
+
+ /******************************************************************/
+ /*******************VALIDATING INPUT ARGUMENTS*********************/
+ /******************************************************************/
+ if(m_neighborInfoVec.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< ENEIGHBOR_INFO_VECTOR_EMPTY << " " <<
+ getErrorMessage(ENEIGHBOR_INFO_VECTOR_EMPTY) <<
+ " ActiveDTWShapeRecognizer::computeConfidence()" << endl;
+
+ LTKReturnError(ENEIGHBOR_INFO_VECTOR_EMPTY);
+ }
+ // Temporary vector to store the recognition results
+ LTKShapeRecoResult outResult;
+ vector<pair<int,float> > classIdSimilarityPairVec;
+ pair<int, float> classIdSimilarityPair;
+
+ // Temporary vector to store the distinct classes appearing in distIndexPairVector
+ intVector distinctClassVector;
+ intVector::iterator distinctClassVectorIter;
+
+ vector <LTKShapeRecoResult>::iterator resultVectorIter = m_vecRecoResult.begin();
+ vector <LTKShapeRecoResult>::iterator resultVectorIterEnd = m_vecRecoResult.end();
+
+ // Variable to store sum of distances to all the prototypes in distIndexPairVector
+ float similaritySum = 0.0f;
+ // Temporary variable to store the confidence value.
+ float confidence = 0.0f;
+
+
+
+ // Confidence computation for the ActiveDTW (1-NN) Classifier
+ if(m_nearestNeighbors == 1)
+ {
+ vector <struct NeighborInfo>::iterator distIndexPairIter = m_neighborInfoVec.begin();
+ vector <struct NeighborInfo>::iterator distIndexPairIterEnd = m_neighborInfoVec.end();
+
+
+
+ for(; distIndexPairIter != distIndexPairIterEnd; ++distIndexPairIter)
+ {
+ //Check if the class is already present in distinctClassVector
+ //The complexity of STL's find() is linear, with atmost last-first comparisons for equality
+ distinctClassVectorIter = find(distinctClassVector.begin(), distinctClassVector.end(), (*distIndexPairIter).classId);
+
+ //The distinctClassVectorIter will point to distinctClassVector.end() if the class is not present in distinctClassVector
+ if(distinctClassVectorIter == distinctClassVector.end())
+ {
+ classIdSimilarityPair.first = (*distIndexPairIter).classId ;
+ float similarityValue = SIMILARITY((*distIndexPairIter).distance);
+
+ classIdSimilarityPair.second = similarityValue;
+ similaritySum += similarityValue;
+
+ classIdSimilarityPairVec.push_back(classIdSimilarityPair);
+ distinctClassVector.push_back((*distIndexPairIter).classId);
+ }
+ }
+
+ /************COMPUTING CONFIDENCE VALUES FOR EACH CLASS************/
+ int classIdSimilarityPairVecSize = classIdSimilarityPairVec.size();
+ for( int i = 0 ; i < classIdSimilarityPairVecSize ; ++i)
+ {
+ int classID = classIdSimilarityPairVec[i].first;
+ confidence = classIdSimilarityPairVec[i].second;
+ confidence /= similaritySum;
+ outResult.setConfidence(confidence);
+ outResult.setShapeId(classID);
+
+ if(confidence > 0)
+ m_vecRecoResult.push_back(outResult);
+ }
+ classIdSimilarityPairVec.clear();
+ }
+ // Computing confidence for k-NN classifier, implementation of the confidence measure described in paper (cite)
+ else
+ {
+ if(m_nearestNeighbors >= m_neighborInfoVec.size())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) <<
+ "m_nearestNeighbors >= m_prototypeSet.size(), using distIndexPairVector.size() for m_nearestNeighbors instead" << endl;
+ m_nearestNeighbors = m_neighborInfoVec.size();
+ }
+
+ // Variable to store the maximum of the number of samples per class.
+ int maxClassSize = (max_element(m_shapeIDNumPrototypesMap.begin(), m_shapeIDNumPrototypesMap.end(), &compareMap))->second;
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "maxClassSize: " <<maxClassSize<< endl;
+
+ // Vector to store the cumulative similarity values
+ vector<float> cumulativeSimilaritySum;
+
+ // Populate the values in cumulativeSimilaritySum vector for the top m_nearestNeighbors prototypes
+ // Assumption is m_nearestNeighbors >= MIN_NEARESTNEIGHBORS and m_nearestNeighbors < m_dtwEuclideanFilter, validation done in readClassifierConfig()
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Displaying cumulativeSimilaritySum..." << endl;
+ int i = 0;
+ for( i = 0 ; i < m_nearestNeighbors ; ++i)
+ {
+
+ classIdSimilarityPair.first = m_neighborInfoVec[i].classId;
+ float similarityValue = SIMILARITY((m_neighborInfoVec[i]).distance);
+
+ classIdSimilarityPair.second = similarityValue;
+
+ classIdSimilarityPairVec.push_back(classIdSimilarityPair);
+ similaritySum += similarityValue;
+ cumulativeSimilaritySum.push_back(similaritySum);
+
+ // Logging the cumulative similarity values for debugging
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "classID:" <<
+ m_neighborInfoVec[i].classId << " confidence:" <<
+ similarityValue << endl;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << i << ": " << similaritySum << endl;
+ }
+
+
+ for(i = 0 ; i < classIdSimilarityPairVec.size() ; ++i)
+ {
+
+ int classID = classIdSimilarityPairVec[i].first;
+
+ int finalNearestNeighbors = 0;
+
+ //Check if the class is already present in distinctClassVector
+ distinctClassVectorIter = find(distinctClassVector.begin(), distinctClassVector.end(), classID);
+
+ //The distinctClassVectorIter will point to distinctClassVector.end() if the class is not present in distinctClassVector
+ if(distinctClassVectorIter == distinctClassVector.end())
+ {
+ distinctClassVector.push_back(classID);
+ confidence = 0.0f;
+
+ //If the confidence is based on Adaptive k-NN scheme,
+ //Computing number of nearest neighbours for the class to be used for computation of confidence
+ if(m_adaptivekNN == true )
+ {
+
+ int sizeProportion = (int)ceil(1.0*m_nearestNeighbors*m_shapeIDNumPrototypesMap[classID]/maxClassSize);
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"sizeProportion of class " <<classID<<" is "<<sizeProportion<<endl;
+
+ // Computing min(sizeProportion, m_shapeIDNumPrototypesMap[classID])
+ int upperBound = (sizeProportion < m_shapeIDNumPrototypesMap[classID]) ? sizeProportion:m_shapeIDNumPrototypesMap[classID];
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"upperBound: " <<upperBound<<endl;
+
+ // Computing max(upperBound, MIN_NEARESTNEIGHBORS)
+ finalNearestNeighbors = (MIN_NEARESTNEIGHBORS > upperBound) ? MIN_NEARESTNEIGHBORS:upperBound;
+ }
+ //Else, compute kNN based confidence
+ else if(m_adaptivekNN == false)
+ {
+ finalNearestNeighbors = m_nearestNeighbors;
+ }
+ else
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: " << ECONFIG_FILE_RANGE << " " <<
+ "m_adaptivekNN should be true or false" <<
+ " ActiveDTWShapeRecognizer::computeConfidence()" << endl;
+ LTKReturnError(ECONFIG_FILE_RANGE);
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"finalNearestNeighbors: " <<finalNearestNeighbors<<endl;
+
+ for( int j = 0 ; j < finalNearestNeighbors ; ++j)
+ {
+ if(classID == classIdSimilarityPairVec[j].first)
+ {
+ confidence += classIdSimilarityPairVec[j].second;
+ }
+ }
+ confidence /= cumulativeSimilaritySum[finalNearestNeighbors-1];
+
+ outResult.setShapeId(classID);
+ outResult.setConfidence(confidence);
+
+ if(confidence > 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)<<"classId: " <<classID<<" confidence: "<<confidence<<endl;
+
+ m_vecRecoResult.push_back(outResult);
+ }
+ }
+ }
+ classIdSimilarityPairVec.clear();
+ }
+
+ //Sort the result vector in descending order of confidence
+ sort(m_vecRecoResult.begin(), m_vecRecoResult.end(), sortResultByConfidence);
+
+ distinctClassVector.clear();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeConfidence()" << endl;
+
+ return SUCCESS;
+
+}
+
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : sortResultByConfidence
+* DESCRIPTION : Sort the LTKShapeRecoResult vector based on the Confidence value
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+bool ActiveDTWShapeRecognizer::sortResultByConfidence(const LTKShapeRecoResult& x, const LTKShapeRecoResult& y)
+{
+ return (x.getConfidence()) > (y.getConfidence());
+}
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : compareMap
+* DESCRIPTION : Sort the STL's map based on the 'value'(second) field
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+
+bool ActiveDTWShapeRecognizer::compareMap( const map<int, int>::value_type& lhs, const map<int, int>::value_type& rhs )
+{
+ return lhs.second < rhs.second;
+}
+
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : unloadModelData
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS : SUCCESS
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::unloadModelData()
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::unloadModelData()" << endl;
+
+ int returnStatus = SUCCESS;
+
+ //Update MDT file with any modification, if available in memory
+ if(m_prototypeSetModifyCount >0)
+ {
+ m_prototypeSetModifyCount = m_MDTUpdateFreq-1;
+
+ returnStatus = writePrototypeShapesToMDTFile();
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::unloadModelData()" << endl;
+ }
+ m_prototypeSetModifyCount = 0;
+ }
+
+ //Clearing the prototypSet
+ m_prototypeShapes.clear();
+ m_shapeIDNumPrototypesMap.clear();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::unloadModelData()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : setDeviceContext
+* DESCRIPTION : New Function - Not yet added
+* ARGUMENTS :
+* RETURNS : SUCCESS
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::setDeviceContext(const LTKCaptureDevice& deviceInfo)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::setDeviceContext()" << endl;
+
+ m_captureDevice = deviceInfo;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::setDeviceContext()" << endl;
+
+ return SUCCESS;
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : performClustering
+* DESCRIPTION : This method performs clustering on each class data
+and returns a vector specifying which samples
+belong to which cluster
+* ARGUMENTS : INPUT
+shapeSamplesVec vector<LTKShapeSample> Class Data to be clustered
+: OUTPUT
+outputVector int2DVector
+(Here each row of the outputVector denotes a cluster
+in turn each row holds the indices of the samples
+belonging to that cluster)
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::performClustering(const vector<LTKShapeSample>& shapeSamplesVec,
+ int2DVector& outputVector)
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::performClustering()" << endl;
+
+ intVector tempVec;
+
+ float2DVector distanceMatrix;
+ int sampleCount=shapeSamplesVec.size();
+ int returnStatus = SUCCESS;
+
+
+
+ if(m_prototypeReductionFactor == -1)
+ {
+ //find number of clusters automatically
+ //this is done when either of NumClusters or PrototypeReducrion factor is set
+ //to automatic
+ LTKHierarchicalClustering<LTKShapeSample,ActiveDTWShapeRecognizer> hc(shapeSamplesVec,AVERAGE_LINKAGE,AVG_SIL);
+
+ returnStatus = hc.cluster(this,&ActiveDTWShapeRecognizer::computeDTWDistance);
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::performClustering()" << endl;
+ LTKReturnError(returnStatus);
+ }
+
+ //Cluster results are populated in an outputVector
+ hc.getClusterResult(outputVector);
+
+ }
+ else if(m_prototypeReductionFactor == 0|| m_numClusters >= sampleCount)
+ {
+ intVector clusterIndices;
+ //case where clustering is not required every sample is a cluster by itself
+ for(int i = 0; i < sampleCount; i++)
+ clusterIndices.push_back(i);
+
+ outputVector.push_back(clusterIndices);
+ clusterIndices.clear();
+
+ }
+ else
+ {
+ //clustering has to be performed
+
+ int numClusters;
+ if(m_numClusters == NN_NUM_CLUST_INITIAL)
+ {
+ numClusters = (100-m_prototypeReductionFactor)*sampleCount/100;
+ if(numClusters == 0)
+ {
+ numClusters = 1;
+ }
+ }
+
+ else if(m_prototypeReductionFactor == NN_NUM_CLUST_INITIAL)
+ {
+ numClusters = m_numClusters;
+ }
+
+ try
+ {
+
+ LTKHierarchicalClustering<LTKShapeSample,ActiveDTWShapeRecognizer>
+ hc(shapeSamplesVec,numClusters, AVERAGE_LINKAGE);
+
+ if(numClusters == 1)
+ {
+ int tempVar;
+ hc.computeProximityMatrix(this, &ActiveDTWShapeRecognizer::computeDTWDistance);
+
+
+ for(tempVar=0;tempVar<shapeSamplesVec.size();tempVar++)
+ {
+ tempVec.push_back(tempVar);
+ }
+
+ outputVector.push_back(tempVec);
+ tempVec.clear();
+ }
+ else
+ {
+ returnStatus = hc.cluster(this,&ActiveDTWShapeRecognizer::computeDTWDistance);
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << returnStatus << " " <<
+ " ActiveDTWShapeRecognizer::performClustering()" << endl;
+ LTKReturnError(returnStatus);
+ }
+
+ //Cluster results are populated in an outputVector
+ hc.getClusterResult(outputVector);
+ }
+
+ }
+ catch(LTKException e)
+ {
+ int errorCode = e.getErrorCode();
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: " << errorCode << " " <<
+ " ActiveDTWShapeRecognizer::performClustering()" << endl;
+ LTKReturnError(errorCode);
+ }
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::performClustering()" << endl;
+
+
+
+ return SUCCESS;
+
+}
+
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getShapeSampleFromInkFile
+* DESCRIPTION : This method will get the ShapeSample by giving the ink
+* file path as input
+* ARGUMENTS :
+* RETURNS : SUCCESS
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile(const string& inkFilePath,
+ vector<LTKShapeFeaturePtr>& shapeFeatureVec)
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile()" << endl;
+
+ if ( inkFilePath.empty() )
+ return FAILURE;
+
+ LTKCaptureDevice captureDevice;
+ LTKScreenContext screenContext;
+
+
+ LTKTraceGroup inTraceGroup, preprocessedTraceGroup;
+
+
+ inTraceGroup.emptyAllTraces();
+
+ int returnVal = m_shapeRecUtil.readInkFromFile(inkFilePath,
+ m_lipiRootPath, inTraceGroup,
+ captureDevice, screenContext);
+
+ if (returnVal!= SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<returnVal<<
+ " ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile()" << endl;
+ LTKReturnError(returnVal);
+ }
+
+ m_ptrPreproc->setCaptureDevice(captureDevice);
+ m_ptrPreproc->setScreenContext(screenContext);
+
+ preprocessedTraceGroup.emptyAllTraces();
+
+ //Preprocessing to be done for the trace group that was read
+ int errorCode = preprocess(inTraceGroup, preprocessedTraceGroup);
+ if( errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+
+
+ errorCode = m_ptrFeatureExtractor->extractFeatures(preprocessedTraceGroup,
+ shapeFeatureVec);
+
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::getShapeFeatureFromInkFile()" << endl;
+
+ return SUCCESS;
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : trainFromListFile
+* DESCRIPTION : This method will do the training by giving the Train List
+* file as input
+* ARGUMENTS :
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int ActiveDTWShapeRecognizer::trainFromListFile(const string& listFilePath)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+
+ //Count for the no. of samples read for a shape
+ int sampleCount = 0;
+
+ //Count of the no. of shapes read so far
+ int shapeCount = 0;
+
+ //Flag to skip reading a newline in the list file, when a new class starts
+ bool lastshapeIdFlag = false;
+
+ //Ink File Path
+ string path = "";
+
+ //Line from the list file
+ string line = "";
+
+ //Line is split into tokens
+ stringVector tokens;
+
+ //Flag is set when EOF is reached
+ bool eofFlag = false;
+
+ //ID for each shapes
+ int shapeId = -1;
+
+ //classId of the character
+ int prevClassId = -1;
+
+ //Indicates the first class
+ bool initClassFlag = false;
+
+ /**vectors for cluster indices
+ *each vector corresponds to a cluster in a class
+ *each vector has the indices of the shapesamples belonging to the cluster
+ **/
+ int2DVector clusterIndices;
+
+ /**
+ * this will hold a vector of indices pertaining to a certain cluster
+ **/
+ intVector cluster;
+
+ /**
+ * this will hold a temporary float feature vector
+ **/
+ doubleVector tempFeature;
+
+ /**
+ * Feature Matrix
+ **/
+ double2DVector featureMatrix;
+
+ /**
+ * Covariance Matrix
+ **/
+ double2DVector covarianceMatrix;
+
+ /**
+ * Eigen Vector Matrix
+ **/
+ double2DVector eigenVectors;
+
+ /**
+ * Eigen Values
+ **/
+ doubleVector eigenValues;
+
+ /**
+ * nrot --> number of iterations for eigen vector computation
+ **/
+ int nrot = 0;
+
+ /**
+ * clusterModel
+ **/
+
+ ActiveDTWClusterModel clusterModel;
+
+
+
+ /**
+ * vector of cluster models
+ **/
+ vector<ActiveDTWClusterModel> clusterModelVector;
+
+
+ /**
+ * shape Model
+ **/
+
+ ActiveDTWShapeModel shapeModel;
+
+ /**
+ * vector of singleton clusters
+ **/
+
+ shapeMatrix singletonVector;
+
+ /**
+ * selected eigen vectors
+ **/
+ double2DVector selectedEigenVectors;
+
+ /**
+ * cluster mean
+ **/
+ doubleVector clusterMean;
+
+
+
+ LTKShapeSample shapeSampleFeatures;
+
+
+ vector<LTKShapeSample> shapeSamplesVec;
+
+ vector<LTKShapeSample> clusteredShapeSampleVec;
+
+ ofstream mdtFileHandle;
+ ifstream listFileHandle;
+
+ vector<LTKShapeFeaturePtr> shapeFeature;
+
+ //Opening the train list file for reading mode
+ listFileHandle.open(listFilePath.c_str(), ios::in);
+
+ //Return error if unable to open the training list file
+ if(!listFileHandle)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< ETRAINLIST_FILE_OPEN << " " <<
+ getErrorMessage(ETRAINLIST_FILE_OPEN)<<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ LTKReturnError(ETRAINLIST_FILE_OPEN);
+ }
+
+ //Open the Model data file for writing mode
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(), ios::out);
+ }
+ else
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(),ios::out|ios::binary);
+ }
+
+ //Return error if unable to open the Model data file
+ if(!mdtFileHandle)
+ {
+ listFileHandle.close();
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EMODEL_DATA_FILE_OPEN << " " <<
+ getErrorMessage(EMODEL_DATA_FILE_OPEN)<<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ LTKReturnError(EMODEL_DATA_FILE_OPEN);
+ }
+
+ //Write the number of Shapes
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle << m_numShapes << endl;
+ }
+ else
+ {
+ mdtFileHandle.write((char*) &m_numShapes, sizeof(unsigned short));
+ }
+
+ int errorCode = SUCCESS;
+ while(!listFileHandle.eof())
+ {
+ // Not a sample of a new class
+ if( lastshapeIdFlag == false )
+ {
+ //Get the line from the list file
+ getline(listFileHandle, line, NEW_LINE_DELIMITER);
+
+ path = "";
+
+ //Check if EOF is reached
+ if( listFileHandle.eof() )
+ {
+ eofFlag = true;
+ }
+
+ //Skip commented line
+ if ( line[0] == COMMENTCHAR )
+ {
+ continue;
+ }
+
+ if (eofFlag == false)
+ {
+ //Tokenize the string
+ errorCode = LTKStringUtil::tokenizeString(line, LIST_FILE_DELIMITER, tokens);
+
+ if( errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ listFileHandle.close();
+ mdtFileHandle.close();
+ LTKReturnError(errorCode);
+ }
+
+
+ //Tokens must be of size 2, one is pathname and other is shapeId
+ //If the end of file not reached then continue the looping
+ if( tokens.size() != 2 && eofFlag == false )
+ continue;
+
+ //Tokens[0] indicates the path name
+ path = tokens[0];
+
+ //Tokens[1] indicates the shapeId
+ shapeId = atoi( tokens[1].c_str() );
+
+ if(shapeId < 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<<
+ "The ActiveDTWShapeRecognizer requires training file class Ids to be positive integers and listed in the increasing order"<<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ errorCode = EINVALID_SHAPEID;
+ break;
+ }
+ else if(shapeId < prevClassId)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<<
+ "Shape IDs in the train list file should be in the increasing order. Please use scripts/validateListFile.pl to generate list files." <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ errorCode = EINVALID_ORDER_LISTFILE;
+ break;
+ }
+
+
+ //This condition is used to check the first shape must be start from 0
+ if( initClassFlag == false )
+ {
+ initClassFlag = true;
+ prevClassId=shapeId;
+ }
+ }
+ }
+ else //Sample of a new class; do not read the next line during this iteration
+ {
+ //flag unset to read next line during the next iteration
+ lastshapeIdFlag = false;
+ }
+
+ // Sample from the same class, extract features, and push the extracted features to shapeSamplesVec
+ if( shapeId == prevClassId && ! path.empty())
+ {
+ if( getShapeFeatureFromInkFile(path, shapeFeature) != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<
+ "Error extracting features from the ink file: " <<
+ path << ", extracting features from the next sample."<<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ continue;
+ }
+
+ shapeSampleFeatures.setFeatureVector(shapeFeature);
+ shapeSampleFeatures.setClassID(shapeId);
+
+ ++sampleCount;
+ shapeSamplesVec.push_back(shapeSampleFeatures);
+
+ shapeFeature.clear();
+
+ }
+
+ // Sample of new class seen, or end of list file reached; train all the samples of previous class ID
+ if( shapeId != prevClassId || eofFlag == true )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) <<
+ "Training for class : " << prevClassId << endl;
+
+ //Increase shape count only if there are atleast one sample per class
+ if( sampleCount > 0 )
+ shapeCount++;
+
+ //check that shapecount must not be greater than specified number
+ //of shapes, if projecttype was not dynamic
+ if( !m_projectTypeDynamic && shapeCount > m_numShapes )
+ {
+ errorCode = EINVALID_NUM_OF_SHAPES;
+ break;
+ }
+
+ if( shapeCount > 0 && sampleCount > 0 )
+ {
+
+ /** PERFORM CLUSTERING **/
+
+
+
+ errorCode = performClustering(shapeSamplesVec,clusterIndices);
+
+
+
+ if( errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ listFileHandle.close();
+ mdtFileHandle.close();
+ LTKReturnError(errorCode);
+ }
+
+
+
+
+ int2DVector::iterator iter = clusterIndices.begin();
+ int2DVector::iterator iEnd = clusterIndices.end();
+
+
+
+ /**ITERATING THROUGH THE VARIOUS CLUSTERS **/
+ for(;iter != iEnd; ++iter)
+ {
+ cluster = (*iter);
+
+
+
+ /** SINGLETON VECTORS **/
+ if(cluster.size() < m_minClusterSize)
+ {
+ /**CONSTRUCTING THE SINGLETON VECTOR**/
+ for(int i = 0; i < cluster.size(); i++)
+ singletonVector.push_back(shapeSamplesVec[cluster[i]].getFeatureVector());
+ }
+
+ /** CLUSTER PROCESSING **/
+ else
+ {
+ //gather all the shape samples pertaining to a particular cluster
+ int clusterSize = cluster.size();
+ int i = 0;
+ for( i = 0; i < clusterSize; i++)
+ {
+ //CONVERT ALL THE SHAPE SAMPLES TO FLOAT FEATURE VECTORS
+ floatVector floatFeatureVector;
+ errorCode = m_shapeRecUtil.shapeFeatureVectorToFloatVector(shapeSamplesVec[cluster[i]].getFeatureVector(),
+ floatFeatureVector);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ int floatFeatureVectorSize = floatFeatureVector.size();
+ for(int i = 0; i < floatFeatureVectorSize; i++)
+ tempFeature.push_back(floatFeatureVector[i]);
+
+ featureMatrix.push_back(tempFeature);
+ tempFeature.clear();
+ floatFeatureVector.clear();
+
+ }
+
+
+ /** COMPUTING COVARIANCE MATRIX **/
+ errorCode = computeCovarianceMatrix(featureMatrix,covarianceMatrix,clusterMean);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ //setting cluster mean for cluster model
+
+ clusterModel.setClusterMean(clusterMean);
+
+
+ /** COMPUTING EIGEN VECTORS **/
+ //computes the eigen vector for the larger covarianceMatrix
+ //from the smaller covarianceMatrix
+ errorCode = computeEigenVectorsForLargeDimension(featureMatrix,covarianceMatrix,eigenVectors,eigenValues);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+
+ doubleVector tempEigenVector;
+ int eigenVectorDimension = eigenVectors.size();
+
+ if(eigenVectorDimension <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EEMPTY_EIGENVECTORS << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(EEMPTY_EIGENVECTORS);
+ }
+
+ int numEigenVectors = eigenVectors[0].size();
+
+ if(numEigenVectors <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_NUM_OF_EIGENVECTORS << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(EINVALID_NUM_OF_EIGENVECTORS );
+ }
+
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ for(int j = 0; j < eigenVectorDimension; j++)
+ tempEigenVector.push_back(eigenVectors[j][i]);
+
+ selectedEigenVectors.push_back(tempEigenVector);
+ tempEigenVector.clear();
+ }
+
+
+
+ /**CONSTRUCTING CLUSTER MODEL **/
+ errorCode = clusterModel.setNumSamples(cluster.size());
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+
+ clusterModel.setEigenValues(eigenValues);
+
+ clusterModel.setEigenVectors(selectedEigenVectors);
+
+
+ /**APPENDING THE CLUSTER MODEL VECTOR**/
+ clusterModelVector.push_back(clusterModel);
+
+ featureMatrix.clear();
+ covarianceMatrix.clear();
+ selectedEigenVectors.clear();
+ clusterMean.clear();
+ eigenValues.clear();
+ eigenVectors.clear();
+ }
+ }
+
+
+ clusterIndices.clear();
+
+
+
+ /**CONSTRUCTING SHAPE MODEL**/
+
+ errorCode = shapeModel.setShapeId(shapeCount - 1);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " "<< endl;
+ LTKReturnError(errorCode);
+ }
+
+ shapeModel.setClusterModelVector(clusterModelVector);
+
+ shapeModel.setSingletonVector(singletonVector);
+
+
+ clusterModelVector.clear();
+ singletonVector.clear();
+
+
+ if(LTKSTRCMP(m_prototypeSelection.c_str(), PROTOTYPE_SELECTION_CLUSTERING) == 0)
+ {
+
+ //Writing results to the MDT file
+
+ errorCode = appendShapeModelToMDTFile(shapeModel, mdtFileHandle);
+
+
+ if( errorCode != SUCCESS )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<<errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+
+ listFileHandle.close();
+ mdtFileHandle.close();
+ LTKReturnError(errorCode);
+ }
+
+
+ }
+
+ //Clearing the shapeSampleVector and clusteredShapeSampleVector
+
+
+ shapeSamplesVec.clear();
+
+ //Resetting sampleCount for the next class
+ sampleCount = 0;
+
+ //Set the flag so that the already read line of next class in the list file is not lost
+ lastshapeIdFlag = true;
+
+ prevClassId = shapeId;
+
+ }
+ }
+ }//End of while
+
+ //Closing the Train List file and Model Data file
+ listFileHandle.close();
+ mdtFileHandle.close();
+
+ if(!m_projectTypeDynamic && shapeCount != m_numShapes)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EINVALID_NUM_OF_SHAPES << " " <<
+ getErrorMessage(EINVALID_NUM_OF_SHAPES)<<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ LTKReturnError(EINVALID_NUM_OF_SHAPES);
+ }
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ LTKReturnError(errorCode);
+
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+
+ return SUCCESS;
+
+}
+
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computeCovarianceMatrix
+* DESCRIPTION : This method computes the covariance matrix and mean of
+a feature matrix
+* ARGUMENTS : INPUT
+featureMatrix double2DVector Feature matrix whose covarianceMatrix
+is to be computed
+;OUTPUT
+covarianceMatrix double2DVector covarianceMatrix of feature matrix
+meanFeature doubleVector mean of feature matrix
+
+ * RETURNS : integer Holds error value if occurs
+ * Holds SUCCESS if no errors
+ *************************************************************************************/
+ int ActiveDTWShapeRecognizer::computeCovarianceMatrix(double2DVector& featureMatrix,
+ double2DVector& covarianceMatrix,doubleVector& meanFeature)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeCovarianceMatrix()" << endl;
+
+ if(featureMatrix.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_FEATUREMATRIX << " " <<
+ getErrorMessage(EEMPTY_FEATUREMATRIX) <<
+ " ActiveDTWShapeRecognizer::computeCovarianceMatrix()" << endl;
+
+ LTKReturnError(EEMPTY_FEATUREMATRIX);
+ }
+
+
+ doubleVector tempVector;
+ double mean;
+
+ int numberOfRows;
+ int numberOfColumns;
+
+ //rows
+ numberOfRows = featureMatrix.size();
+ //cols
+ numberOfColumns = featureMatrix[0].size();
+
+
+ int i = 0;
+ int j = 0;
+ /***********CALCULATING MEAN*********/
+ for(i = 0; i < numberOfColumns;i++)
+ {
+ mean = 0.0;
+ for(j = 0;j < numberOfRows;j++)
+ {
+ mean = mean + featureMatrix[j][i];
+ }
+ mean = mean /numberOfRows;
+ meanFeature.push_back(mean);
+ }
+
+ /**********MEAN CORRECTED DATA************/
+ for( i = 0; i < numberOfRows; i++)
+ {
+ for(j = 0; j < numberOfColumns; j++)
+ {
+ featureMatrix[i][j] = featureMatrix[i][j] - meanFeature[j];
+ }
+ }
+
+ /** COMPUTING COVARIANCE MATRIX**/
+ tempVector.assign(numberOfColumns,0.0);
+ covarianceMatrix.assign(numberOfColumns,tempVector);
+ tempVector.clear();
+
+ bool bcovarianceMatrixFlag = false;
+ for( i = 0; i < numberOfColumns; i++)
+ {
+ for(j = 0;j < numberOfColumns; j++)
+ {
+ if(i <= j)
+ {
+ for(int k = 0; k < numberOfRows; k++)
+ {
+
+ covarianceMatrix[i][j] += featureMatrix[k][i]*featureMatrix[k][j];
+
+ }
+ covarianceMatrix[i][j] = covarianceMatrix[i][j] /(numberOfRows - 1);
+ }
+ else
+ {
+ covarianceMatrix[i][j] = covarianceMatrix[j][i];
+ }
+ if(covarianceMatrix[i][j] != 0.0)
+ bcovarianceMatrixFlag = true;
+ }
+ }
+
+ if(!bcovarianceMatrixFlag)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_COVARIANCEMATRIX << " " <<
+ getErrorMessage(EEMPTY_COVARIANCEMATRIX) <<
+ " ActiveDTWShapeRecognizer::computeCovarianceMatrix()" << endl;
+
+ LTKReturnError(EEMPTY_COVARIANCEMATRIX);
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeCovarianceMatrix()" << endl;
+
+ return SUCCESS;
+ }
+
+
+ /**********************************************************************************
+ * AUTHOR : S Anand
+ * DATE : 3-MAR-2009
+ * NAME : computeEigenVectors
+ * DESCRIPTION : This method computes the eigenValues and eigenVectors of
+ a covarianceMatrix
+ * ARGUMENTS : INPUT
+ covarianceMatrix double2DVector (matrix whose eigenValues and eigenVectors are to be computed)
+ rank int (rank of covarianceMatrix)
+ nrot int (number of rotations) This a parameter used by the algorithm
+ OUTPUT
+ eigenValueVec doubleVector Eigen values of covarianceMatrix
+ eigenVectorMatrix double2DVector Eigen vectors of covarianceMatrix
+
+ * RETURNS : integer Holds error value if occurs
+ * Holds SUCCESS if no erros
+ * NOTES :
+ * CHANGE HISTROY
+ * Author Date Description
+ *************************************************************************************/
+ int ActiveDTWShapeRecognizer::computeEigenVectors(double2DVector &covarianceMatrix,const int rank,
+ doubleVector &eigenValueVec, double2DVector &eigenVectorMatrix, int& nrot)
+ {
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeEigenVectors()" << endl;
+
+ if(covarianceMatrix.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_COVARIANCEMATRIX << " " <<
+ getErrorMessage(EEMPTY_COVARIANCEMATRIX) <<
+ " ActiveDTWShapeRecognizer::computeEigenVectors()" << endl;
+
+ LTKReturnError(EEMPTY_COVARIANCEMATRIX);
+ }
+
+ if(rank <= 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EINVALID_RANK << " " <<
+ getErrorMessage(EINVALID_RANK) <<
+ " ActiveDTWShapeRecognizer::computeEigenVectors()" << endl;
+
+ LTKReturnError(EINVALID_RANK);
+ }
+
+ int MAX_ITER = 1000;
+
+ int ip,count,p,q,r;
+
+ double theta, tau, t,sm,s,h,g,c;
+
+ double app,aqq,apq,vpp,vqq,vpq;
+
+ double2DVector::iterator itrRow,itrRowEnd;
+
+ doubleVector::iterator itrCol,itrColEnd;
+
+ itrRowEnd = eigenVectorMatrix.end();
+
+ for(ip = 0,itrRow = eigenVectorMatrix.begin(); itrRow <itrRowEnd;++ip, ++itrRow)
+ {
+ itrColEnd = (*itrRow).end();
+
+ for(itrCol = (*itrRow).begin(); itrCol < itrColEnd; ++itrCol)
+ {
+ *itrCol = 0;
+ }
+
+ *((*itrRow).begin() + ip) = 1;
+
+ eigenValueVec.push_back(0.0);
+ }
+
+ nrot = 0;
+
+ for(count = 0; count < MAX_ITER; count++)
+ {
+ nrot++;
+
+ sm = 0.0;
+
+ itrRowEnd = covarianceMatrix.end();
+
+ for(p = 0,itrRow = covarianceMatrix.begin(); itrRow <itrRowEnd;++p, ++itrRow)
+ {
+ itrColEnd = (*itrRow).end();
+
+ for(itrCol = (*itrRow).begin()+p+1; itrCol < itrColEnd; ++itrCol)
+ {
+ sm += fabs(*itrCol);
+ }
+ }
+
+ if(sm < EPS)
+ {
+ for(r=0;r<rank;r++)
+ {
+ eigenValueVec[r] = covarianceMatrix[r][r];
+ }
+
+ }
+
+ for(p=0; p<(rank-1) ; p++)
+ {
+ for(q=(p+1); q<rank; q++)
+ {
+ if(fabs(covarianceMatrix[p][q])>EPS1)
+ {
+ theta = (covarianceMatrix[q][q] - covarianceMatrix[p][p])/
+ (2*covarianceMatrix[p][q]);
+
+ t = sqrt(1+theta * theta) - theta;
+
+ c = 1/(sqrt(1+t*t));
+
+ s = t*c;
+
+ tau = s/(1+c);
+
+ apq = covarianceMatrix[p][q];
+
+ app = covarianceMatrix[p][p];
+
+ aqq = covarianceMatrix[q][q];
+
+ vpp = eigenVectorMatrix[p][p];
+
+ vpq = eigenVectorMatrix[p][q];
+
+ vqq = eigenVectorMatrix[q][q];
+
+ for(r=0;r<p;r++)
+ {
+ h = covarianceMatrix[r][p];
+
+ g = covarianceMatrix[r][q];
+
+ covarianceMatrix[r][p] = (double)(c*h - s*g);
+
+ covarianceMatrix[r][q] = (double)(c*g + s*h);
+ }
+ covarianceMatrix[p][p] -= (double)(t*apq);
+
+ covarianceMatrix[p][q] = (double)(0.0);
+
+ for(r=p+1; r<q; r++)
+ {
+ h = covarianceMatrix[p][r];
+
+ g = covarianceMatrix[r][q];
+
+ covarianceMatrix[p][r] = (double)(c*h - s*g);
+
+ covarianceMatrix[r][q] = (double)(c*g + s*h);
+ }
+
+ covarianceMatrix[q][q] += (double)(t*apq);
+
+ for(r = q+1; r<rank; r++)
+ {
+ h = covarianceMatrix[p][r];
+
+ g = covarianceMatrix[q][r];
+
+ covarianceMatrix[p][r] = (double)(c*h - s*g);
+
+ covarianceMatrix[q][r] = (double)(c*g + s*h);
+ }
+
+ for(r = 0; r<rank ; r++)
+ {
+ h = eigenVectorMatrix[r][p];
+
+ g = eigenVectorMatrix[r][q];
+
+ eigenVectorMatrix[r][p] = (double)(c*h - s*g);
+
+ eigenVectorMatrix[r][q] = (double)(c*g + s*h);
+ }
+ }
+ else
+ {
+ covarianceMatrix[p][q] = 0;
+ }
+ }
+ }
+
+ }
+
+
+
+ for(r=0;r<rank;r++)
+ {
+ eigenValueVec[r] = covarianceMatrix[r][r];
+ }
+
+ double temp;
+
+ for(p = 0; p<rank-1; p++)
+ {
+ for(q = p+1; q<rank; q++)
+ {
+ if(fabs(eigenValueVec[p]) < fabs(eigenValueVec[q]))
+ {
+ for(r = 0; r<rank; r++)
+ {
+ temp = eigenVectorMatrix[r][p];
+
+ eigenVectorMatrix[r][p] = eigenVectorMatrix[r][q];
+
+ eigenVectorMatrix[r][q] = temp;
+
+ }
+
+ temp = eigenValueVec[p];
+
+ eigenValueVec[p] = eigenValueVec[q];
+
+ eigenValueVec[q] = temp;
+
+ }
+ }
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::computeEigenVectors()" << endl;
+
+ return SUCCESS;
+
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : initializeFeatureExtractorInstance
+* DESCRIPTION : This method get the Instance of the Feature Extractor
+* from LTKShapeFeatureExtractorFactory
+* ARGUMENTS :
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int ActiveDTWShapeRecognizer::initializeFeatureExtractorInstance(const LTKControlInfo& controlInfo)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::initializeFeatureExtractorInstance()" << endl;
+
+
+ LTKShapeFeatureExtractorFactory factory;
+ int errorCode = factory.createFeatureExtractor(m_featureExtractorName,
+ m_lipiRootPath,
+ m_lipiLibPath,
+ &m_libHandlerFE,
+ controlInfo,
+ &m_ptrFeatureExtractor);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EFTR_EXTR_NOT_EXIST << " " <<
+ " ActiveDTWShapeRecognizer::initializeFeatureExtractorInstance()" << endl;
+ LTKReturnError(errorCode);
+ }
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::initializeFeatureExtractorInstance()" << endl;
+
+ return SUCCESS;
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : deleteFeatureExtractorInstance
+* DESCRIPTION : This method unloads the Feature extractor instance
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+int ActiveDTWShapeRecognizer::deleteFeatureExtractorInstance()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::deleteFeatureExtractorInstance()" << endl;
+
+ if (m_ptrFeatureExtractor != NULL)
+ {
+ typedef int (*FN_PTR_DELETE_SHAPE_FEATURE_EXTRACTOR)(LTKShapeFeatureExtractor *obj);
+ FN_PTR_DELETE_SHAPE_FEATURE_EXTRACTOR deleteFeatureExtractor;
+ void * functionHandle = NULL;
+
+ // Map createpreprocessor and deletePreprocessor functions
+ int returnVal = m_OSUtilPtr->getFunctionAddress(m_libHandlerFE,
+ DELETE_SHAPE_FEATURE_EXTRACTOR,
+ &functionHandle);
+
+ // Could not map the createLipiPreprocessor function from the DLL
+ if(returnVal != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<
+ "Error: "<< EDLL_FUNC_ADDRESS_DELETE_FEATEXT << " " <<
+ getErrorMessage(EDLL_FUNC_ADDRESS_DELETE_FEATEXT) <<
+ " ActiveDTWShapeRecognizer::deleteFeatureExtractorInstance()" << endl;
+
+ LTKReturnError(EDLL_FUNC_ADDRESS_DELETE_FEATEXT);
+ }
+
+ deleteFeatureExtractor = (FN_PTR_DELETE_SHAPE_FEATURE_EXTRACTOR)functionHandle;
+
+ deleteFeatureExtractor(m_ptrFeatureExtractor);
+
+ m_ptrFeatureExtractor = NULL;
+
+ // unload feature extractor dll
+ if(m_libHandlerFE != NULL)
+ {
+ //Unload the DLL
+ m_OSUtilPtr->unloadSharedLib(m_libHandlerFE);
+ m_libHandlerFE = NULL;
+
+ }
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::deleteFeatureExtractorInstance()" << endl;
+
+ return SUCCESS;
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : updateHeaderWithAlgoInfo
+* DESCRIPTION : This method will Update the Header information for the MDT file
+* ARGUMENTS :
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+void ActiveDTWShapeRecognizer::updateHeaderWithAlgoInfo()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::updateHeaderWithAlgoInfo()" << endl;
+
+ m_headerInfo[RECVERSION] = m_currentVersion;
+ string algoName = ACTIVEDTW;
+ m_headerInfo[RECNAME] = algoName;
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::updateHeaderWithAlgoInfo()" << endl;
+
+}
+
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getDistance
+* DESCRIPTION :
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+void ActiveDTWShapeRecognizer::getDistance(const LTKShapeFeaturePtr& f1,
+ const LTKShapeFeaturePtr& f2,
+ float& distance)
+{
+ f1->getDistance(f2, distance);
+}
+
+
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getFeaturesFromTraceGroup
+* DESCRIPTION : 1. PreProcess 2. Extract Features 3.Add to PrototypeSet
+* 4. Add to MDT
+* ARGUMENTS :
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+
+int ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup(const LTKTraceGroup& inTraceGroup,
+ vector<LTKShapeFeaturePtr>& featureVec)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup()" << endl;
+
+ //TraceGroup after Preprocessing
+ LTKTraceGroup preprocessedTraceGroup;
+
+ //Check for empty traces in inTraceGroup
+ if(inTraceGroup.containsAnyEmptyTrace())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_TRACE << " " <<
+ getErrorMessage(EEMPTY_TRACE) <<
+ " ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup()" << endl;
+ LTKReturnError(EEMPTY_TRACE);
+ }
+
+ //Preprocess the inTraceGroup
+ int errorCode = preprocess(inTraceGroup, preprocessedTraceGroup);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ errorCode = m_ptrFeatureExtractor->extractFeatures(preprocessedTraceGroup,
+ featureVec);
+
+ if (errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Exiting ActiveDTWShapeRecognizer::extractFeatVecFromTraceGroup()" << endl;
+ return SUCCESS;
+}
+
+/******************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : getTraceGroup
+* DESCRIPTION : Returns the tracegroups of the shape
+* For singletons it returns the tracegroups from the feature vector
+* For clusters it returns the tracegroup of the cluster mean
+* ARGUMENTS : INPUT:
+shapeID - class whose trace groups are to be returned
+numberOfTraceGroups - maximum number of trace groups to be returned
+: OUTPUT
+outTraceGroups - tracegroups of the class
+* RETURNS :
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+******************************************************************************/
+
+int ActiveDTWShapeRecognizer::getTraceGroups(int shapeID, int numberOfTraceGroups,
+ vector<LTKTraceGroup> &outTraceGroups)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Entering ActiveDTWShapeRecognizer::getTraceGroups"
+ <<endl;
+
+ if(m_shapeIDNumPrototypesMap.find(shapeID) == m_shapeIDNumPrototypesMap.end())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EINVALID_SHAPEID << " " <<
+ getErrorMessage(EINVALID_SHAPEID) <<
+ " ActiveDTWShapeRecognizer::getTraceGroups()" << endl;
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ if(m_shapeIDNumPrototypesMap[shapeID] < numberOfTraceGroups)
+ {
+ numberOfTraceGroups = m_shapeIDNumPrototypesMap[shapeID];
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)
+ << "Number of TraceGroup in PrototypeShapes is less than specified."
+ << "Returning all TraceGroups :"
+ << numberOfTraceGroups <<endl;
+ }
+
+ vector<ActiveDTWShapeModel>::iterator prototypeShapesIter = m_prototypeShapes.begin();
+ int counter =0;
+ vector<ActiveDTWClusterModel> clusterModelVector;
+ shapeMatrix singletonVector;
+
+ for(;prototypeShapesIter!=m_prototypeShapes.end();)
+ {
+ int currentShapeId = (*prototypeShapesIter).getShapeId();
+
+ if(currentShapeId == shapeID)
+ {
+ LTKTraceGroup traceGroup;
+
+ clusterModelVector = (*prototypeShapesIter).getClusterModelVector();
+ singletonVector = (*prototypeShapesIter).getSingletonVector();
+
+ int clusterModelVectorSize = clusterModelVector.size();
+ int singletonVectorSize = singletonVector.size();
+
+ if(singletonVectorSize > 0)
+ {
+ //convert singletons into tracegroups
+ for(int i = 0; i < singletonVectorSize; i++)
+ {
+ //converting the featureVector to traceGroup
+ int errorCode = m_ptrFeatureExtractor->convertFeatVecToTraceGroup(
+ singletonVector[i],traceGroup);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::getTraceGroups()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ outTraceGroups.push_back(traceGroup);
+ counter++;
+ if(counter==numberOfTraceGroups)
+ break;
+ }
+ }
+
+
+ if(clusterModelVectorSize > 0)
+ {
+ //converting all the cluster means into traceGroups
+ for(int i = 0; i < clusterModelVectorSize; i++)
+ {
+ doubleVector clusterMean = clusterModelVector[i].getClusterMean();
+
+ //converting the doubleVector to featureVector
+ vector<LTKShapeFeaturePtr> shapeFeatureVec;
+
+ int errorCode = convertDoubleToFeatureVector(shapeFeatureVec,clusterMean);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::getTraceGroups()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ //converting the featureVector to traceGroup
+ errorCode = m_ptrFeatureExtractor->convertFeatVecToTraceGroup(
+ shapeFeatureVec,traceGroup);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::getTraceGroups()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+
+ outTraceGroups.push_back(traceGroup);
+ clusterMean.clear();
+ counter++;
+ if(counter==numberOfTraceGroups)
+ break;
+ }
+ }
+ }
+ prototypeShapesIter++;
+ }
+
+ //clearing vectors
+ clusterModelVector.clear();
+ singletonVector.clear();
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
+ <<"Exiting ActiveDTWShapeRecognizer::getTraceGroups"
+ <<endl;
+ return SUCCESS;
+}
+
+/***********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : initializePreprocessor
+* DESCRIPTION : This method is used to initialize the PreProcessor
+* ARGUMENTS : preprocDLLPath : string : Holds the Path of the Preprocessor DLL,
+* returnStatus : int : Holds SUCCESS or Error Values, if occurs
+* RETURNS : preprocessor instance
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::initializePreprocessor(const LTKControlInfo& controlInfo,
+ LTKPreprocessorInterface** preprocInstance)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+
+ FN_PTR_CREATELTKLIPIPREPROCESSOR createLTKLipiPreProcessor = NULL;
+
+ int errorCode;
+
+ // Load the DLL with path=preprocDLLPath
+ void* functionHandle = NULL;
+
+ int returnVal = m_OSUtilPtr->loadSharedLib(controlInfo.lipiLib, PREPROC, &m_libHandler);
+
+ if(returnVal != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< ELOAD_PREPROC_DLL << " " <<
+ getErrorMessage(ELOAD_PREPROC_DLL) <<
+ " ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+ LTKReturnError(ELOAD_PREPROC_DLL);
+ }
+
+ // Map createpreprocessor and deletePreprocessor functions
+ returnVal = m_OSUtilPtr->getFunctionAddress(m_libHandler,
+ CREATEPREPROCINST,
+ &functionHandle);
+ // Could not map the createLipiPreprocessor function from the DLL
+ if(returnVal != SUCCESS)
+ {
+ //Unload the dll
+ unloadPreprocessorDLL();
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EDLL_FUNC_ADDRESS_CREATE << " " <<
+ getErrorMessage(EDLL_FUNC_ADDRESS_CREATE) <<
+ " ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+
+ LTKReturnError(EDLL_FUNC_ADDRESS_CREATE);
+ }
+
+ createLTKLipiPreProcessor = (FN_PTR_CREATELTKLIPIPREPROCESSOR)functionHandle;
+
+ functionHandle = NULL;
+
+ // Map createpreprocessor and deletePreprocessor functions
+ returnVal = m_OSUtilPtr->getFunctionAddress(m_libHandler,
+ DESTROYPREPROCINST,
+ &functionHandle);
+
+ // Could not map the createLipiPreprocessor function from the DLL
+ if(returnVal != SUCCESS)
+ {
+ //Unload the dll
+ unloadPreprocessorDLL();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EDLL_FUNC_ADDRESS_CREATE << " " <<
+ getErrorMessage(EDLL_FUNC_ADDRESS_CREATE) <<
+ " ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+ LTKReturnError(EDLL_FUNC_ADDRESS_CREATE);
+ }
+
+ m_deleteLTKLipiPreProcessor = (FN_PTR_DELETELTKLIPIPREPROCESSOR)functionHandle;
+
+ // Create preprocessor instance
+ errorCode = createLTKLipiPreProcessor(controlInfo, preprocInstance);
+
+ if(errorCode!=SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ // Could not create a LTKLipiPreProcessor
+ if(*preprocInstance == NULL)
+ {
+ // Unload the DLL
+ unloadPreprocessorDLL();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< ECREATE_PREPROC << " " <<
+ getErrorMessage(ECREATE_PREPROC) <<
+ " ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+ LTKReturnError(ECREATE_PREPROC);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::initializePreprocessor()" << endl;
+
+ return SUCCESS;
+
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : deletePreprocessor
+* DESCRIPTION : This method is used to deletes the PreProcessor instance
+* ARGUMENTS : ptrPreprocInstance : Holds the pointer to the LTKPreprocessorInterface
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+
+//int ActiveDTWShapeRecognizer::deletePreprocessor(LTKPreprocessorInterface *ptrPreprocInstance)
+int ActiveDTWShapeRecognizer::deletePreprocessor()
+{
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::deletePreprocessor()" << endl;
+
+ //deleting the preprocessor instance
+ if(m_ptrPreproc != NULL)
+ {
+ m_deleteLTKLipiPreProcessor(m_ptrPreproc);
+ m_ptrPreproc = NULL;
+ }
+
+ //Unload the dll
+ int returnStatus = unloadPreprocessorDLL();
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Error: " <<
+ getErrorMessage(returnStatus) <<
+ " ActiveDTWShapeRecognizer::deletePreprocessor()" << endl;
+ LTKReturnError(returnStatus);
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::deletePreprocessor()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : unloadPreprocessorDLL
+* DESCRIPTION : This method is used to Unloads the preprocessor DLL.
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::unloadPreprocessorDLL()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::unloadPreprocessorDLL()" << endl;
+
+ //Check the preprocessor DLL was loaded already
+ if(m_libHandler != NULL)
+ {
+ //Unload the DLL
+ m_OSUtilPtr->unloadSharedLib(m_libHandler);
+ m_libHandler = NULL;
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::unloadPreprocessorDLL()" << endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : findOptimalDeformation
+* DESCRIPTION : This method computes the parameters required to construct the optimal
+deformation of each cluster that is closest to the test sample
+* ARGUMENTS : INPUT
+eigenValues doubleVector (eigenValues of cluster)
+eigenVector double2DVector (eigenVectors of cluster)
+clusterMean doubleVector (mean of cluster)
+testSample doubleVector (test sample)
+:OUTPUT
+deformationParameters doubleVector (deformation parameters)
+*
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::findOptimalDeformation(doubleVector& deformationParameters,doubleVector& eigenValues, double2DVector& eigenVector,
+ doubleVector& clusterMean, doubleVector& testSample)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+
+ if(eigenValues.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_EIGENVALUES << " " <<
+ getErrorMessage(EEMPTY_EIGENVALUES) <<
+ " ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+
+ LTKReturnError(EEMPTY_EIGENVALUES);
+ }
+
+ if(eigenVector.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_EIGENVECTORS << " " <<
+ getErrorMessage(EEMPTY_EIGENVECTORS) <<
+ " ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+
+ LTKReturnError(EEMPTY_EIGENVECTORS);
+ }
+
+ if(clusterMean.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_CLUSTERMEAN << " " <<
+ getErrorMessage(EEMPTY_CLUSTERMEAN) <<
+ " ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+
+ LTKReturnError(EEMPTY_CLUSTERMEAN);
+ }
+
+ if(eigenValues.size() != eigenVector.size())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< ENUM_EIGVALUES_NOTEQUALTO_NUM_EIGVECTORS << " " <<
+ getErrorMessage(ENUM_EIGVALUES_NOTEQUALTO_NUM_EIGVECTORS) <<
+ " ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+
+ LTKReturnError(ENUM_EIGVALUES_NOTEQUALTO_NUM_EIGVECTORS);
+ }
+
+
+ doubleVector diffVec;
+ doubleVector linearConstant;
+ doubleVector tempDoubleVec;
+ doubleVector lowerBounds;
+ doubleVector upperBounds;
+ double tempSum;
+
+ int n ;
+
+ int i = 0;
+
+
+
+ /***************CALCULATING PARAMETERS***********************/
+ /**CALCULATING THE DIFFERENCE VECTOR**/
+ diffVec.assign(clusterMean.size(),0.0);
+
+ for(i = 0; i < diffVec.size(); i++)
+ diffVec[i] = testSample[i] - clusterMean[i];
+
+
+ /**CALCULATING THE LINEAR CONSTANT TERM**/
+ //linearConstant is calculated as:
+ //linearConstant = eigVec*diffVec
+ double2DVector::iterator iStart = eigenVector.begin();
+ double2DVector::iterator iEnd = eigenVector.end();
+
+ for(;iStart != iEnd;++iStart)
+ {
+ tempDoubleVec = (*iStart);
+
+ tempSum = 0.0;
+ for(i = 0; i < tempDoubleVec.size(); i++ )
+ {
+
+ tempSum += (tempDoubleVec[i] * diffVec[i]);
+ }
+
+ linearConstant.push_back(tempSum);
+ }
+
+ //problem dimension
+ n = eigenVector.size();
+
+
+
+ double tempBounds;
+
+ for( i = 0; i < n; i++)
+ {
+
+ tempBounds = sqrt(eigenValues[i] * m_eigenSpreadValue);
+ lowerBounds.push_back((-1) * tempBounds);
+ upperBounds.push_back(tempBounds);
+ }
+
+ /**OPTIMIZATION PROCEDURE**/
+ for( i = 0; i < n; i++)
+ {
+ if(linearConstant[i] >= lowerBounds[i] && linearConstant[i] <= upperBounds[i])
+ deformationParameters[i] = linearConstant[i];
+ else
+ {
+ if(linearConstant[i] < lowerBounds[i])
+ deformationParameters[i] = lowerBounds[i];
+ else
+ deformationParameters[i] = upperBounds[i];
+ }
+ }
+
+ //clearing vectors
+ linearConstant.clear();
+ lowerBounds.clear();
+ upperBounds.clear();
+ diffVec.clear();
+ tempDoubleVec.clear();
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::findOptimalDeformation()" << endl;
+ return SUCCESS;
+};
+
+/**************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : validatePreprocParameters
+* DESCRIPTION : This method is used to validate the preproc parameters with
+* mdt header values
+* ARGUMENTS : none
+* RETURNS : none
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+****************************************************************************/
+int ActiveDTWShapeRecognizer::validatePreprocParameters(stringStringMap& headerSequence)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::validatePreprocParameters()" << endl;
+
+
+ string tempStrVar = "";
+ string headerValue = "";
+ int headerValueInt = 0;
+ float headerValueFloat = 0.0f;
+ int tempIntegerValue = 0;
+ float tempFloatValue = 0.0f;
+
+ //preproc sequence
+ string mdtPreprocSeqn = headerSequence[PREPROC_SEQ];
+ if(LTKSTRCMP(m_preProcSeqn.c_str(), mdtPreprocSeqn.c_str()) != 0 &&
+ LTKSTRCMP("NA", mdtPreprocSeqn.c_str()) != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preprocSeqn in config file ("<<
+ m_preProcSeqn <<") does not match with the value in MDT file ("<<
+ mdtPreprocSeqn <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+
+
+ //ResampTraceDimension
+ headerValue = "";
+ if(LTKSTRCMP("NA", headerSequence[TRACE_DIM].c_str()) != 0)
+ {
+ headerValueInt = atoi(headerSequence[TRACE_DIM].c_str());
+ tempIntegerValue = m_ptrPreproc->getTraceDimension();
+
+ if(headerValueInt != tempIntegerValue )
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of TraceDimension in config file ("<<
+ tempIntegerValue<<") does not match with the value in MDT file ("<<
+ headerValueInt <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+ }
+
+
+ // preserve aspect ratio
+ bool preProcPreserveAspectRatio = m_ptrPreproc->getPreserveAspectRatio();
+ tempStrVar = "false";
+ if (preProcPreserveAspectRatio == true)
+ {
+ tempStrVar = "true";
+ }
+
+ if(LTKSTRCMP((headerSequence[PRESER_ASP_RATIO]).c_str(), tempStrVar.c_str()) != 0 &&
+ LTKSTRCMP((headerSequence[PRESER_ASP_RATIO]).c_str(), "NA") != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcPreserveAspectRatio in config file ("<<
+ tempStrVar<<") does not match with the value in MDT file ("<<
+ headerSequence[PRESER_ASP_RATIO] <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+
+ //NormPreserveRelativeYPosition
+ bool preProcNormPreserveRelativeYPosition = m_ptrPreproc->getPreserveRealtiveYPosition();
+ tempStrVar = "false";
+ if (preProcNormPreserveRelativeYPosition == true)
+ {
+ tempStrVar = "true";
+ }
+
+ if(LTKSTRCMP((headerSequence[PRESER_REL_Y_POS]).c_str(), tempStrVar.c_str()) != 0 &&
+ LTKSTRCMP((headerSequence[PRESER_REL_Y_POS]).c_str(), "NA") != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcNormPreserveRelativeYPosition in config file ("<<
+ tempStrVar<<") does not match with the value in MDT file ("<<
+ headerSequence[PRESER_REL_Y_POS] <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+
+
+ // NormPreserveAspectRatioThreshold
+ tempFloatValue = m_ptrPreproc->getAspectRatioThreshold();
+ if(LTKSTRCMP((headerSequence[ASP_RATIO_THRES]).c_str(), "NA") != 0)
+ {
+ headerValueFloat = LTKStringUtil::convertStringToFloat(headerSequence[ASP_RATIO_THRES]);
+
+ if(headerValueFloat != tempFloatValue)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcPreserveAspectRatioThreshold in config file ("<<
+ tempFloatValue<<") does not match with the value in MDT file ("<<
+ headerValueFloat <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+ }
+
+
+
+ // NormLineWidthThreshold
+ if(LTKSTRCMP((headerSequence[DOT_SIZE_THRES]).c_str(), "NA") != 0)
+ {
+ headerValueFloat = LTKStringUtil::convertStringToFloat(headerSequence[DOT_SIZE_THRES]);
+ tempFloatValue = m_ptrPreproc->getSizeThreshold();
+
+ if(headerValueFloat != tempFloatValue)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcNormLineWidthThreshold in config file ("<<
+ tempFloatValue<<") does not match with the value in MDT file ("<<
+ headerValueFloat <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+ }
+
+
+ // NormDotSizeThreshold
+ if(LTKSTRCMP((headerSequence[DOT_THRES]).c_str(), "NA") != 0)
+ {
+ headerValueFloat = LTKStringUtil::convertStringToFloat(headerSequence[DOT_THRES]);
+ tempFloatValue = m_ptrPreproc->getDotThreshold();
+
+ if(headerValueFloat != tempFloatValue)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcNormDotSizeThreshold in config file ("<<
+ tempFloatValue<<") does not match with the value in MDT file ("<<
+ headerValueFloat <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+ }
+
+
+
+ //ResampPointAllocation
+ tempStrVar = "";
+ tempStrVar = m_ptrPreproc->getResamplingMethod();
+ if(LTKSTRCMP((headerSequence[RESAMP_POINT_ALLOC]).c_str(), tempStrVar.c_str()) != 0 &&
+ LTKSTRCMP((headerSequence[RESAMP_POINT_ALLOC]).c_str(), "NA") != 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcResampPointAllocation in config file ("<<
+ tempStrVar<<") does not match with the value in MDT file ("<<
+ headerSequence[RESAMP_POINT_ALLOC] <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+
+
+ //SmoothWindowSize
+ if(LTKSTRCMP((headerSequence[SMOOTH_WIND_SIZE]).c_str(), "NA") != 0)
+ {
+ headerValueInt = atoi(headerSequence[SMOOTH_WIND_SIZE].c_str());
+ tempIntegerValue = m_ptrPreproc->getFilterLength();
+
+ if(headerValueInt != tempIntegerValue)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< ECONFIG_MDT_MISMATCH << " " <<
+ "Value of preProcSmoothWindowSize in config file ("<<
+ tempIntegerValue<<") does not match with the value in MDT file ("<<
+ headerValueInt <<")"<<
+ " ActiveDTWShapeRecognizer::loadModelData()" << endl;
+ LTKReturnError(ECONFIG_MDT_MISMATCH);
+ }
+ }
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::validatePreprocParameters()" << endl;
+ return SUCCESS;
+
+}
+
+
+/*********************************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : computeEigenVectorsForLargeDimension
+* DESCRIPTION : This method computes the eigen values and eigen vectors for larger
+covariance matrices of large dimension using the eigen value and
+eigen vectors of the smaller covariance matrix
+* ARGUMENTS :INPUT
+meanCorrectedData double2DVector
+-- used for constructing the smaller covariance matrix
+covarianceMatrix double2DVector
+-- this is the larger covariance matrix whose eigen values and
+eigen vectors are to be computed
+:OUTPUT
+eigenValues doubleVector
+-- eigenValues of the larger covarianceMatrix
+eigenVectors double2DVector
+-- eigenVectors of the larger covarianceMatrix
+*
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+* NOTES : This based on a paper implementation
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::computeEigenVectorsForLargeDimension(double2DVector& meanCorrectedData,double2DVector& covarianceMatrix,
+ double2DVector& eigenVector,doubleVector& eigenValues)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::computeEigenVectorsForLargeDimension()" << endl;
+
+ if(meanCorrectedData.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_MEANCORRECTEDDATA << " " <<
+ getErrorMessage(EEMPTY_MEANCORRECTEDDATA) <<
+ " ActiveDTWShapeRecognizer::computeEigenVectorsForLargeDimension()" << endl;
+
+ LTKReturnError(EEMPTY_MEANCORRECTEDDATA);
+ }
+
+ if(covarianceMatrix.empty())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EEMPTY_COVARIANCEMATRIX << " " <<
+ getErrorMessage(EEMPTY_COVARIANCEMATRIX) <<
+ " ActiveDTWShapeRecognizer::computeEigenVectorsForLargeDimension()" << endl;
+
+ LTKReturnError(EEMPTY_COVARIANCEMATRIX);
+ }
+
+
+ //covarianceSmall = A(transpose) * A
+ double2DVector covarianceSmall;
+
+ doubleVector tempVector;
+
+ //eigen values and eigen vectors of A(transpose) * A
+ double2DVector eigVecMat;
+ doubleVector eigValVec;
+
+ //number of iterations for computing eigen vectors
+ int nrot = 0;
+
+ int meanCorrectedDataSize = meanCorrectedData.size();
+ int rowSize = meanCorrectedData[0].size();
+
+ tempVector.assign(meanCorrectedDataSize,0.0);
+ covarianceSmall.assign(meanCorrectedDataSize,tempVector);
+ tempVector.clear();
+
+ int i = 0;
+ int j = 0;
+
+ //calculating A(transpose)* A
+ for(i = 0; i < meanCorrectedDataSize; i++)
+ {
+ for(j = 0;j < meanCorrectedDataSize; j++)
+ {
+ if(i <= j)
+ {
+ for(int k = 0; k < rowSize; k++)
+ {
+ covarianceSmall[i][j] += meanCorrectedData[i][k]*meanCorrectedData[j][k];
+ }
+ covarianceSmall[i][j] = covarianceSmall[i][j] /(meanCorrectedDataSize -1);
+ }
+ else
+ {
+ covarianceSmall[i][j] = covarianceSmall[j][i];
+ }
+ }
+ }
+
+
+ //allocating memory for eigVecMat
+ tempVector.assign(meanCorrectedDataSize,0.0);
+ eigVecMat.assign(meanCorrectedDataSize,tempVector);
+ tempVector.clear();
+
+
+ //computing the eigen vectors of A(transpose)*A
+
+
+ int errorCode = computeEigenVectors(covarianceSmall,covarianceSmall.size(),
+ eigValVec,eigVecMat,nrot);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::trainFromListFile()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+
+
+
+
+ /**CALCULATING EIGEN ENERGY **/
+ double totalEigenEnergy = 0.0;
+ double currentEigenEnergy = 0.0;
+ int numEigenVectors = 0;
+
+ int eigenValSize = eigValVec.size();
+ for( i = 0; i < eigenValSize; i++)
+ totalEigenEnergy += eigValVec[i];
+
+ /**DETERMINING NUMBER OF EIGEN VECTORS**/
+ while(currentEigenEnergy <= ((m_percentEigenEnergy*totalEigenEnergy)/100) && numEigenVectors < eigenValSize)
+ currentEigenEnergy += eigValVec[numEigenVectors++];
+
+ /**COMPUTING THE EIGEN VECTORS OF THE LARGER COVARIANCE MATRIX AS (A * EIGENVECTOR) **/
+
+ tempVector.assign(numEigenVectors,0.0);
+ eigenVector.assign(rowSize,tempVector);
+ tempVector.clear();
+
+ for( i = 0; i < rowSize; i++)
+ {
+ for(int j = 0; j < numEigenVectors; j++)
+ {
+ for(int k = 0; k < meanCorrectedDataSize; k++)
+ {
+ eigenVector[i][j] += meanCorrectedData[k][i] * eigVecMat[k][j];
+ }
+ }
+ }
+
+ //calculating the magnitude of each eigenVectors
+ doubleVector magnitudeVector;
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ double tempMagnitude = 0;
+ for(j = 0; j < rowSize; j++)
+ tempMagnitude += (eigenVector[j][i] * eigenVector[j][i]);
+ double sqrtMagnitude = sqrt(tempMagnitude);
+ magnitudeVector.push_back(sqrtMagnitude);
+ }
+
+
+ //normalizing eigenVectors
+ for( i = 0; i < numEigenVectors; i++)
+ {
+ for(j = 0; j < rowSize; j++)
+ eigenVector[j][i] = (eigenVector[j][i]/magnitudeVector[i]);
+ }
+ magnitudeVector.clear();
+
+ //selecting the corresponding eigen values
+ for( i = 0; i < numEigenVectors; i++)
+ eigenValues.push_back(eigValVec[i]);
+
+ eigVecMat.clear();
+ eigValVec.clear();
+ covarianceSmall.clear();
+
+
+ return SUCCESS;
+
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : convertDoubleToFeatureVector
+* DESCRIPTION : This method converts the double Vector (flatenned version of the feature vector)
+to the vector<LTKShapeFeaturePtr> form
+* ARGUMENTS : INPUT
+* featureVec doubleVector
+:OUTPUT
+shapeFeatureVec vector<LTKShapeFeaturePtr>
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no erros
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::convertDoubleToFeatureVector(vector<LTKShapeFeaturePtr>& shapeFeatureVec,doubleVector& featureVec)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::convertDoubleToFeatureVector" << endl;
+
+ LTKShapeFeaturePtr shapeFeature;
+ int featureVectorSize = featureVec.size();
+ int featureDimension;
+ floatVector tempFeature;
+
+ for(int i = 0; i < featureVectorSize;)
+ {
+ shapeFeature = m_ptrFeatureExtractor->getShapeFeatureInstance();
+ featureDimension = shapeFeature->getFeatureDimension();
+
+
+ for(int j = 0; j < featureDimension; j++)
+ {
+ tempFeature.push_back((float)featureVec[i]);
+ i++;
+ }
+
+
+ if (shapeFeature->initialize(tempFeature) != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_INPUT_FORMAT << " " <<
+ "Number of features extracted from a trace is not correct"<<
+ " ActiveDTWShapeRecognizer::convertDoubleToFeatureVector" << endl;
+
+ LTKReturnError(EINVALID_INPUT_FORMAT);
+ }
+ shapeFeatureVec.push_back(shapeFeature);
+
+ tempFeature.clear();
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::convertDoubleToFeatureVector" << endl;
+
+ return SUCCESS;
+
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : adapt
+* DESCRIPTION : adapt recent recognized sample
+* ARGUMENTS : shapeID : True shapeID of sample
+* RETURNS : Success : If sample was adapted successfully
+* Failure : Returns Error Code
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::adapt(int shapeId)
+{
+ try{
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)
+ << "Enter ActiveDTWShapeRecognizer::adapt()"<<endl;
+
+ //check if shapeId has already seen by classifier else add shapeId
+ if(m_shapeIDNumPrototypesMap.find(shapeId) == m_shapeIDNumPrototypesMap.end())
+ {
+
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ //Adaptation Code
+ LTKAdapt* adaptObj = LTKAdapt::getInstance(this);
+
+ int nErrorCode;
+ nErrorCode = adaptObj->adapt(shapeId);
+ if(nErrorCode !=0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during ActiveDTWShapeRecognizer::adapt()"<<endl;
+ LTKReturnError(nErrorCode);
+ }
+
+ //Clear Variables cached
+ m_neighborInfoVec.clear();
+ m_vecRecoResult.clear();
+
+ }
+ catch(...)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during ActiveDTWShapeRecognizer::adapt()"<<endl;
+ return FAILURE;
+ }
+
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)
+ << "Exit ActiveDTWShapeRecognizer::adapt()"<<endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : adapt
+* DESCRIPTION : adapt sample passed as argument
+* ARGUMENTS : sampleTraceGroup : TraceGroup of sample to be adapted
+* shapeID : True shapeID of sample
+* RETURNS : Success : If sample was adapted successfully
+* Failure : Returns Error Code
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::adapt(const LTKTraceGroup& sampleTraceGroup, int shapeId )
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)
+ << "Enter ActiveDTWShapeRecognizer::Adapt()"<<endl;
+
+ int errorCode;
+
+ if(shapeId < 0)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "ActiveDTWShapeRecognizer::Adapt(): Invalid shapeId"<< endl;
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ //check if shapeId has already seen by classifier else add shapeId
+ if(m_shapeIDNumPrototypesMap.find(shapeId) == m_shapeIDNumPrototypesMap.end())
+ {
+ //add class
+ errorCode = addClass(sampleTraceGroup, shapeId);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during call to recognize in ActiveDTWShapeRecognizer::Adapt()"<<endl;
+ LTKReturnError(errorCode);
+ }
+ }
+ else
+ {
+ //recognize and adapt
+ vector<int> vecSubSet;
+ vector<LTKShapeRecoResult> vecRecoResult;
+ LTKScreenContext objScreenContext;
+
+ errorCode = recognize(sampleTraceGroup,objScreenContext,
+ vecSubSet,CONF_THRESHOLD_FILTER_OFF,
+ NN_DEF_RECO_NUM_CHOICES,vecRecoResult);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during call to recognize in ActiveDTWShapeRecognizer::Adapt()"<<endl;
+ LTKReturnError(errorCode);
+ }
+
+ errorCode = adapt(shapeId);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)
+ << "Error during call to recognize in ActiveDTWShapeRecognizer::Adapt()"<<endl;
+ LTKReturnError(errorCode);
+ }
+
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_INFO)
+ << "Exit ActiveDTWShapeRecognizer::Adapt()"<<endl;
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : deleteAdaptInstance
+* DESCRIPTION : delete AdaptInstance
+* ARGUMENTS :
+* RETURNS : None
+* NOTES :
+* CHANGE HISTROY
+* Author Date Description
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::deleteAdaptInstance()
+{
+ //Implemented as deleteAdaptInstance is called by ~NNShapeRecognizer
+ //and adaptObj object is not available in NN.cpp
+
+ LTKAdapt *adaptInstance = LTKAdapt::getInstance(this);
+ if(adaptInstance)
+ {
+ adaptInstance->deleteInstance();
+ }
+
+ return SUCCESS;
+}
+
+/**********************************************************************************
+* AUTHOR ; S Anand
+* DATE : 3-MAR-2009
+* NAME : writePrototypeShapesToMDTFile
+* DESCRIPTION : Flushes the prototype shapes data to activedtw.mdt file
+* ARGUMENTS :
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+
+int ActiveDTWShapeRecognizer::writePrototypeShapesToMDTFile()
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::writePrototypeShapesToMDTFile()" << endl;
+
+ int errorCode = SUCCESS;
+
+ //Flush to MDT only after m_MDTUpdateFreq modifications
+ m_prototypeSetModifyCount++;
+
+ if(m_prototypeSetModifyCount == m_MDTUpdateFreq)
+ {
+ m_prototypeSetModifyCount = 0;
+
+ ofstream mdtFileHandle;
+
+ //Open the Model data file for writing mode
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(), ios::out);
+ }
+ else
+ {
+ mdtFileHandle.open(m_activedtwMDTFilePath.c_str(),ios::out|ios::binary);
+ }
+
+ //Return error if unable to open the Model data file
+ if(!mdtFileHandle)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< EMODEL_DATA_FILE_OPEN << " " <<
+ getErrorMessage(EMODEL_DATA_FILE_OPEN) <<
+ " ActiveDTWShapeRecognizer::writePrototypeShapesToMDTFile()" << endl;
+
+ LTKReturnError(EMODEL_DATA_FILE_OPEN);
+ }
+
+ //write the number of shapes to MDT file
+
+ if ( m_MDTFileOpenMode == NN_MDT_OPEN_MODE_ASCII )
+ {
+ // 0 represents dynamic
+ mdtFileHandle << 0 << endl;
+ }
+ else
+ {
+ int numShapes = 0;
+ mdtFileHandle.write((char*) &numShapes, sizeof(unsigned short));
+ }
+
+ int prototypeShapesSize = m_prototypeShapes.size();
+
+ for(int i = 0; i < prototypeShapesSize; i++)
+ {
+ errorCode = appendShapeModelToMDTFile(m_prototypeShapes[i],mdtFileHandle);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::writePrototypeShapesToMDTFile()" << endl;
+ LTKReturnError(errorCode);
+ }
+ }
+
+ mdtFileHandle.close();
+
+ //Updating the Header Information
+ updateHeaderWithAlgoInfo();
+
+ //Adding header information and checksum generation
+ string strModelDataHeaderInfoFile = "";
+ LTKCheckSumGenerate cheSumGen;
+
+ errorCode = cheSumGen.addHeaderInfo(
+ strModelDataHeaderInfoFile,
+ m_activedtwMDTFilePath,
+ m_headerInfo);
+
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::writePrototypeSetToMDTFile()" << endl;
+
+ LTKReturnError(errorCode);
+ }
+ }
+
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::writePrototypeShapesToMDTFile()" << endl;
+
+ return SUCCESS;
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : addClass
+* DESCRIPTION : Adds a new trace group as a class
+* ARGUMENTS : INPUT
+sampleTraceGroup LTKTraceGroup
+shapeID int
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::addClass(const LTKTraceGroup& sampleTraceGroup, int& shapeID)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::addClass()" << endl;
+
+ int errorCode;
+
+ //unless projecttype is dynamic we cannot add classes
+ if(!m_projectTypeDynamic)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EPROJ_NOT_DYNAMIC << " " <<
+ "Not allowed to ADD shapes to a project with fixed number of shapes"<<
+ " ActiveDTWShapeRecognizer::addClass()" << endl;
+
+ LTKReturnError(EPROJ_NOT_DYNAMIC);
+ }
+
+
+ //if the sample does not have a shape id, we assign it NEW_SHAPEID = -2 in runshaperecInternal
+ //then in the following module we determine the new shape id based on the existing shape ids
+ if(shapeID = NEW_SHAPEID)
+ {
+ int tempShapeID;
+
+ if(m_shapeIDNumPrototypesMap.size() > 0)
+ {
+ map<int,int>::reverse_iterator m_shapeIDNumPrototypesMapIter;
+ m_shapeIDNumPrototypesMapIter = m_shapeIDNumPrototypesMap.rbegin();
+ tempShapeID = m_shapeIDNumPrototypesMapIter->first;
+ shapeID = tempShapeID+1;
+ }
+ else
+ {
+ shapeID = LTK_START_SHAPEID;
+ }
+
+ }
+
+ vector<LTKShapeFeaturePtr> tempFeatureVec;
+
+ errorCode = extractFeatVecFromTraceGroup(sampleTraceGroup,tempFeatureVec);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::addClass()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ shapeMatrix newShapeMatrix;
+
+ newShapeMatrix.push_back(tempFeatureVec);
+
+ //add the feature vector as a singleton Vector
+ ActiveDTWShapeModel newShapeModel;
+
+
+ errorCode = newShapeModel.setShapeId(shapeID);
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< errorCode << " "<< endl;
+ LTKReturnError(errorCode);
+ }
+
+ newShapeModel.setSingletonVector(newShapeMatrix);
+
+ if(m_prototypeShapes.empty())
+ {
+ m_prototypeShapes.push_back(newShapeModel);
+ }
+ else
+ {
+ int prototypeShapesSize = m_prototypeShapes.size();
+ int maxClassId = m_prototypeShapes[prototypeShapesSize - 1].getShapeId();
+
+ if(shapeID > maxClassId)
+ m_prototypeShapes.push_back(newShapeModel);
+ else
+ {
+ vector<ActiveDTWShapeModel>::iterator prototypeShapesIter = m_prototypeShapes.begin();
+
+ while(prototypeShapesIter != m_prototypeShapes.end())
+ {
+ int currentShapeId = (*prototypeShapesIter).getShapeId();
+
+ if(currentShapeId > shapeID)
+ {
+ m_prototypeShapes.insert(prototypeShapesIter,newShapeModel);
+ break;
+ }
+ prototypeShapesIter++;
+ }
+ }
+ }
+
+ //Update m_shapeIDNumPrototypesMap
+ m_shapeIDNumPrototypesMap[shapeID]= 1;
+
+ //Update MDT File
+ errorCode = writePrototypeShapesToMDTFile();
+ if(errorCode != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error: "<< errorCode << " " <<
+ " ActiveDTWShapeRecognizer::addClass()" << endl;
+ LTKReturnError(errorCode);
+ }
+
+ //clearing vectors
+ tempFeatureVec.clear();
+ newShapeMatrix.clear();
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::addClass()" << endl;
+
+ return SUCCESS;
+}
+/**********************************************************************************
+* AUTHOR : S Anand
+* DATE : 3-MAR-2009
+* NAME : deleteClass
+* DESCRIPTION : Deletes the class with shapeID
+* ARGUMENTS : INPUT
+shapeID int
+* RETURNS : integer Holds error value if occurs
+* Holds SUCCESS if no errors
+*************************************************************************************/
+int ActiveDTWShapeRecognizer::deleteClass(int shapeID)
+{
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " <<
+ "ActiveDTWShapeRecognizer::deleteClass()" << endl;
+
+ if(!m_projectTypeDynamic)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EPROJ_NOT_DYNAMIC << " " <<
+ "Not allowed to delete shapes to a project with fixed number of Shapes"<<
+ " ActiveDTWShapeRecognizer::deleteClass()" << endl;
+
+ LTKReturnError(EPROJ_NOT_DYNAMIC);
+ }
+
+ //Validate Input Parameters - shapeID
+ if(m_shapeIDNumPrototypesMap.find(shapeID) ==m_shapeIDNumPrototypesMap.end())
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: "<< EINVALID_SHAPEID << " " <<
+ "shapeID is not valid"<<
+ " ActiveDTWShapeRecognizer::deleteClass()" << endl;
+
+ LTKReturnError(EINVALID_SHAPEID);
+ }
+
+ vector<ActiveDTWShapeModel>::iterator prototypeShapesIter;
+
+ int prototypeShapesSize = m_prototypeShapes.size();
+ int k = 0;
+
+ for(int i = 0; i < prototypeShapesSize; i++)
+ {
+ prototypeShapesIter = m_prototypeShapes.begin() + k;
+
+ int classId = (*prototypeShapesIter).getShapeId();
+
+ if(classId == shapeID)
+ {
+ vector<ActiveDTWClusterModel> currentClusterModelVector;
+ shapeMatrix currentSingletonVector;
+
+ //clearing cluster Model and singleton vectors
+ currentClusterModelVector = (*prototypeShapesIter).getClusterModelVector();
+ currentClusterModelVector.clear();
+ (*prototypeShapesIter).setClusterModelVector(currentClusterModelVector);
+
+ currentSingletonVector = (*prototypeShapesIter).getSingletonVector();
+ currentSingletonVector.clear();
+ (*prototypeShapesIter).setSingletonVector(currentSingletonVector);
+
+ m_prototypeShapes.erase(prototypeShapesIter);
+ continue;
+ }
+ k++;
+ prototypeShapesIter++;
+ }
+
+ //Update m_shapeIDNumPrototypesMap
+ m_shapeIDNumPrototypesMap.erase(shapeID);
+
+ //Update MDT File
+ int returnStatus = writePrototypeShapesToMDTFile();
+
+ if(returnStatus != SUCCESS)
+ {
+ LOG(LTKLogger::LTK_LOGLEVEL_ERR)<<"Error: " << returnStatus << " " <<
+ "Exiting ActiveDTWShapeRecognizer::deleteClass" <<endl;
+ LTKReturnError(returnStatus);
+ }
+
+
+ LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " <<
+ "ActiveDTWShapeRecognizer::deleteClass()" << endl;
+
+ return SUCCESS;
+}
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.h b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.h
new file mode 100644
index 00000000..9459d5c7
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/ActiveDTWShapeRecognizer.h
@@ -0,0 +1,1203 @@
+/*****************************************************************************************
+* Copyright (c) 2006 Hewlett-Packard Development Company, L.P.
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+* Software, and to permit persons to whom the Software is furnished to do so,
+* subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies
+* or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*****************************************************************************************/
+/************************************************************************
+* SVN MACROS
+*
+* $LastChangedDate: 2011-08-23 13:28:15 +0530 (Tue, 23 Aug 2011) $
+* $Revision: 857 $
+* $Author: jitender $
+*
+************************************************************************/
+/*********************************************************************************************
+* FILE DESCR: Definitions for ActiveDTW Shape Recognition module
+*
+* CONTENTS:
+*
+* AUTHOR: S Anand
+*
+*
+* DATE:3-MAR-2009
+* CHANGE HISTORY:
+* Author Date Description of change
+***********************************************************************************************/
+
+
+#ifndef __ACTIVEDTWSHAPERECOGNIZER_H
+#define __ACTIVEDTWSHAPERECOGNIZER_H
+
+#include "LTKInc.h"
+#include "LTKTypes.h"
+#include "LTKMacros.h"
+#include "LTKShapeRecognizer.h"
+#include "LTKShapeRecoUtil.h"
+#include "LTKShapeSample.h"
+#include "LTKCheckSumGenerate.h"
+#include "LTKDynamicTimeWarping.h"
+#include "ActiveDTWShapeModel.h"
+#include "ActiveDTWAdapt.h"
+
+class LTKTraceGroup;
+class LTKPreprocessorInterface;
+class LTKShapeSample;
+class LTKShapeFeatureExtractor;
+class LTKShapeFeature;
+class LTKAdapt;
+
+#define SIMILARITY(distance) (1 / (distance + EPS ))
+#define SUPPORTED_MIN_VERSION "3.0.0"
+
+#define CLUSTER 0
+#define SINGLETON 1
+
+#define INVALID_SHAPEID -2
+#define NEW_SHAPEID -2
+
+//#ifdef _INTERNAL
+//#endif
+
+typedef int (*FN_PTR_LOCAL_DISTANCE)(LTKShapeFeaturePtr, LTKShapeFeaturePtr,float&);
+typedef int (*FN_PTR_CREATELTKLIPIPREPROCESSOR)(const LTKControlInfo& , LTKPreprocessorInterface** );
+typedef int (*FN_PTR_DELETELTKLIPIPREPROCESSOR)(LTKPreprocessorInterface* );
+
+typedef vector<LTKShapeFeaturePtr> shapeFeature;
+typedef vector<shapeFeature> shapeMatrix;
+
+
+/**
+* @ingroup ActiveDTWShapeRecognizer.h
+* @brief The Header file for the ActiveDTWShapeRecognizer
+* @class ActiveDTWShapeRecognizer
+*<p> <p>
+*/
+
+class ActiveDTWShapeRecognizer: public LTKShapeRecognizer
+{
+
+public:
+ //#ifdef _INTERNAL
+ friend class LTKAdapt;
+ int adapt(int shapeID );
+ int adapt(const LTKTraceGroup& sampleTraceGroup, int shapeID );
+
+ /**
+ * This function does the recognition function required for training phase (called from trainLVQ)
+ * The input parameter are the incharacter, which is compared with the existing
+ * set of prototypes and then the matched code vector and along with its index (and also the shape id) is returned
+ * @param incharacter is the character which we are trying to recognise.
+ * @param returnshapeID is the value of the matched character which is returned, codeCharacter is the matched prototype (code vector) vector, and codeVecIndex is the matched prototype (code vector) index
+ */
+ int trainRecognize(LTKShapeSample& inShapeSample, LTKShapeSample& bestShapeSample, int& codeVecIndex);
+
+ int writePrototypeShapesToMDTFile();
+
+ int addClass(const LTKTraceGroup& sampleTraceGroup, int& shapeID);
+
+ int deleteClass(int shapeID);
+
+ int readInternalClassifierConfig();
+
+private:
+
+ int deleteAdaptInstance();
+
+
+
+ // #endif
+
+
+private:
+
+ FN_PTR_DELETELTKLIPIPREPROCESSOR m_deleteLTKLipiPreProcessor;
+ //Function pointer for deleteLTKLipiPreProcessor
+
+ // preproc lib handle
+ void *m_libHandler;
+
+ // feature extractor lib handle
+ void *m_libHandlerFE;
+
+ unsigned short m_numShapes;
+ /**< @brief Number of shapes
+ * <p>
+ * It Defines the number of shapes to be recognized
+ *
+ * DEFAULT: 0
+ *
+ * Note: If the project is dynamic, then this numShapes was set to 0
+ * If the project is not dynamic, then the numShapes was read from project configuration file
+ * </p>
+ */
+
+
+ string m_prototypeSelection;
+ /**< @brief The Prototype Selection
+ * <p>
+ * if Prototype Selection = clustering, the training method used was clustering
+ *
+ * DEFAULT: LTKPreprocDefaults::NN_DEF_PROTOTYPESELECTION
+ * Possible values are "clustering"
+ * </p>
+ */
+
+ int m_prototypeReductionFactor;
+ /**< @brief The prototype Reduction factor
+ * <p>
+ * if PrototypeReductionFactor = 0 every training sample is cluster on its own
+ * = 100 all training samples are represented by one prototype
+ * = 80 then all samples are represented by 20% of the training samples
+ *
+ * DEFAULT: LTKPreprocDefaults::NN_DEF_PROTOTYPEREDUCTIONFACTOR
+ * RANGE: 0 TO 100
+ * </p>
+ */
+
+ int m_numClusters;
+ /**< @brief The number of clusters
+ * <p>
+ * if NumClusters = k, then k clusters are found from the training samples
+ *
+ *
+ *
+ * DEFAULT: There is no default as this and prototype reduction factor are dependent
+ * RANGE:
+ * </p>
+ */
+
+
+ float m_percentEigenEnergy;
+ /**< @brief The percent of Eigen Energy
+ * <p>
+ * if PercentEigenEnergy = 90 then those eigen values contributing to 90% of the Eigen Energy,
+ * and their corresponding eigen vectors are retained
+ *
+ *
+ * DEFAULT: LTKClassifierDefaults::ACTIVEDTW_DEF_PERCENTEIGENENERGY
+ * RANGE: 1-100
+ * </p>
+ */
+
+ int m_eigenSpreadValue;
+ /**< @brief The eigen values spread range
+ * <p>
+ * if EigenSpreadValue = 16 then deformation parameters for computing the optimal deformation,
+ * can lie in the range [-4*Eigen Value,4*Eigen Value]
+ *
+ *
+ * DEFAULT: LTKClassifierDefaults::ACTIVEDTW_DEF_EIGENSPREADVALUE
+ * RANGE: greater than 0
+ * </p>
+ */
+
+ int m_minClusterSize;
+ /**< @brief The minimum cluster size
+ * <p>
+ * It specifies the minimum number of samples required to form a cluster
+ *
+ *
+ * DEFAULT: LTKPreprocDefaults::ADAPT_DEF_MIN_NUMBER_SAMPLES_PER_CLASS
+ * RANGE: >= 2
+ * </p>
+ */
+
+ bool m_useSingleton;
+ /**< @brief Use Singletons
+ * <p>
+ * It specifies if singletons should be considered during the recognition process
+ * If Use Singleton is true, singletons will be considered during the recognition process,
+ * else they will be ignored
+ *
+ * DEFAULT: LTKClassifierDefaults::ACTIVEDTW_DEF_USESINGLETON
+ * RANGE: True or False
+ * </p>
+ */
+
+
+ int m_nearestNeighbors;
+ /**< @brief Nearest Neighbors
+ * <p>
+ *
+ * DEFAULT: LTKClassifierDefaults::NN_DEF_NEARESTNEIGHBORS
+ * </p>
+ */
+
+
+ float m_dtwBanding;
+ /**< @brief DTW Banding
+ * <p>
+ *
+ * DEFAULT: LTKClassifierDefaults::NN_DEF_BANDING
+ * </p>
+ */
+
+ int m_dtwEuclideanFilter;
+ /**< @brief DTW Euclidean Filter
+ * <p>
+ *
+ * DEFAULT: LTKClassifierDefaults::ACTIVEDTW_DEF_DTWEUCLIDEANFILTER
+ * </p>
+ */
+
+ string m_featureExtractorName;
+ /**< @brief The Feature Extractor
+ * <p>
+ *
+ * DEFAULT:
+ *
+ * </p>
+ */
+
+ bool m_projectTypeDynamic;
+ /**< @brief Project Dynamic
+ * <p>
+ * if projectTypeDynamic = true, then the project is dynamic ie, the numShapes can take any number of value
+ * = false, then the project is not dynamic ie, the numShape can take value specified in project.cfg file
+ *
+ * DEFAULT: false
+ * </p>
+ */
+
+ LTKPreprocessorInterface *m_ptrPreproc;
+ /**< @brief Pointer to preprocessor instance
+ * <p>
+ * Instance which is used to call the preprocessing methods before recognition
+ *
+ * DEFAULT: NULL
+ * </p>
+ */
+
+ string m_activedtwCfgFilePath;
+ /**< @brief Full path of ActiveDTW configuration file
+ * <p>
+ * Assigned value in the ActiveDTWShapeRecognizer::initialize function
+ * </p>
+ */
+
+ string m_activedtwMDTFilePath;
+ /**< @brief Full path of Model data file
+ * <p>
+ * Assigned value in the ActiveDTWShapeRecognizer::initialize function
+ * </p>
+ */
+
+ stringStringMap m_headerInfo;
+ /**< @brief Header Information
+ * <p>
+ * </p>
+ */
+
+ LTKShapeRecoUtil m_shapeRecUtil;
+ /**< @brief Pointer to LTKShapeRecoUtil class
+ * <p>
+ * Instance which used to call Shape Recognizer Utility functions
+ *
+ * DEFAULT: NULL
+ */
+
+ string m_lipiRootPath;
+ /**< @brief Path of the Lipi Root
+ * <p>
+ * DEFAULT: LipiEngine::getLipiPath()
+ * </p>
+ */
+
+ string m_lipiLibPath;
+ /**< @brief Path of the Lipi Libraries
+ * <p>
+ * DEFAULT: LipiEngine::getLipiLibPath()
+ * </p>
+ */
+
+ LTKShapeFeatureExtractor *m_ptrFeatureExtractor;
+ /**< @brief Pointer to LTKShapeFeatureExtractor class
+ * <p>
+ * DEFAULT: NULL
+ * </p>
+ */
+
+ string m_preProcSeqn;
+ /**< @brief Preprocessor Sequence
+ * <p>
+ * This string will holds what sequence the preprocessor methods to be executed
+ * </p>
+ */
+
+ LTKCaptureDevice m_captureDevice;
+
+ /** Structure to store information required for recognition and adaptation **/
+ struct NeighborInfo
+ {
+ int typeId;
+ int sampleId;
+ int classId;
+ double distance;
+ };
+ /**< @brief Structure to store information required for recognition and adaptation
+ * <p>
+ * TypeId: Specifies whether it is a singleton (defined by 1) or a cluster (defined by 0)
+ * SampleId: Specifies which singleton or cluster sample. The range of values depend on
+ * the number of clusters or singletons (>= 0)
+ * ClassId: Specifies the class id
+ * Distance: The distance between the test sample and singleton or
+ * the distance between the test sample and optimal deformation (cluster case)
+ * The range of values is >= 0
+ *
+ * DEFAULT: NULL
+ * Range: Depends on Individual fields
+ * </p>
+ */
+
+ /**Vector to store the distances from each class to test sample**/
+ vector <struct NeighborInfo> m_neighborInfoVec;
+ /**< @brief Neighbor Information Vector
+ * <p>
+ * This vector contains the distance information between the test samples and
+ * prototype data. It is a vector of structures NeighborInfo
+ * </p>
+ */
+
+ /** contains all the prototype data from load Model data **/
+ vector<ActiveDTWShapeModel> m_prototypeShapes;
+ /**< @brief Prototype Shapes
+ * <p>
+ * This is a vector of ActiveDTWShapeModels
+ * This populated via the loadModelData function
+ * </p>
+ */
+
+ /** Sorts dtw distances **/
+ static bool sortDist(const NeighborInfo& x, const NeighborInfo& y);
+ /**
+ * This method compares distances
+ *
+ * Semantics
+ *
+ * - Compare distances
+ *
+ * @param NeighborInfo(X)
+ * @param NeighborInfo(Y)
+ *
+ * @return TRUE: if X.distance lesser than Y.distance
+ * FALSE: if X.distance greater than Y.distance
+ * @exception none
+ */
+
+ vector<stringStringPair> m_preprocSequence;
+
+ intIntMap m_shapeIDNumPrototypesMap;
+ /**< @brief Map of shapeID and Number of Samples per shape
+ * <p>
+ *
+ * </p>
+ */
+
+ int m_prototypeSetModifyCount;
+ /**< @brief
+ * <p>
+ * Used to count number of modifications done to m_prototypeShapes.
+ * Write to MDT after m_prototypeModifyCntCFG such modifications or at Exit.
+ * </p>
+ */
+
+ int m_MDTUpdateFreq;
+ /**< @brief Update MDT after a specified number of modifications to m_prototypeSet
+ * <p>
+ * Specified in ActiveDTW.cfg
+ *
+ * </p>
+ */
+
+ shapeFeature m_cachedShapeFeature;
+ /**< @brief Store shapeFeature of the last inTraceGroup to Recognize
+ * Used during subsequent call to Adapt
+ * <p>
+ *
+ *
+ * </p>
+ */
+
+ float m_rejectThreshold;
+ /**< @brief Threshold on the confidence to reject a test sample
+ * <p>
+ *
+ * </p>
+ */
+
+ bool m_adaptivekNN;
+ /**< @brief Adaptive kNN method to compute confidence
+ * <p>
+ * If m_adaptivekNN = true, the adaptive kNN method is used for confidence computation
+ * false, NN or kNN method is used, based on the value of m_nearestNeighbors
+ * </p>
+ */
+
+ string m_currentVersion;
+
+ string m_MDTFileOpenMode;
+ /**< @brief File modes of the mdt file
+ * <p>
+ * If m_adaptivekNN = ascii, the mdt file is written in ascii mode
+ * binary, the mdt file will be written in binary mode
+ * Default: LTKPreprocDefaults::NN_MDT_OPEN_MODE_ASCII
+ * </p>
+ */
+
+ //dtw obj for computing the dtw distance between features
+ DynamicTimeWarping<LTKShapeFeaturePtr, float> m_dtwObj;
+ /**< @brief Dynamic Time Warping Object
+ * <p>
+ * This object aids in calculating the dtw distance between two LTKShapeFeaturePtrs
+ * and the distance is in float
+ * </p>
+ */
+
+ //store the recognitioresults
+ vector<LTKShapeRecoResult> m_vecRecoResult;
+ /**< @brief Vector of LTKShapeRecoResult
+ * <p>
+ * This vector is used to store the confidence values computed using computeConfidence
+ * </p>
+ */
+
+ //minimum numberOfSamples to form cluster
+
+
+ public:
+
+ /** @name Constructors and Destructor */
+
+ /**
+ * Constructor
+ */
+ ActiveDTWShapeRecognizer(const LTKControlInfo& controlInfo);
+
+ /**
+ * Destructor
+ */
+ ~ActiveDTWShapeRecognizer();
+
+ //@}
+
+ /**
+ * This method initializes the ActiveDTW shape recognizer
+ * <p>
+ * Semantics
+ * - Set the project name in ActiveDTWShapeRecognizer::headerInfo with the parameter passed.<br>
+ * m_headerInfo[PROJNAME] = strProjectName;
+ *
+ * - Initialize ActiveDTWShapeRecognizer::m_activedtwCfgFilePath <br>
+ * m_activedtwCfgFilePath = ActiveDTWShapeRecognizer::m_lipiRootPath + LTKMacros::PROJECTS_PATH_STRING +
+ * strProjectName + LTKMacros::PROFILE_PATH_STRING + strProfileName +
+ * LTKInc::SEPARATOR + LTKInc::ActiveDTW + LTKInc::CONFIGFILEEXT;
+ *
+ * - Initializes ActiveDTWShapeRecognizer::m_activedtwMDTFilePath <br>
+ * m_activedtwMDTFilePath = ActiveDTWShapeRecognizer::m_lipiRootPath + LTKMacros::PROJECTS_PATH_STRING +
+ * strProjectName + LTKMacros::PROFILE_PATH_STRING + strProfileName +
+ * LTKInc::SEPARATOR + LTKInc::ActiveDTW + LTKInc::DATFILEEXT;
+ *
+ * - Initializes ActiveDTWShapeRecognizer::m_projectTypeDynamic with the value returned from LTKShapeRecoUtil::isProjectDynamic
+ *
+ * - Initialize the preprocessor using LTKShapeRecoUtil::initializePreprocessor and assign
+ * default values for
+ * -# Normalised size
+ * -# Threshold size
+ * -# Aspect ratio
+ * -# Dot threshold
+ *
+ * - Initialize the recognizers instance variables with the values given in classifier config file.
+ *
+ * </p>
+ * @param strProjectName : string : Holds the name of the Project
+ * @param strProfileName : string : Holds the name of the Profile
+ *
+ * @return int : LTKInc::SUCCESS if initialization done successfully
+ * errorValues if initialization has some errors
+ *
+ * @exception LTKErrorList::ECONFIG_FILE_OPEN Could not open project.cfg
+ * @exception LTKErrorList::EINVALID_NUM_OF_SHAPES Negative value for number of shapes
+ * @exception LTKErrorList::ELOAD_PREPROC_DLL Could not load preprocessor DLL
+ * @exception LTKErrorList::EDLL_FUNC_ADDRESS_CREATE Could not map createPreprocInst
+ * @exception LTKErrorList::EDLL_FUNC_ADDRESS_DELETE Could not map destroyPreprocInst
+ */
+
+ /**
+ * This method calls the train method of the ActiveDTW classifier.
+ *
+ */
+ int train(const string& trainingInputFilePath,
+ const string& mdtHeaderFilePath,
+ const string &comment,const string &dataset,
+ const string &trainFileType=INK_FILE) ;
+
+ /**
+ * This method loads the Training Data of the ActiveDTW classifier.
+ * @param
+ * @return LTKInc::SUCCESS : if the model data was loaded successfully
+ * @exception
+ */
+ int loadModelData();
+
+ /**
+ * This method unloads all the training data
+ * @param none
+ * @return LTKInc::SUCCESS : if the model data was unloaded successfully
+ * @exception none
+ */
+ int unloadModelData();
+
+ /**
+ * This method sets the device context for the recognition
+ *
+ * @param deviceInfo The parameter to be set
+ * @return
+ * @exception
+ */
+ int setDeviceContext(const LTKCaptureDevice& deviceInfo);
+
+ /**
+ * Populates a vector of LTKShapeRecoResult consisting of top classes with their confidences.
+ *
+ * Semantics
+ *
+ * - Validate the input arguments
+ * - Extract the features from traceGroup
+ * - Compute the optimal deformation vectors for each class
+ * - If the dtwEuclidean filter is on:
+ * --Then for Clusters
+ * -- Calculate the euclidean distances between the test samples and the optimal deformations
+ * Accordingly populate the distFilter vector
+ * --Then for singletons
+ * --Calculate the euclidean distances between the test samples and the singletonVectors
+ * Accordingly populate the distFilter vector
+ * - Compute the dtw distances between the test sample and the optimal deformations and singletonVectors
+ -- If the dtwEuclidean filter is on then calculate the dtw distances only
+ to those deformations and singletonVectors recommended by the dtw euclidean filter
+ * - Populate the distIndexPairVector with distances and shapeID
+ * - Sort the distIndexPairVector based on the distances in ascending order
+ * - Compute the confidences of the classes appearing in distIndexPairVector, call computeConfidence()
+ * - Check if the first element of resultVector has confidence less than m_rejectThreshold, if so,
+ empty the resultVector (reject the sample), log and return.
+ * - If the confThreshold value was specified by the user (not equal to -1),
+ delete the entries from resultVector with confidence values less than confThreshold.
+ * - If the numChoices value was specified by the user (not equal to -1),
+ update the resultVector with top numChoices entries, delete the other values.
+ *
+ * @param traceGroup The co-ordinates of the shape which is to be recognized
+ * @param screenContext Contains information about the input field like whether it is boxed input
+ * or continuous writing
+ * @param subSetOfClasses A subset of the entire class space which is to be used for
+ * recognizing the input shape.
+ * @param confThreshold Classes with confidence below this threshold are not returned,
+ * valid range of confThreshold: (0,1)
+ * @param numOfChoices Number of top choices to be returned in the result structure
+ * @param resultVector The result of recognition
+ *
+ * @return SUCCESS: resultVector populated successfully
+ * FAILURE: return ErrorCode
+ * @exception none
+ */
+ int recognize(const LTKTraceGroup& traceGroup,
+ const LTKScreenContext& screenContext,
+ const vector<int>& subSetOfClasses,
+ float confThreshold,
+ int numChoices,
+ vector<LTKShapeRecoResult>& outResultVector);
+
+ /* Overloaded the above function to take vector<LTKShapeFeaturePtr> as
+ * input
+ */
+ int recognize(const vector<LTKShapeFeaturePtr>& shapeFeatureVec,
+ const vector<int>& inSubSetOfClasses,
+ float confThreshold,
+ int numChoices,
+ vector<LTKShapeRecoResult>& outResultVector);
+
+ /**
+ * In case of:
+ * 1. Singleton Vectors: This method converts them to traceGroups
+ * 2. Clusters: This method converts the cluster means to traceGroup
+ * Semantics
+ *
+ * - Check if shapeID is valid, if not return error code
+ * - Check if project is Dynamic, if not return ErrorCode
+ * - Update PrototypeSet
+ * - Update MDTFile
+ *
+ * @param shapeID : int : Holds shapeID
+ * @param numberOfTraceGroups : int : Maximum number of Trace Groups to populate
+ * @param outTraceGroups : vector<LTKTraceGroup> : TraceGroup
+ *
+ * @return SUCCESS: TraceGroup is populated successfully
+ * FAILURE: return ErrorCode
+ * @exception none
+ */
+ int getTraceGroups(int shapeID, int numberOfTraceGroups, vector<LTKTraceGroup> &outTraceGroups);
+
+
+
+ private:
+ /**
+ * This function is the train method using Clustering prototype selection technique.
+ *
+ *
+ * Semantics
+ *
+ * - Note the start time for time calculations.
+ *
+ * - Create an instance of the feature extractor using ActiveDTWShapeRecognizer::initializeFeatureExtractorInstance() method
+ *
+ * - Call train method depending on the inFileType
+ * - ActiveDTWShapeRecognizer::trainFromListFile() if inFileType = LTKMacros::INK_FILE
+ * - ActiveDTWShapeRecognizer::trainFromFeatureFile() if inFileType = LTKMacros ::FEATURE_FILE
+ *
+ * - Update the headerInfo with algorithm version and name using ActiveDTWShapeRecognizer::updateHeaderWithAlgoInfo() method
+ *
+ * - Calculate the checksum.
+ *
+ * - Note the finish time for time calculations.
+ *
+ *
+ * @param inputFilePath :string : Path of trainListFile / featureFile
+ * @param strModelDataHeaderInfoFile : string : Holds the Header information of Model Data File
+ * @param inFileType : string : Possible values ink / featureFile
+ *
+ * @return LTKInc::SUCCESS : if the training done successfully
+ * @return errorCode : if it contains some errors
+ */
+ int trainClustering(const string& trainingInputFilePath,
+ const string& mdtHeaderFilePath,
+ const string& trainFileType);
+
+
+ /**
+ * This method do the map between the module name and function names from the cfg file
+ *
+ * Semantics
+ *
+ * - Read the Preprocess Sequence from the nn.cfg
+ *
+ * - Split the sequence into tokens with delimiter LTKMacros::DELEMITER_SEQUENCE using LTKStringUtil::tokenizeString
+ *
+ * - Split each token with delimiter LTKMacrosDELEMITER_FUNC using LTKStringUtil::tokenizeString
+ * to get the Module name and Function name
+ *
+ * - Store the Module name and the Function name into a structure
+ *
+ *
+ * @param none
+ * @return LTKInc::SUCCESS : if functions are successfully mapped,
+ * @return errorCodes : if contains any errors
+ * @exception none
+ */
+ int mapPreprocFunctions();
+
+ /**
+ * This method will assign default values to the members
+ *
+ * Semantics
+ *
+ * - Assign Default values to all the data members
+ *
+ *
+ * @param none
+ *
+ * @return none
+ */
+ void assignDefaultValues();
+
+ /** Reads the ActiveDTW.cfg and initializes the instance variable of the classifier with the user defined
+ * values.
+ *
+ * Semantics
+ *
+ * - Open the activedtw.cfg using LTKConfigFileReader
+ *
+ * - Incase of file open failure (activedtw.cfg), default values of the classifier parameters are used.
+ *
+ * - The valid values of the classifier parameters are cached in to the class data members.
+ * LTKConfigFileReader::getConfigValue is used to get the value fora key defined in the config file
+ *
+ * - Exception is thrown if the user has specified an invalid valid for a parameter
+ *
+ *
+ * @param none
+ * @return SUCCESS : If the Config file read successfully
+ * @return errorCode : If it contains some errors
+ * @exception LTKErrorList::ECONFIG_FILE_RANGE The config file variable is not within the correct range
+ */
+ int readClassifierConfig();
+
+ /**
+ * This function serves as wrapper function to the Dtw distance computation function
+ * (for use by clustering prototype selection)
+ * @param train This is an input parameter and corresponds to the training character.
+ * @param test This is an input parameter and corresponds to the testing character.
+ */
+ int computeDTWDistance(const LTKShapeSample& inFirstShapeSampleFeatures,
+ const LTKShapeSample& inSecondShapeSampleFeatures,
+ float& outDTWDistance);
+
+ /**
+ * computes the dtw distance between two shape feature vectors
+ **/
+ int computeDTWDistance(const vector<LTKShapeFeaturePtr>& inFirstFeatureVector,
+ const vector<LTKShapeFeaturePtr>& inSecondFeatureVector,
+ float& outDTWDistance);
+ /**
+ * This function serves as wrapper function to the Dtw distance computation function
+ * (for use by recognize function)
+ * @param train This is an input parameter and corresponds to the training character.
+ * @param test This is an input parameter and corresponds to the testing character.
+ */
+
+
+ /**
+ * Computes the euclidean distance between two shape Features
+ **/
+ int computeEuclideanDistance(const shapeFeature& inFirstFeature,
+ const shapeFeature& inSecondFeature,
+ float& outEuclideanDistance);
+ /**
+ * This function is used to compute the Euclidean distance between two shape Features
+ * (for use by recognize when dtwEuclidean filter is on)
+ * @param train This is an input parameter and corresponds to the training character.
+ * @param test This is an input parameter and corresponds to the testing character.
+ */
+
+
+
+
+
+ /**
+ * This method creates a custom feature extractor instance and stores it's address in
+ * ActiveDTWShapeRecognizer::m_ltkFE. The local distance function pointer is also initialized.
+ *
+ * Semantics
+ *
+ *
+ * - Intialize the ActiveDTWShapeRecognizer::m_ptrFeatureExtractor with address of the feature extractor instance created
+ * using LTKShapeFeatureExtractorFactory::createFeatureExtractor
+ *
+ * - Cache the address of LTKShapeFeatureExtractor::getLocalDistance() in an instance variable
+ *
+ * @param none
+ *
+ * @return 0 on LTKInc::SUCCESS and 1 on LTKInc::FAILURE
+ *
+ * @exception none
+ */
+ int initializeFeatureExtractorInstance(const LTKControlInfo& controlInfo);
+
+ /**
+ * This method trains the classifier from the train list file whose path is passed as paramater.
+ *
+ * Semantics
+ *
+ * - Open the trainListFile for reading.
+ *
+ * - Open the mdt file for writing.
+ *
+ * - Write header information to the mdt file
+ * - ActiveDTWShapeRecognizer::m_numShapes
+ * - ActiveDTWShapeRecognizer::m_traceDimension
+ * - ActiveDTWShapeRecognizer::m_flexibilityIndex
+ *
+ * - Get a valid line from the train list file
+ * - Skip commented lines
+ * - Skip lines where number_of_tokens != 2
+ * - Throw error LTKErrorList::EINITSHAPE_NONZERO, if the first shape in the list file is not zero
+ * - Throw error LTKErrorList::EINVALID_ORDER_LISTFILE if the shapes are not in sequential order
+ *
+ * - For every valid line get the ShapeSample from the ink file using ActiveDTWShapeRecognizer::getShapeSampleFromInkFile
+ * - Read ink from UNIPEN ink file
+ * - Skip if the trace group is empty
+ * - Pre process the trace group read from the ink file
+ * - Extract features
+ *
+ * - Push all the ShapeSamples corresponding to a shape into a vector of ShapeSample ShapeSamplesVec.
+ *
+ * - When all the ShapeSamples corresponding to a Shape have been collected, cluster them using ActiveDTWShapeRecognizer::performClustering
+ *
+ * - performClustering results in vector of clustered ShapeSamples.
+ *
+ * - computeCovarianceMatrix of clusters
+ *
+ * - computeEigenVectorsForLargeDimension for the covariance matrices of the clusters
+ *
+ * - construct shape models using cluster models and singletons
+ *
+ * - Append these clustered vector<ActiveDTWShapeModel> to the mdt file.
+ *
+ *
+ * @param listFilePath : string : Holds the path for train list file
+ * @param trainSet : ShapeSampleVector: Holds the ShapeSample for all shapes, used for LVQ only
+ *
+ * @return none
+ *
+ * @exception LTKErrorList::EFILE_OPEN_ERROR : Error in Opening a file (may be mdt file or list file)
+ * @exception LTKErrorList::EINVALID_NUM_OF_SHAPES : Invalid value for number of shapes
+ * @exception LTKErrorList::EINVALID_ORDER_LISTFILE: Invalid order of shapeId in List file
+ * @exception LTKErrorList::EINITSHAPE_NONZERO : Initial shapeId must not be zero
+ * @exception LTKErrorList::EEMPTY_EIGENVECTORS : Number of eigen vectors must be a positive number
+ * @exception LTKErrorList::EINVALID_NUM_OF_EIGENVECTORS : Number of eigen vector must be a positive number
+ */
+
+ int trainFromListFile(const string& listFilePath);
+
+ /**
+ * This method will get the ShapeSample by giving the ink file path as input
+ *
+ * Semantics
+ *
+ * - Call the LTKShapeRecoUtil::readInkFromFile() method (Utility Method) to read the ink file
+ * By reading this file, an inTraceGroup was generated
+ *
+ * - Preprocess the inTraceGroup and get the preprocessed trace group
+ * LTKTraceGroup preprocessedTraceGroup
+ *
+ * - Extract features from the preprocessed trace group to get the ShapeSamples.
+ *
+ *
+ * @param path : string : The path for Ink file
+ * @param ShapeSample : ShapeSample : The ShapeSample generated after feature extraction
+ *
+ * @return SUCCESS : If the ShapeSample was got successfully
+ * @return FAILURE : Empty traces group detected for current shape
+ *
+ * @exception LTKErrorList::EINKFILE_EMPTY : Ink file is empty
+ * @exception LTKErrorList::EINK_FILE_OPEN : Unable to open unipen ink file
+ * @exception LTKErrorList::EINKFILE_CORRUPTED : Incorrect or corrupted unipen ink file.
+ * @exception LTKErrorList::EEMPTY_TRACE : Number of points in the trace is zero
+ * @exception LTKErrorList::EEMPTY_TRACE_GROUP : Number of traces in the trace group is zero
+ */
+ int getShapeFeatureFromInkFile(const string& inkFilePath,
+ vector<LTKShapeFeaturePtr>& shapeFeatureVec);
+
+
+ /**
+ * This method will do Custering for the given ShapeSamples
+ *
+ * Semantics
+ *
+ * - If the ActiveDTWShapeRecognizer::m_prototypeReductionFactor is -1 means Automatic clustering could be done
+ *
+ * - If the ActiveDTWShapeRecognizer::m_prototypeReductionFactor is 0 means No clustering was needed
+ *
+ * - Otherwise clustering is needed based on the value of ActiveDTWShapeRecognizer::m_prototypeReductionFactor
+ *
+ *
+ *
+ * @param ShapeSamplesVec : ShapeSampleVector : Holds all the ShapeSample for a single class
+ * @param resultVector : int2DVector : Vector of indices of samples belonging to a cluster
+ *
+ * @return SUCCESS ; On successfully performing clustering
+ * @return ErrorCode ; On some error
+ * @exception none
+ */
+ int performClustering(const vector<LTKShapeSample>& shapeSamplesVec,
+ int2DVector& outputVector);
+
+ /**
+ * This method computes the covariance matrix and the mean for a given feature matrix
+ *
+ * Semantics
+ *
+ * - Computes the mean of the feature matrix
+ *
+ * - Computes the mean corrected data
+ *
+ * - Computes the covariance matrix
+ *
+ *
+ *
+ * @param featureMatrix : double2DVector : Holds all the features of a cluster
+ * @param covarianceMatrix : double2DVector : covariance matrix of the cluster
+ * @param meanFeature : doubleVector : mean feature of the cluster
+ *
+ * @return SUCCESS ; On successfully computing the covariance matrix
+ * @return ErrorCode ; On some error
+ * @exception LTKErrorList:: EEMPTY_FEATUREMATRIX, Feature matrix is empty
+ */
+ int computeCovarianceMatrix(double2DVector& featureMatrix,
+ double2DVector& covarianceMatrix,doubleVector& meanFeature);
+
+ /**
+ * compute the eigen vectors
+ * for a covariance Matrix
+ * @inparam covarianceMatrix,rank,nrot --> no of rotations
+ * @outparam eigenValueVec, eigenVectorMatrix
+ **/
+ int computeEigenVectors(double2DVector &covarianceMatrix,const int rank,
+ doubleVector &eigenValueVec, double2DVector &eigenVectorMatrix, int& nrot);
+
+
+ /**
+ * This method will Update the Header information for the MDT file
+ *
+ * Semantics
+ *
+ * - Copy the version number to a string
+ *
+ * - Update the version info and algoName to ActiveDTWShapeRecognizer::m_headerInfo, which specifies the
+ * header information for MDT file
+ *
+ *
+ * @param none
+ *
+ * @return none
+
+ * @exception none
+ */
+ void updateHeaderWithAlgoInfo();
+
+ int preprocess (const LTKTraceGroup& inTraceGroup, LTKTraceGroup& outPreprocessedTraceGroup);
+
+
+ /**
+ * This append the shape model data to the mdt file
+ *
+ * Semantics
+ *
+ * - Append cluster models
+ *
+ * - Append singleton vectors
+ *
+ *
+ *
+ * @param shapeModel : ActiveDTWShapeModel : Holds clusters and singletons of a shape
+ * @param mdtFileHandle : ofstream : file handle for the mdt file
+ *
+ * @return SUCCESS ; On successfully appending the data to mdt file
+ * @return ErrorCode:
+ * @exception LTKErrorList:: EINVALID_FILE_HANDLE, unable to open mdt file
+ */
+ int appendShapeModelToMDTFile(const ActiveDTWShapeModel& shapeModel,ofstream& mdtFileHandle);
+
+ /**
+ * find optimal deformation parameters using bound constrained optimization
+ * here any third part library can be called
+ * we will solve the equation
+ * Min f(x)
+ * Subject to: lb <= x <= ub
+ * where lb -- lower bound ub --- upper bound
+ **/
+
+ /**
+ * This solves the optimization problem and finds the deformation parameters
+ * It constructs the optimal deformation, the sample in the cluster closest to the test sample
+ * Semantics
+ *
+ * - Solve the optimization problem
+ * Min f(x)
+ * Subject to: lb <= x <= ub
+ * where lb -- lower bound ub --- upper bound
+ *
+ *
+ *
+ * @param eigenValues : doubleVector : eigen values of a cluster
+ * @param eigenVector : double2DVector : eigen vectorsof a cluster
+ * @param clusterMean : doubleVector : mean of the cluster
+ * @param testSample : doubleVector : test sample
+ * @param deformationParameters : doubleVector : parameters required to construct the optimal deformation
+ *
+ * @return SUCCESS ; On successfully appending the data to mdt file
+ * @return ErrorCode:
+ * @exception LTKErrorList:: EEMPTY_EIGENVALUES, eigen values are empty
+ * @exception LTKErrorList:: EEMPTY_EIGENVECTORS, eigen vectors are empty
+ * @exception LTKErrorList:: EEMPTY_CLUSTERMEAN, cluster mean is empty
+ * @exception LTKErrorList:: ENUM_EIGVALUES_NOTEQUALTO_NUM_EIGVECTORS, number of eigen value is not equal to the number of eigen vectors
+ * @exception LTKErrorList:: EEMPTY_EIGENVECTORS, eigen vectors are empty
+ */
+ int findOptimalDeformation(doubleVector& deformationParameters,doubleVector& eigenValues, double2DVector& eigenVector,
+ doubleVector& clusterMean, doubleVector& testSample);
+
+ static void getDistance(const LTKShapeFeaturePtr& f1,const LTKShapeFeaturePtr& f2, float& distance);
+
+
+ /**
+ * This method computes the confidences of test sample belonging to various classes
+ *
+ * Semantics
+ *
+ * - Compute the confidence based on the values of m_nearestNeighbors and m_adaptiveKNN
+ * - Populate the resultVector
+ * - Sort the resultVector
+ * -
+ *
+ * @param distIndexPairVector : vector<struct NeighborInfo>: Holds the samples, classIDs and distances to the test sample
+ * @param resultVector : vector<LTKShapeRecoResult> : Holds the classIDs and the respective confidences
+ *
+ * @return SUCCESS: resultVector populated
+ * FAILURE: return ErrorCode
+ * @exception none
+ */
+ int computeConfidence();
+
+ /**
+ * The comparison function object of STL's sort() method, overloaded for class LTKShapeRecoResult, used to sort the vector of LTKShapeRecoResult based on the member variable confidence
+ *
+ * Semantics
+ *
+ * - Check if the first object's confidence value is greater than the second object's confidence value
+ * - Return true or false
+ * -
+ *
+ * @param x : LTKShapeRecoResult : First object for comparison
+ * @param y : LTKShapeRecoResult : Second object for comparison
+ *
+ * @return true: If x.confidence > y.confidence
+ * false: If x.confidence <= y.confidence
+ * @exception none
+ */
+ static bool sortResultByConfidence(const LTKShapeRecoResult& x, const LTKShapeRecoResult& y);
+
+ static bool compareMap( const map<int, int>::value_type& lhs, const map<int, int>::value_type& rhs );
+
+ int mapFeatureExtractor();
+
+ int deleteFeatureExtractorInstance();
+ /**
+ * This method extracts shape features from given TraceGroup
+ *
+ * Semantics
+ *
+ * - PreProcess tracegroup
+ * - Extract Features
+ *
+ * @param inTraceGroup : LTKTraceGroup : Holds TraceGroup of sample
+ *
+ * @return SUCCESS: if shapeFeatures is populated successfully
+ * FAILURE: return ErrorCode
+ * @exception none
+ */
+
+ int extractFeatVecFromTraceGroup(const LTKTraceGroup& traceGroup,
+ vector<LTKShapeFeaturePtr>& featureVec);
+
+
+ /** This method is used to initialize the PreProcessor
+ *
+ * Semantics
+ *
+ * - Load the preprocessor DLL using LTKLoadDLL().
+ *
+ * - Get the proc address for creating and deleting the preprocessor instance.
+ *
+ * - Create preprocessor instance.
+ *
+ * - Start the logging for the preprocessor module.
+ *
+ * @param preprocDLLPath : string : Holds the Path of the Preprocessor DLL,
+ * @param errorStatus : int : Holds SUCCESS or Error Values, if occurs
+ * @return preprocessor instance
+ *
+ * @exception ELOAD_PREPROC_DLL Could not load preprocessor DLL
+ * @exception EDLL_FUNC_ADDRESS_CREATE Could not map createPreprocInst
+ * @exception EDLL_FUNC_ADDRESS_DELETE Could not map destroyPreprocInst
+ */
+ int initializePreprocessor(const LTKControlInfo& controlInfo,
+ LTKPreprocessorInterface** preprocInstance);
+
+ /** This method is used to deletes the PreProcessor instance
+ *
+ * Semantics
+ *
+ * - Call deleteLTKPreprocInst from the preproc.dll.
+ *
+ * - Unload the preprocessor DLL.
+ *
+ * @param ptrPreprocInstance : Holds the pointer to the LTKPreprocessorInterface
+ * @return none
+ * @exception none
+ */
+
+ int deletePreprocessor();
+
+ /** This method is used to Unloads the preprocessor DLL.
+ *
+ * Semantics
+ *
+ * - If m_libHandler != NULL, unload the DLL
+ * LTKUnloadDLL(m_libHandler);
+ * m_libHandler = NULL;
+ *
+ * @param none
+ * @return none
+ * @exception none
+ */
+ int unloadPreprocessorDLL();
+
+ /**< @brief Pointer to LTKOSUtil interface
+ * <p>
+ *
+ * </p>
+ */
+ LTKOSUtil* m_OSUtilPtr;
+
+ int validatePreprocParameters(stringStringMap& headerSequence);
+
+ /**
+ * Computes the eigen values and eigen vectors of the larger covariance matrix using the
+ * a smaller covariance matrix
+ *
+ * Semantics
+ *
+ * - Compute the smaller covariance matrix, using meanCorrectedData(Transpose)*meanCorrectedData(Transpose)
+ *
+ * - Compute the eigen vectors of the smaller covariance matrix
+ *
+ * - Determine the number of eigen vectors, depending on the eigen energy to be retained
+ *
+ * - Compute the eigen vectors of the larger covariance matrix
+ *
+ * - Normalizing the eigen vectors
+ *
+ *
+ *
+ * @param meanCorrectedData : double2DVector : mean corrected data
+ * @param covarianceMatrix : double2DVector : covariance matrix of the corresponding mean corrected data
+ * @param eigenValues : doubleVector : output selected eigen values
+ * @param eigenVector : double2DVectorr : output selected eigen vectors
+ *
+ * @return SUCCESS ; On successfully computing eigen values and eigen vectors
+ * @return ErrorCode:
+ * @exception LTKErrorList:: EEMPTY_MEANCORRECTEDDATA, empty mean corrected data
+ * @exception LTKErrorList:: EEMPTY_COVARIANCEMATRIX, empty covariance matrix
+ */
+ int computeEigenVectorsForLargeDimension(double2DVector& meanCorrectedData,double2DVector& covarianceMatrix,
+ double2DVector& eigenVector,doubleVector& eigenValues);
+
+ /**
+ * This converts the double vector to a feature vector
+ * It constructs the optimal deformation, the sample in the cluster closest to the test sample
+ *
+ *
+ * @param featureVec : doubleVector : input double feature vector
+ * @param shapeFeatureVec : vector<LTkShapeFeaturePtr> : output feature vector
+ *
+ * @return SUCCESS ; On successfully conversion
+ * @return ErrorCode:
+ * @exception LTKErrorList:: EINVALID_INPUT_FORMAT
+ */
+ int convertDoubleToFeatureVector(vector<LTKShapeFeaturePtr>& shapeFeatureVec,doubleVector& featureVec);
+
+
+};
+
+#endif
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.cfg b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.cfg
new file mode 100644
index 00000000..142470cf
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.cfg
@@ -0,0 +1,422 @@
+#------------------------------------------------------------------------------
+# activedtw.cfg
+#
+# Configuration file for Active-DTW Classification Method for
+# Lipi Toolkit 4.0.0
+#------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+# The standard format for the configuration entries is the name of the
+# configuration parameter seperated by an equal to sign and then the value of
+# the configuration parameter. For example:
+# ConfigurationEntryName = value
+#
+# Lines starting with a # are commnet lines
+#
+# A cfg entry is strictly a key value pair and leaving the key without the
+# value or specification of a value out of the range is not permitted
+#
+# If a cfg entry is not specified at all, then default values are used by the
+# recognizer
+#------------------------------------------------------------------------------
+
+#-------------------------------
+# PREPROCESSING
+#-------------------------------
+
+#-------------------------------------------------------------------------------
+# ResampTraceDimension
+#
+# Description: The number of target points for resampling. In other words,
+# each character will be resampled to this number of points. In case of
+# multistroke characters, this number of points will be distributed between
+# the strokes in proportion to their lengths in proportion to their initial
+# number of points.
+#
+# Valid values: Any integer > 0
+# Units: Points
+# Default value: 60
+# Typical value: Average number of points per character in the training data set.
+#-------------------------------------------------------------------------------
+ResampTraceDimension = 60
+
+
+
+#-------------------------------------------------------------------------------
+# ResampPointAllocation
+#
+# Description: Method to be used for point allocation among different strokes
+# during resampling. Two schemes have been implemented lengthbased and point
+# based. In lengthbased allocation scheme, the number of points allocated to
+# each stroke is proportional to the length of the stroke. Length of a stroke
+# is calculated as the sum of the distances between each point in the stroke.
+# In the pointbased allocation scheme, the target stroke point allocation is
+# proportional to the number of points in the initial stroke.
+#
+# Valid value: [lengthbased | pointbased]
+# Default value: lengthbased
+#-------------------------------------------------------------------------------
+ResampPointAllocation = lengthbased
+
+
+#-------------------------------------------------------------------------------
+# NormDotSizeThreshold
+#
+# Description: This threshold is used to determine whether a character is a dot.
+# It is expressed in real length terms (inches) and converted internally to
+# points using knowledge of the device�s spatial resolution. If the width
+# and height are both less than this threshold, then all the points are replaced
+# with the center of the of the normalized character, basically to represent it
+# as a dot
+#
+# Valid values: Any real number > 0
+# Units: inches
+# Default value: 0.01
+# Typical value: < 0.1
+#-------------------------------------------------------------------------------
+NormDotSizeThreshold = 0.01
+
+#-------------------------------------------------------------------------------
+# NormLineWidthThreshold
+#
+# Description: This threshold is used to detect whether the character is a
+# vertical or horizontal line. If only the height is less than this threshold
+# then the character is detected as a horizontal line and if only the width is
+# less than this threshold then the character is detected as a vertical line.
+# Assuming the height is along the y-dimension and width is along the x-
+# dimension, during normalization of a horizontal line only the x-coordinates
+# are scaled and the y-coordinates are translated to the center of the character,
+# with out scaling. Similarly for the vertical line only the y-coordinates are
+# normalized and the x-coordinates are translated to the center with out scaling
+#
+# Valid values: Any real number > 0
+# Units: inches
+# Default value: 0.01
+# Typical value: < 0.1
+#-------------------------------------------------------------------------------
+NormLineWidthThreshold = 0.01
+
+#-------------------------------------------------------------------------------
+# NormPreserveAspectRatio
+#
+# Description: This parameter is used to indicate whether the aspect ratio
+# has to be preserved during normalization. The aspect ratio is the calculated
+# as maximum of (height/width , width/height). The aspect ratio is preserved only
+# if the calculated aspect ratio is greater than the threshold value specified
+# through NormPreserveAspectRatioThreshold and this configuration variable is
+# set to true. If this configuration variable is set to false the aspect ratio
+# is not preserved during normalization.
+#
+# Valid value: [true | false]
+# Default value: true
+#-------------------------------------------------------------------------------
+NormPreserveAspectRatio = true
+
+
+#-------------------------------------------------------------------------------
+# NormPreserveAspectRatioThreshold
+#
+# Description: Aspect ratio is preserved during normalization if the computed
+# aspect ratio (max(height/width, width/height)) is greater than this threshold
+# and the configuration value NormPreserveAspectRatio is set to true. During
+# aspect ratio preserving normalization, the larger of the two dimensions is
+# normalized to the standard size and the other dimension is normalized
+# proportional to the initial height and width ratio, so that the initial
+# aspect ratio is maintained.
+#
+# Valid values: Any real number >= 1
+# Default value: 3
+# Typical value: >= 1.5
+#-------------------------------------------------------------------------------
+NormPreserveAspectRatioThreshold = 3
+
+#-------------------------------------------------------------------------------
+# NormPreserveRelativeYPosition
+#
+# Description: The relative Y position is the mean of the y-coordinates in the
+# input character. During normalization if this parameter is set to true, each
+# y-coordinate of the character point is translated by the initial y-mean value,
+# so that the mean of the y-coordinates remains the same before and after
+# normalization. This is typically used in the word recognition context where
+# each stroke of the character has to be normalized separately and the relative
+# position of the strokes should be maintained even after normalization.
+#
+# Valid value: [true | false]
+# Default value: false
+#-------------------------------------------------------------------------------
+NormPreserveRelativeYPosition = false
+
+#-------------------------------------------------------------------------------
+# SmoothWindowSize
+#
+# Description: The configuration value specifies the length of the moving
+# average filter (size of the window) for smoothing the character image.
+# If this value is set to N, then each point in the input character is replaced
+# by the average of value of this point, (N-1)/2 points on the right and (N-1)/2
+# on the left of this point.
+#
+# Valid value: Any integer > 0
+# Units: Points
+# Typical value: 5
+# Default value: 3
+#-------------------------------------------------------------------------------
+SmoothWindowSize = 3
+
+#-------------------------------------------------------------------------------
+# NNPreprocSequence
+#
+# Description: This variable is used to specify the sequence of preprocessing
+# operations to be carried out on the input character sample before extracting
+# the features. A valid preprocessing sequence can consist of combination of one
+# or more of the functions selected from the valid values set mentioned below.
+# The CommonPreProc prefix is used specify the default preprocessing module of
+# LipiTk. The user can add his own preprocessing functions in other modules and
+# specify them in the preprocessing sequence.
+#
+# Valid values: Any sequence formed from the following set
+# CommonPreProc::normalizeSize;
+# CommonPreProc::removeDuplicatePoints;
+# CommonPreProc::smoothenTraceGroup;
+# CommonPreProc::dehookTraces;
+# CommonPreProc::normalizeOrientation;
+# CommonPreProc::resampleTraceGroup;
+# Default value: {CommonPreProc::normalizeSize,CommonPreProc::resampleTraceGroup,CommonPreProc::normalizeSize}
+#-------------------------------------------------------------------------------
+PreprocSequence={CommonPreProc::normalizeSize,CommonPreProc::resampleTraceGroup,CommonPreProc::normalizeSize}
+
+#---------------------------------------
+# TRAINING
+#---------------------------------------
+
+#-------------------------------------------------------------------------------
+# NNTrainPrototypeSelectionMethod
+#
+# Description: This is used to specify the prototype selection method to be used
+# while training the shape recognizer. When set to hier-clustering, the
+# prototypes are selected using hierarchical clustering method.
+#
+# Valid value: [hier-clustering]
+# Default value: hier-clustering
+#-------------------------------------------------------------------------------
+NNTrainPrototypeSelectionMethod=hier-clustering
+
+
+#-------------------------------------------------------------------------------
+# NNTrainPrototypeReductionFactorPerClass
+#
+# Description: This config parameter is used only when the prototype selection
+# is clustering. This config parameter is used to specify the amount of the
+# initial prototypes to be excluded during prototype selection.
+# Set it to automatic if the number of clusters is to be determined
+# automatically. Set it to none if no prototype selection is required. If the
+# value of this parameter is set to a number between 1-100, say 25, then 75%
+# (i.e 100-25) of the initial training data are retained as prototypes.
+# This parameter can be specified only if the NNTrainNumPrototypesPerClass
+# is not specified.
+#
+# Valid value: [automatic | none | any real number from 0-100]
+# Default value: automatic
+#-------------------------------------------------------------------------------
+NNTrainPrototypeReductionFactorPerClass = 25
+
+#-------------------------------------------------------------------------------
+# NNTrainNumPrototypesPerClass
+#
+# Description: This config parameter is used only when the prototype selection
+# is clustering. This is used to specify the number of prototypes to be selected
+# from the training data. This parameter can be specified only if
+# PrototypeReductionFactor is not specified. This config entry is commented as
+# only one of NNTrainPrototypeReductionFactorPerClass or
+# NNTrainNumPrototypesPerClass can be active in a valid cfg file.
+#
+# Valid value: [automatic | none | any integer from 1-N]
+# (N is the number of samples # per class)
+# Default value: automatic
+#-------------------------------------------------------------------------------
+#NNTrainNumPrototypesPerClass=100
+
+# Note: Only one of either PrototypeReductionFactor or NumClusters can be
+# enabled at any particular instance
+
+#-------------------------------------------------------------------------------
+# ActiveDTWRetainPercentEigenEnergy
+#
+# Description: This config parameter is used to specify the amount of Eigen
+# energy to be included to select the number of eigen vectors
+#
+# Valid value: [any integer from 0-100]
+#
+# Default value: 90
+#-------------------------------------------------------------------------------
+ActiveDTWRetainPercentEigenEnergy= 90
+
+#-------------------------------------------------------------------------------
+# ActiveDTWMinClusterSize
+#
+# Description: This config parameter is used to specify the minimum number
+# of samples required to form a cluster
+#
+# Valid value: [any postive integer > 1]
+#
+# Default value: 2
+#-------------------------------------------------------------------------------
+ActiveDTWMinClusterSize = 2
+
+#-----------------------------------------
+# FEATURE EXTRACTION
+#-----------------------------------------
+
+#-------------------------------------------------------------------------------
+# FeatureExtractor
+#
+# Description: The configuration value is used to specify the feature extraction
+# module to be used for feature extraction. The point float feature extraction
+# module extracts the x,y,cosine and sine angle features at every point of the
+# character.
+#
+# Valid value: [PointFloatShapeFeatureExtractor]
+# Default value: PointFloatShapeFeatureExtractor
+#-------------------------------------------------------------------------------
+FeatureExtractor=PointFloatShapeFeatureExtractor
+
+#-----------------------------------------
+# RECOGNITION
+#-----------------------------------------
+
+#-------------------------------------------------------------------------------
+# NNRecoDTWEuFilterOutputSize
+#
+# Description: This config parameter is used to set the proportion of nearest
+# cluster or singleton vectors from a class (filtered based on euclidean distance)
+# to be considered for calculating deformations or dtw distance. Set to 100 if
+# all clusters or singletons are to be considered for calculating dtw distance.
+# This is mainly used to increase the speed of recognition.
+#
+# Valid value: [all | any number from 1-100]
+# Default Value: all
+#-------------------------------------------------------------------------------
+NNRecoDTWEuFilterOutputSize = 30
+
+#-------------------------------------------------------------------------------
+# ActiveDTWEigenSpreadValue
+#
+# Description: This value is used to configure the range of values the
+# bound constraint optimization algorithm will take to calculate the
+# optimal deformation sample
+# Valid value: [greater than 0| default = 16]
+#-------------------------------------------------------------------------------
+ActiveDTWEigenSpreadValue = 16
+
+#-------------------------------------------------------------------------------
+# ActiveDTWUseSingleton
+#
+# Description: This value is used to configure whether singleton vectors
+# from classes will be taken into consideration during the recognition
+# process
+# Valid value: [true | false]
+# Default Value: true
+#-------------------------------------------------------------------------------
+ActiveDTWUseSingleton = true
+
+#-------------------------------------------------------------------------------
+# NNRecoRejectThreshold
+#
+# Description: Threshold to reject the test sample. If the confidence obtained
+# for the recognition of test sample is less than this threshold then the test
+# sample is rejected.
+#
+# Valid value: Any real number from 0-1
+# Default value: 0.001
+#-------------------------------------------------------------------------------
+NNRecoRejectThreshold = 0.001
+
+#-------------------------------------------------------------------------------
+# NNRecoNumNearestNeighbors
+#
+# Description: Number of nearest neighbors to be considered during recognition
+# and computation of confidence. If the value is set to 1, nearest neighbor
+# classifier is used, otherwise k-nearest neighbor or Adaptive k-nearest
+# neighbor classifiers are used. By default, nearest neighbor classifier is used.
+#
+# Valid value: Any integer >= 1
+# Default value: 1
+#-------------------------------------------------------------------------------
+NNRecoNumNearestNeighbors = 1
+
+#-------------------------------------------------------------------------------
+# NNRecoUseAdaptiveKNN
+#
+# Description: This parameter is used to specify whether Adaptive k-nearest
+# neighbor recognizer (A-kNN) is to be used. If set to true, A-kNN recognizer is
+# used, otherwise kNN recognizer is used. The A-kNN recognizer automatically
+# determines the number of nearest neighbors to be considered for recognition in
+# each class. If NNRecoNumNearestNeighbors is set to 1, this parameter is
+# automatically set to false and the manually set value will not be considered.
+#
+# Valid value: [true | false]
+# Default value: false
+#-------------------------------------------------------------------------------
+NNRecoUseAdaptiveKNN = false
+
+#--------------------------------------------
+# ADAPTATION
+#--------------------------------------------
+
+#-------------------------------------------------------------------------------
+# ActiveDTWMaxClusterSize
+#
+# Description: This config parameter is used to specify the maximum number
+# of samples a cluster is permitted to have
+#
+# Valid value: [any postive integer > 1 And Greater than ActiveDTWMinClusterSize]
+#
+# Default value: 2
+#-------------------------------------------------------------------------------
+ActiveDTWMaxClusterSize = 30
+
+#--------------------------------------------
+# COMMON FOR TRAINING AND RECOGNITION
+#--------------------------------------------
+
+
+#-------------------------------------------------------------------------------
+# NNDTWBandingRadius
+#
+# Description: This configuration parameter specifies the banding radius
+# to be used for DTW computation. This is used to speed up the computation
+# process. If this value is zero no banding is done. The value is specified as
+# fraction of ResampTraceDimension to be used while computing the DTW
+# distance.
+#
+# Valid values: Any real number > 0 and <= 1
+# Default Value: 0.33
+#-------------------------------------------------------------------------------
+NNDTWBandingRadius=0.33
+
+#-------------------------------------------------------------------------------
+#ActiveDTWMDTFileUpdateFreq
+#
+# Description: This configuration parameter specifies the number of iterations after
+# which MDT file is to be updated.
+# Every call to addClass or deleteClass will add/delete the given class. These
+# in-memory changes will be reflected in nn.mdt only after the specified
+# number of such iterations and on application exit.
+#
+# Valid values: Any integer > 0
+# Default value: 5
+# Typical value: 5
+#-------------------------------------------------------------------------------
+ActiveDTWMDTFileUpdateFreq = 100
+
+#-------------------------------------------------------------------------------
+# NNMDTFileOpenMode
+#
+# Description: This configuration parameter specifies the mode for
+# opening the mdt file.
+#
+# Valid values: ascii, binary
+# Default Value: ascii
+#-------------------------------------------------------------------------------
+
+NNMDTFileOpenMode=ascii
+
diff --git a/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.pro b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.pro
new file mode 100644
index 00000000..255c5512
--- /dev/null
+++ b/src/plugins/lipi-toolkit/3rdparty/lipi-toolkit/src/reco/shaperec/activedtw/activedtw.pro
@@ -0,0 +1,27 @@
+LIPILIBS = shaperecommon ltkcommon ltkutil featureextractorcommon
+include(../../../lipiplugin.pri)
+
+INCLUDEPATH += \
+ ../../../util/lib \
+ ../featureextractor/common \
+ ../common \
+
+HEADERS += \
+ ActiveDTW.h \
+ ActiveDTWAdapt.h \
+ ActiveDTWClusterModel.h \
+ ActiveDTWShapeModel.h \
+ ActiveDTWShapeRecognizer.h \
+
+SOURCES += \
+ ActiveDTW.cpp \
+ ActiveDTWShapeRecognizer.cpp\
+ ActiveDTWClusterModel.cpp \
+ ActiveDTWShapeModel.cpp \
+ ActiveDTWAdapt.cpp \
+
+win32 {
+ DEFINES += ACTIVEDTW_EXPORTS
+ LIBS += Advapi32.lib
+ #DEF_FILE = ActiveDTW.def
+}