/**********************************************************************************
* AUTHOR		: Deepu V.
* DATE			: 22-AUG-2005
* NAME			: updateRecognitionResults
* DESCRIPTION	: This function tries to update the
*               : shape recognition choices with new shape recognition results
* ARGUMENTS		: results - new results for updating the results
* RETURNS		:
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of
*************************************************************************************/
int BoxedFieldRecognizer::updateRecognitionResults(const vector<LTKShapeRecoResult>& results, LTKRecognitionContext& rc)
{
	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
	    <<"Entering: BoxedFieldRecognizer::updateRecognitionResults"
	    <<endl;

	multimap< float, pair<int,int>, greater<float> >backTrace;
	                   //A multi map is used for finding best N paths
	multimap< float, pair<int,int>, greater<float> >::iterator iter, iterend;
	                   //Iterator for accessing elements of the map
	pair<int,int> combination;
	                   //Temporary variable that keeps a (int,int) pair
	int wordResultIndex, shapeResultIndex;
	                   //loop index variables
	float wordConfidence, shapeConfidence;
	                   //word level and shape level confidences
	unsigned short newSymbol;
	                   //temporary storage for shape recognizer id
	float newConf;     //temporary storage for shape recognizer confidence

	vector<LTKWordRecoResult> newResultVector;
	                   //new results after finding the best N paths

	int numWordRecoResults = rc.getNumResults();
	                   //number of word recognition results requested
	int numShapeRecoResults = results.size();
	                   //number of choices from the shape recognizer
        vector<unsigned short>initVec;
                           //for initializing the trellis



	//If there is no decoded results (First shape recognition in the word)
    if(m_decodedResults.empty())
	{
		//Initializing the results vector
		m_decodedResults.assign(numShapeRecoResults,LTKWordRecoResult());

		//iterating through different word recognition choices
 		for(wordResultIndex = 0; (wordResultIndex<numShapeRecoResults); ++wordResultIndex)
		{
				//Retrieving the shape recognition choices

				newSymbol = results.at(wordResultIndex).getShapeId();
				newConf   = results.at(wordResultIndex).getConfidence();

				//updating the results

				initVec.assign(1,newSymbol);
				m_decodedResults.at(wordResultIndex).setWordRecoResult(initVec,newConf);

		}
	}

    else
	{
		//initializing a temporary result vector
		//newResultVector.assign(smallerResultNumber,LTKWordRecoResult());

		//iterating through each word recognition result
		for(wordResultIndex=0; wordResultIndex<m_decodedResults.size(); ++wordResultIndex)
		{
			wordConfidence = (m_decodedResults.at(wordResultIndex)).getResultConfidence();

			//iterating through each shape recognition results
			for(shapeResultIndex =0; shapeResultIndex<numShapeRecoResults; ++shapeResultIndex )
			{
				//adding total confidence to the map. so that later they
				//can be retrieved in the sorted order
				shapeConfidence = (results.at(shapeResultIndex)).getConfidence();
				backTrace.insert( pair<float, pair<int,int> >( (shapeConfidence+wordConfidence),
					pair<int,int>(wordResultIndex,shapeResultIndex)));
			}
		}

		iterend = backTrace.end();

		//iterating through the map to retrieve the largest confidences.
		for(wordResultIndex = 0,iter = backTrace.begin(); (wordResultIndex<numWordRecoResults)&&(iter!= iterend); ++wordResultIndex,++iter)
		{

			//confidence
			wordConfidence = (*iter).first;

			//the combination that gave this
			//confidence
			combination = (*iter).second;

			//copying the word reco result corresponding to
			//the combination to new result vector
			//newResultVector.at(wordResultIndex) = m_decodedResults.at(combination.first);
			LTKWordRecoResult tempWordRecoResult = m_decodedResults.at(combination.first);

			//retrieving the shape recognition result id
			//and confidence corresponding to the combination
			newSymbol = results.at(combination.second).getShapeId();
			newConf   = results.at(combination.second).getConfidence();

			//updating the word reco result with new id and confidence
			//newResultVector.at(wordResultIndex).updateWordRecoResult(newSymbol, newConf);

				tempWordRecoResult.updateWordRecoResult(newSymbol,newConf);
				newResultVector.push_back(tempWordRecoResult);
		}

		//assigning the newly created result vector
		m_decodedResults = newResultVector;
	}


	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
		<<"Exiting: BoxedFieldRecognizer::updateRecognitionResults"
		<<endl;


	return SUCCESS;
}
/**********************************************************************************
* AUTHOR		: Deepu V.
* DATE			: 22-AUG-2005
* NAME			: recognizeTraces
* DESCRIPTION	: performs the recognition of the new strokes added to rc
*               : pre condition - markers are present in this vector
*               :               - m_numTracesProcessed  and m_numCharsProcessed
*               :                 set to proper value
* ARGUMENTS		: rc - The recognitino context
* RETURNS		:
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of
*************************************************************************************/
int BoxedFieldRecognizer::recognizeTraces(LTKRecognitionContext& rc )
{
	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
	    <<"Entering: BoxedFieldRecognizer::recognizeTraces"
	    <<endl;

	vector<LTKTrace>::const_iterator traceIter,traceEnd,traceBegin;
	                 //iterator for the traces

	int errorCode = FAILURE;

	int recUnit;     //unit for recognition (should be char)

	LTKTraceGroup emptyChar;
	                 //TraceGroup object that buffers
	                 //all ink corresponding to a character

	vector<int> subSet;
	                 //passing a null arguement for shape subset

	vector<LTKShapeRecoResult> shapeRecoResults;
	                 //The object to hold the output from shape recognizer

	LTKScreenContext screenContext = rc.getScreenContext();
	                 //retrieving the screen context

	LTKCaptureDevice captureDevice = rc.getDeviceContext();
	                 //retrieving the device context

	const LTKTraceVector & traces = rc.getAllInk();
	                //retrieving the traces from recognition context

	string tempStr;  //temporary string object


	if(m_shapeRecognizer == NULL)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Shape recognizer not initialized" <<endl;

		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
		    <<"Error : "<< ENULL_POINTER <<":"<< getErrorMessage(ENULL_POINTER)
            <<" BoxedFieldRecognizer::recognizeTraces" <<endl;

		LTKReturnError(ENULL_POINTER);

	}
	else if( (errorCode = m_shapeRecognizer->setDeviceContext(captureDevice)) != SUCCESS)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Unable to set device context in shape rec : " << getErrorMessage(errorCode) <<endl;

		 LOG(LTKLogger::LTK_LOGLEVEL_ERR)
             <<"Error: BoxedFieldRecognizer::recognizeTraces"<<endl;

		LTKReturnError(errorCode);
	}

	shapeRecoResults.reserve(m_numShapeRecoResults+1);//reserving memory


	if(m_numTracesProcessed > traces.size())
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Invalid number of traces processed. "
		    << "Traces processed = " << m_numTracesProcessed
            <<  " > total number of traces" << traces.size() <<endl;

        LOG(LTKLogger::LTK_LOGLEVEL_ERR)
		             <<"Error : "<< EINVALID_NUM_OF_TRACES <<":"<< getErrorMessage(EINVALID_NUM_OF_TRACES)
             <<" BoxedFieldRecognizer::recognizeTraces" <<endl;

		LTKReturnError(EINVALID_NUM_OF_TRACES);
	}
	//Start processing from the number of traces processed.
	traceBegin = traces.begin() + m_numTracesProcessed;
	traceEnd = traces.end();int r=0;

	for(traceIter = traceBegin; traceIter != traceEnd; ++traceIter)
	{
		/* Marker strokes are inserted to detect
		 * end of segment.  The marker strokes are
		 * identified by 9number of channels == 0)
         */
		if((*traceIter).getNumberOfPoints() == 0)
		{
			tempStr = REC_UNIT_INFO;
			if((errorCode = rc.getFlag(tempStr,recUnit)) != SUCCESS)
			{
				LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            		<<"Error: BoxedFieldRecognizer::recognizeTraces"<<endl;

				LTKReturnError(errorCode);
			}
			switch(recUnit)
			{

			/* The segment is character
			 * This algorithm recognizes
			 * only character segments
			 */
			case REC_UNIT_CHAR:
				shapeRecoResults.clear();
				//calling the shape recognizer's recognize method.

				if(m_boxedChar.getNumTraces() == 0)
				{
					LTKShapeRecoResult T;
					T.setShapeId(SHRT_MAX);
					T.setConfidence(1.0);
					shapeRecoResults.push_back(T);
				}
				else if( (errorCode =	m_shapeRecognizer->recognize(m_boxedChar,screenContext,subSet,
					m_shapeRecoMinConfidence, m_numShapeRecoResults, shapeRecoResults ))!= SUCCESS )
				{
					LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Shape recognition failed : " << getErrorMessage(errorCode) <<endl;

					LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            			<<"Error: BoxedFieldRecognizer::recognizeTraces"<<endl;

					LTKReturnError(errorCode);
				}


				//This updates the recognition results using
				//current shape recognition results

				if((errorCode = updateRecognitionResults(shapeRecoResults,rc)) != SUCCESS)
				{
					LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            			<<"Error: BoxedFieldRecognizer::recognizeTraces"<<endl;

					LTKReturnError(errorCode);
				}

				for(r=0;r<shapeRecoResults.size();++r)
				{
					LTKShapeRecoResult& tempResult=shapeRecoResults[r];

				}

				m_boxedChar = emptyChar;//making the trace group empty again
				break;

			default:
				LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Unsupported reccognizer mode by Box Field" <<endl;

				LOG(LTKLogger::LTK_LOGLEVEL_ERR)
				    <<"Error : "<< EINVALID_RECOGNITION_MODE <<":"<< getErrorMessage(EINVALID_RECOGNITION_MODE)
             		<<" BoxedFieldRecognizer::recognizeTraces" <<endl;

				LTKReturnError(EINVALID_RECOGNITION_MODE);

			}
			++m_numCharsProcessed;      //incrementing number of characters processed
		}
		else
		{
			m_boxedChar.addTrace(*traceIter); //buffering the trace to the temp TraceGroup for recognition
		}
		++m_numTracesProcessed;         //incrementing the number of traces processed
	}


	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
		<<"Exiting: BoxedFieldRecognizer::recognizeTraces"
		<<endl;

	return SUCCESS;
}
/**********************************************************************************
* AUTHOR		: Deepu V.
* DATE			: 22-AUG-2005
* NAME			: recognize
* DESCRIPTION	: This is the recognize call
*               : The results of the recognition is set on the Recognition context
*               : object.  In case of BATCH_MODE recognition recognition of every
*               : character is performed.  otherwise the recognizer updates the outputs
*               : with the recognized results
* ARGUMENTS		: rc - The recognition context for the current recognition
* RETURNS		: SUCCESS/FAILURE
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of
*************************************************************************************/
int BoxedFieldRecognizer::recognize (LTKRecognitionContext& rc)
{
	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
	    <<"Entering: BoxedFieldRecognizer::recognize"
	    <<endl;

	string 	tempStr = REC_UNIT_INFO;  //temp string required to pass the arguments to set/get Flags

	int tempFlagValue = 0; //temp int to hold flag values

	int errorCode = 0;

	vector <LTKWordRecoResult>::iterator resultIter,resultEnd;  //iterates through decoded recognition results

	int numWordRecoResults ; //Number of results required by the application

	int resultIndex ; //index to iterate through the results

	vector<unsigned short> resultString; //result

	float normConf; //normalized confidence

	//Returning FAILURE if the recognition context
	//is not segmented into characters

	if((errorCode=rc.getFlag(tempStr,tempFlagValue))!=SUCCESS)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            <<"Error: BoxedFieldRecognizer::recognize"<<endl;

		LTKReturnError(errorCode);
	}

	if( tempFlagValue != REC_UNIT_CHAR)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
		    <<"Error : "<< EINVALID_SEGMENT <<":"<< getErrorMessage(EINVALID_SEGMENT)
            <<" BoxedFieldRecognizer::recognize" <<endl;

		LTKReturnError(EINVALID_SEGMENT);
	}

	tempStr =REC_MODE;

	if((errorCode=rc.getFlag(tempStr,tempFlagValue))!=SUCCESS)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            <<"Error: BoxedFieldRecognizer::recognize"<<endl;

		LTKReturnError(errorCode);
	}

	if(tempFlagValue == REC_MODE_BATCH)
	{
		//clear all the recognizer state
		clearRecognizerState();
		recognizeTraces(rc);
	}
	else if (tempFlagValue == REC_MODE_STREAMING)
	{
		recognizeTraces(rc);
	}
	else
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
		    <<"Error : "<< EINVALID_REC_MODE <<":"<< getErrorMessage(EINVALID_REC_MODE)
            <<" BoxedFieldRecognizer::recognize" <<endl;

		LTKReturnError(EINVALID_REC_MODE);
	}

	/* Now all the recognized results are in
	 * m_decodedResults.
	 */

	resultEnd =	m_decodedResults.end();

	for(resultIter = m_decodedResults.begin(); resultIter != resultEnd ; ++resultIter)
	{
		normConf = (*resultIter).getResultConfidence();

		normConf /= ((*resultIter).getResultWord()).size();

		(*resultIter).setResultConfidence(normConf);

	}

	//number of requested results
	numWordRecoResults =  rc.getNumResults();

	//checking with existing recognition results' size
	if(numWordRecoResults > m_decodedResults.size())
	{
		LOG(LTKLogger::LTK_LOGLEVEL_INFO)
			<< "Don't have enough results to populate. Num of results available = "
			<< m_decodedResults.size() <<", however, results asked for ="
			<< numWordRecoResults <<endl;
	}

	resultEnd = m_decodedResults.end();
	for(resultIndex =0,resultIter = m_decodedResults.begin();(resultIndex <numWordRecoResults)&&(resultIter != resultEnd); ++resultIndex,++resultIter)
	{
		//map the shape ids to unicode IDs
		if((errorCode = LTKStrEncoding::shapeStrToUnicode(m_boxedShapeProject,(*resultIter).getResultWord(),resultString)) != SUCCESS)
		{
			LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            	<<"Error: BoxedFieldRecognizer::recognize"<<endl;

			LTKReturnError(errorCode);
		}

		//adding the recognition result to recognition context
		 rc.addRecognitionResult(LTKWordRecoResult(resultString,
												   (*resultIter).getResultConfidence()));

		resultString.clear();

	}

	//clearing state of the recognizer
	clearRecognizerState();


	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
		<<"Exiting: BoxedFieldRecognizer::recognize"
	    <<endl;

	return SUCCESS;
}
/*****************************************************************************
* AUTHOR		: Deepu V.
* DATE			: 22-AUG-2005
* NAME			: processInk
* DESCRIPTION	: This method is called from recognition context whenever new traces
*               : are added to it.  The Recognizer need to process the new traces
*               : in this methods and updates the internal state.
* ARGUMENTS		: rc - The recognition context for the current recognition
* RETURNS		: SUCCESS/FAILURE
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of
******************************************************************************/
int BoxedFieldRecognizer::processInk (LTKRecognitionContext& rc)
{
	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
	    <<"Entering: BoxedFieldRecognizer::processInk"
	    <<endl;

	string tempStr = REC_UNIT_INFO;

	int tempFlagValue=0;

	int errorCode=0;

	if((errorCode=rc.getFlag(tempStr,tempFlagValue))!=SUCCESS)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            <<"Error: BoxedFieldRecognizer::processInk"<<endl;

		LTKReturnError(errorCode);
	}

	//give an error if the Ink is not segmented into characters
	if(tempFlagValue != REC_UNIT_CHAR)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
		    <<"Error : "<< EINVALID_SEGMENT <<":"<< getErrorMessage(EINVALID_SEGMENT)
            <<" BoxedFieldRecognizer::processInk" <<endl;

		LTKReturnError(EINVALID_SEGMENT);
	}

	tempStr = REC_MODE;


	if((errorCode=rc.getFlag(tempStr,tempFlagValue))!=SUCCESS)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
            <<"Error: BoxedFieldRecognizer::processInk"<<endl;

		LTKReturnError(errorCode);
	}

	//if the recognizer mode is correct
	if (tempFlagValue == REC_MODE_STREAMING)
	{
		//recognize the newly added strokes
		recognizeTraces(rc);
	}
	else
	{
		//give an error otherwise
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)
			<<"Error : "<< EINVALID_REC_MODE <<":"<< getErrorMessage(EINVALID_REC_MODE)
            <<" BoxedFieldRecognizer::processInk" <<endl;


		LTKReturnError(EINVALID_REC_MODE);
	}

	LOG(LTKLogger::LTK_LOGLEVEL_DEBUG)
		<<"Exiting: BoxedFieldRecognizer::processInk"
	    <<endl;

	return SUCCESS;
}
Ejemplo n.º 5
0
/**********************************************************************************
* AUTHOR		: Thanigai Murugan K
* DATE			: 30-AUG-2005
* NAME			: evaluateWordRecognizer
* DESCRIPTION	: Load the model data and call recognize function and display the
*				  results. 
* ARGUMENTS		: pReco - handle to LTKWordRecognizer object
* RETURNS		: -1 on error 0 on success
* NOTES			:
* CHANGE HISTROY
* Author			Date				Description of change
*************************************************************************************/
int evaluateWordRecognizer(LTKWordRecognizer *pReco, const string& infilelist)
{
	int iErrorCode = 0;
	string tempStr(REC_UNIT_INFO), tempStr1(REC_MODE);
	string path;
	string strShapeId;

	vector<LTKTraceGroup> fieldInk;
	int charIndex;
	wstring eolstr(L"\r\n");
	int i;
    string strWordId;

	LTKRecognitionContext *recoContext = new LTKRecognitionContext();

	LTKCaptureDevice deviceContext;
	LTKScreenContext screenContext;

	recoContext->setWordRecoEngine(pReco);
	recoContext->setFlag(tempStr,REC_UNIT_CHAR);
	recoContext->setFlag(tempStr1,REC_MODE_STREAMING);

	recoContext->setNumResults(numChoices);

	ifstream in(infilelist.c_str());
	if(in == NULL)
	{
		LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< "Test list file open error " << infilelist <<endl;
		cout << "Test list file open error : " << infilelist.c_str() << endl;

		//delete recognition context object
		if(recoContext)
		{
			//ptrObj->deleteRecognitionContext(recoContext);

			delete recoContext;
			recoContext = NULL;
		}
		return FAILURE;
	}

	ofstream resultfile(strOutputFileName,ios::out|ios::binary);

	//a Header of 0xFEFF is required to identify this is a
	//16 bit unicode file
	const unsigned short fHeader = 0xfeff;
	resultfile.write((char*)&fHeader,sizeof(unsigned short));

	while(in)
	{
		//Get the file name
		if(!getline(in,path,' ')) 
		{
			break;
		}
		
		//Get the word ID
		getline(in,strWordId);
		//iWordID = atoi(strShapeId.c_str());

		if(path.length() > 0 && path[0] == COMMENTCHAR )
		{
			continue;
		}

		if(path.length() == 0)
		{
			LOG(LTKLogger::LTK_LOGLEVEL_ERR)<< "Empty File name" <<endl;
			continue;
		}

		try
		{
			fieldInk.clear();

			getAbsolutePath(path,strLipiRootPath);

			cout << path << endl;

			//read the word file
			if(readWordFile(path, fieldInk, deviceContext, screenContext) != SUCCESS)
			{
				LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Error reading ink file:" << path << endl;
				cout<<"Error reading ink file:" << path << endl;
				cout<<"Aborted"<<endl;

				//delete recognition context object
				if(recoContext)
				{
					//ptrObj->deleteRecognitionContext(recoContext);

					delete recoContext;
					recoContext = NULL;
				}
				return FAILURE;

			}
			recoContext->setDeviceContext(deviceContext);
			recoContext->setScreenContext(screenContext);

			if(fieldInk.size()==0)
			{

				LOG(LTKLogger::LTK_LOGLEVEL_ERR) << "Empty trace group read from:" << path << endl;
				continue;
			}
			
			for(charIndex = 0; charIndex < fieldInk.size(); ++charIndex)
			{
				recoContext->beginRecoUnit();
				recoContext->addTraceGroups(LTKTraceGroupVector(1,fieldInk.at(charIndex)));
				recoContext->endRecoUnit();
				recoContext->beginRecoUnit();
				recoContext->addTraceGroups(LTKTraceGroupVector(1,LTKTraceGroup()));
				recoContext->endRecoUnit();

			}
		}
		catch(LTKException e)
		{
			LOG(LTKLogger::LTK_LOGLEVEL_ERR) << e.getExceptionMessage() <<endl;

			//delete recognition context object
			if(recoContext)
			{
				//ptrObj->deleteRecognitionContext(recoContext);

				delete recoContext;
				recoContext = NULL;
			}

			return FAILURE;
		}

		//Calling recognize and retrieving the top result
		{
			LTKWordRecoResult result;
			vector<LTKWordRecoResult> r2;
			recoContext->recognize();
			recoContext->getTopResult(result);
			recoContext->getNextBestResults(numChoices-1, r2);

			vector<unsigned short> resultVec = result.getResultWord();
			if(!resultVec.empty())
			{
				resultfile.write((char *)&(resultVec.at(0)), resultVec.size()*sizeof(unsigned short));
				resultfile.write((char*)eolstr.c_str(),eolstr.length()*sizeof(unsigned short));

				for(i =0; i<r2.size(); ++i)
				{
					resultVec = r2.at(i).getResultWord();
					resultfile.write((char *)&(resultVec.at(0)), resultVec.size()*sizeof(unsigned short));
					resultfile.write((char*)eolstr.c_str(),eolstr.length()*sizeof(unsigned short));
				}
			}

			recoContext->clearRecognitionResult();
		}

		resultfile.write((char*)eolstr.c_str(),eolstr.length()*sizeof(unsigned short));
	}

	resultfile.close();

	//delete recognition context object
	if(recoContext)
	{
		//ptrObj->deleteRecognitionContext(recoContext);

		delete recoContext;
		recoContext = NULL;
	}

	return SUCCESS;
}
int main(int argc, char** argv)
{
	char *envstring = NULL;
	int iResult;
	string tempStr(REC_UNIT_INFO), tempStr1(REC_MODE);
	string path;
	string strShapeId;
    string strWordId;
	char infilelist[MAX_PATH];
	string outfile("wordrectst.out");
	vector<LTKTraceGroup> fieldInk;
	int charIndex;
	wstring eolstr(L"\r\n");
	int i;
    

	// first argument is the logical project name 
	// second argument is the ink file to recognize
	// third argument is the output file
	if(argc < 4)
	{
		cout << "\nUsage:";
		cout << "\nwordrectst <logical projectname> <list file to recognize> <outputfile>";
		cout << "\nlist of valid <logicalname>s is available in $LIPI_ROOT/projects/lipiengine.cfg file";
		cout << endl;
        delete utilPtr;
		return -1;
	}

	// Get the LIPI_ROOT environment variable 
	envstring = getenv(LIPIROOT_ENV_STRING);
	if(envstring == NULL)
	{
		cout << "\nError, Environment variable is not set LIPI_ROOT\n";
        delete utilPtr;
		return -1;
	}

	// Load the LipiEngine.DLL
	hLipiEngine = NULL;
	iResult = utilPtr->loadSharedLib(envstring, LIPIENGINE_MODULE_STR, &hLipiEngine);

	if(iResult != SUCCESS)
	{
		cout << "Error loading LipiEngine module" << endl;
        delete utilPtr;
		return -1;
	}

	if(MapFunctions() != 0)
	{
		cout << "Error fetching exported functions of the module" << endl;
        delete utilPtr;
		return -1;
	}

	// create an instance of LipiEngine Module
	ptrObj = createLTKLipiEngine();

	// set the LIPI_ROOT path in Lipiengine module instance
	ptrObj->setLipiRootPath(envstring);

	// Initialize the LipiEngine module
	iResult = ptrObj->initializeLipiEngine();
	if(iResult != SUCCESS)
	{
		cout << iResult << ": Error initializing LipiEngine.\n";
		utilPtr->unloadSharedLib(hLipiEngine);
        delete utilPtr;

		return -1;
	}

//	Assign the logical name of the project to this string, i.e. TAMIL_WORD
	string strLogicalName = string(argv[1]);

	strcpy(infilelist,  argv[2]);
	outfile = argv[3];

	LTKWordRecognizer *pWordReco = NULL;
	ptrObj->createWordRecognizer(strLogicalName,&pWordReco);
	if(pWordReco == NULL)
	{
		cout << "\nError creating Word Recognizer\n";
	
		utilPtr->unloadSharedLib(hLipiEngine);
        delete utilPtr;
		return -1;
	}

//	You can also use project and profile name to create LipiEngine instance as follows...
//	string strProjectName = "tamil_boxed_field";
//	string strProfileName = "default";
//	LTKWordRecognizer *pWordReco = ptrObj->createWordRecognizer(&strProjectName, &strProfileName);

	int iErrorCode = 0;
	LTKRecognitionContext *recoContext = new LTKRecognitionContext();

	if(iErrorCode != 0)
	{
		cout << "\nError creating recognition context.\n";
		ptrObj->deleteWordRecognizer(pWordReco);

        utilPtr->unloadSharedLib(hLipiEngine);
        delete utilPtr;
        
		return -1;
	}

	LTKCaptureDevice deviceContext;
	LTKScreenContext screenContext;
	int numChoices = 2;

	// Setting the device attributes
	deviceContext.setSamplingRate(120);	
	deviceContext.setXDPI(2500);
	deviceContext.setYDPI(2500);
	deviceContext.setUniformSampling(true);

	// Set the engine to recognizer
	recoContext->setWordRecoEngine(pWordReco);
	
	// set the device context
	recoContext->setDeviceContext(deviceContext);
	// set the screen context
	recoContext->setScreenContext(screenContext);

	recoContext->setFlag(tempStr,REC_UNIT_CHAR);
	recoContext->setFlag(tempStr1,REC_MODE_STREAMING);

	// set the number of choices required
	recoContext->setNumResults(numChoices);

	ifstream in(infilelist);
	if(in == NULL)
	{
		cout << "Test list file open error : " << infilelist << endl;
        delete utilPtr;
		return -1;
	}

	ofstream resultfile(outfile.c_str(),ios::out|ios::binary);

	//a Header of 0xFEFF is required to identify this is a
	//16 bit unicode file
	const unsigned short fHeader = 0xfeff;
	resultfile.write((char*)&fHeader,sizeof(unsigned short));

	while(in)
	{
		//Get the file name
		if(!getline(in,path,' ')) 
		{
			break;
		}
		
		//Get the word ID
		getline(in,strWordId);
		//iWordID = atoi(strShapeId.c_str());

		cout << path << endl;

		try
		{
			fieldInk.clear();
		
			//read the word file
			readWordFile(path, fieldInk, deviceContext, screenContext);
			
			for(charIndex = 0; charIndex < fieldInk.size(); ++charIndex)
			{
				recoContext->beginRecoUnit();
				recoContext->addTraceGroups(LTKTraceGroupVector(1,fieldInk.at(charIndex)));
				recoContext->endRecoUnit();

			}
		}
		catch(LTKException e)
		{
			LOG(LTKLogger::LTK_LOGLEVEL_ERR) << e.getExceptionMessage();
			return FAILURE;
		}

		//Calling recognize and retrieving the top result
		{
			LTKWordRecoResult result;
			vector<LTKWordRecoResult> r2;
			recoContext->recognize();
			recoContext->getTopResult(result);
			recoContext->getNextBestResults(numChoices-1, r2);

			vector<unsigned short> resultVec = result.getResultWord();

			if(!resultVec.empty())
			{
				resultfile.write((char *)&(resultVec.at(0)), resultVec.size()*sizeof(unsigned short));
				resultfile.write((char*)eolstr.c_str(),eolstr.length()*sizeof(unsigned short));

				for(i =0; i<r2.size(); ++i)
				{
					resultVec = r2.at(i).getResultWord();
					resultfile.write((char *)&(resultVec.at(0)), resultVec.size()*sizeof(unsigned short));
					resultfile.write((char*)eolstr.c_str(),eolstr.length()*sizeof(unsigned short));
				}
			}

			recoContext->clearRecognitionResult();
		}

	}

	resultfile.close();

	//delete word recognition instance
	if(pWordReco)
	{
		ptrObj->deleteWordRecognizer(pWordReco);
	}

	//delete recognition context object
	if(recoContext)
	{
		//ptrObj->deleteRecognitionContext(recoContext);
		delete recoContext;
	}

	

	//unload the LipiEngine module from memory...
	utilPtr->unloadSharedLib(hLipiEngine);
    delete utilPtr;

	return 0;
}