/****************************************************************************** * AUTHOR : Bharath A * DATE : 12-Jun-2008 * NAME : convertFeatVecToTraceGroup * DESCRIPTION : * ARGUMENTS : * RETURNS : * NOTES : * CHANGE HISTROY * Author Date Description ******************************************************************************/ int NPenShapeFeatureExtractor::convertFeatVecToTraceGroup( const vector<LTKShapeFeaturePtr>& shapeFeature, LTKTraceGroup& outTraceGroup) { LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " << "NPenShapeFeatureExtractor::convertFeatVecToTraceGroup()" << endl; vector<LTKChannel> channels; // channels of a trace LTKChannel xChannel("X", DT_FLOAT, true); // x-coordinate channel of the trace LTKChannel yChannel("Y", DT_FLOAT, true); // y-coordinate channel of the trace //initializing the channels of the trace channels.push_back(xChannel); channels.push_back(yChannel); // composing the trace format object LTKTraceFormat traceFormat(channels); vector<float> point; // a point of a trace LTKTrace trace(traceFormat); for(int count=0;count<(int)shapeFeature.size();count++) { float Xpoint, Ypoint; bool penUp; NPenShapeFeature* ptr = (NPenShapeFeature*)(shapeFeature[count].operator ->()); Xpoint = ptr->getX(); Ypoint = ptr->getY(); penUp = ptr->isPenUp(); point.push_back(Xpoint); point.push_back(Ypoint); trace.addPoint(point); point.clear(); if(penUp == true) // end of a trace, clearing the trace now { outTraceGroup.addTrace(trace); trace.emptyTrace(); LTKTrace tempTrace(traceFormat); trace = tempTrace; } } LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " << "NPenShapeFeatureExtractor::convertFeatVecToTraceGroup()" << endl; return SUCCESS; }
int NPenShapeFeature::getDistance(const LTKShapeFeaturePtr& shapeFeaturePtr, float& outDistance) const { outDistance = 0.0; NPenShapeFeature *inFeature = (NPenShapeFeature*)(shapeFeaturePtr.operator ->()); outDistance += (m_x - inFeature->getX())*(m_x - inFeature->getX()); outDistance += (m_y - inFeature->getY())*(m_y - inFeature->getY()); outDistance += (m_cosAlpha - inFeature->getCosAlpha())*(m_cosAlpha - inFeature->getCosAlpha()); outDistance += (m_sinAlpha - inFeature->getSinAlpha())*(m_sinAlpha - inFeature->getSinAlpha()); outDistance += (m_cosBeta - inFeature->getCosBeta())*(m_cosBeta - inFeature->getCosBeta()); outDistance += (m_sinBeta - inFeature->getSinBeta())*(m_sinBeta - inFeature->getSinBeta()); outDistance += (m_aspect - inFeature->getAspect())*(m_aspect - inFeature->getAspect()); outDistance += (m_curliness - inFeature->getCurliness())*(m_curliness - inFeature->getCurliness()); outDistance += (m_linearity - inFeature->getLinearity())*(m_linearity - inFeature->getLinearity()); outDistance += (m_slope - inFeature->getSlope())*(m_slope - inFeature->getSlope()); return SUCCESS; }
LTKShapeFeaturePtr NPenShapeFeature::clone() const { NPenShapeFeature* npenSF = new NPenShapeFeature(); npenSF->setX(this->getX()); npenSF->setY(this->getY()); npenSF->setCosAlpha(this->getCosAlpha()); npenSF->setSinAlpha(this->getSinAlpha()); npenSF->setCosBeta(this->getCosBeta()); npenSF->setSinBeta(this->getSinBeta()); npenSF->setAspect(this->getAspect()); npenSF->setCurliness(this->getCurliness()); npenSF->setLinearity(this->getLinearity()); npenSF->setSlope(this->getSlope()); npenSF->setPenUp(this->isPenUp()); return (LTKShapeFeaturePtr)npenSF; }
/********************************************************************************** * AUTHOR : Bharath A * DATE : 12-Jun-2008 * NAME : extractFeatures * DESCRIPTION : Extracts NPen features from a trace group * ARGUMENTS : The trace group from which features have to be extracted * RETURNS : vector of NPenShapeFeature objects * NOTES : * CHANGE HISTROY * Author Date Description of change *************************************************************************************/ int NPenShapeFeatureExtractor::extractFeatures(const LTKTraceGroup& inTraceGroup, vector<LTKShapeFeaturePtr>& outFeatureVec) { LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Entering " << "NPenShapeFeatureExtractor::extractFeatures()" << endl; NPenShapeFeature* featurePtr = NULL; vector<vector<float> > floatFeatureValues; int errorCode; if(inTraceGroup.getNumTraces() == 0) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EEMPTY_TRACE_GROUP); } vector<vector<float> > concatenatedCoord; int currPenUpPointIndex = -1; vector<int> penUpPointsIndices; int halfWindowSize = m_windowSize/2; if(halfWindowSize==0) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EINVALID_NUM_OF_POINTS); } for(int t=0;t<inTraceGroup.getNumTraces();++t) { LTKTrace eachTrace; inTraceGroup.getTraceAt(t,eachTrace); if(eachTrace.isEmpty()) { LOG(LTKLogger::LTK_LOGLEVEL_ERR) <<"Error: FeatureExtractor::findAllFeatures"<<endl; LTKReturnError(EEMPTY_TRACE); } vector<float> xVec; vector<float> yVec; eachTrace.getChannelValues(X_CHANNEL_NAME,xVec); eachTrace.getChannelValues(Y_CHANNEL_NAME,yVec); if(t==0) { vector<float> firstPoint; firstPoint.push_back(xVec[0]); firstPoint.push_back(yVec[0]); concatenatedCoord.insert(concatenatedCoord.begin(),halfWindowSize,firstPoint); } for(int p=0;p<xVec.size();++p) { vector<float> point; point.push_back(xVec[p]); point.push_back(yVec[p]); concatenatedCoord.push_back(point); } currPenUpPointIndex += xVec.size(); penUpPointsIndices.push_back(currPenUpPointIndex); if(t==(inTraceGroup.getNumTraces()-1)) { vector<float> lastPoint; lastPoint.push_back(xVec[xVec.size()-1]); lastPoint.push_back(yVec[yVec.size()-1]); concatenatedCoord.insert(concatenatedCoord.end(),halfWindowSize,lastPoint); } } /* 0 - normalized x 1 - normalized y 2 - cos alpha 3 - sin alpha 4 - cos beta 5 - sin beta 6 - aspect 7 - curliness 8 - linearity 9 - slope 10 - pen-up / pen-down stroke (0 for pen-down and 1 for pen-up)*/ float deltaX=0; float deltaY=0; float hypotenuse=0; float cosalpha=0; float sinalpha=0; float cosbeta=0; float sinbeta=0; float ispenup=0; float aspect=0; float curliness=0; float linearity=0; float slope=0; float xMin,yMin,xMax,yMax; //for vicnity bounding box; float bbWidth,bbHeight; float maxOfWidthHeight; currPenUpPointIndex = 0; for(int f=halfWindowSize;f<(concatenatedCoord.size()-halfWindowSize);++f) { vector<float> eachPointFeature; eachPointFeature.push_back(concatenatedCoord[f][0]); //x eachPointFeature.push_back(concatenatedCoord[f][1]); //y deltaX = concatenatedCoord[f-1][0] - concatenatedCoord[f+1][0]; deltaY = concatenatedCoord[f-1][1] - concatenatedCoord[f+1][1]; hypotenuse = sqrt((deltaX*deltaX)+(deltaY*deltaY)); if(hypotenuse < EPS) { cosalpha = 1; sinalpha = 0; } else { cosalpha = deltaX / hypotenuse; sinalpha = deltaY / hypotenuse; } eachPointFeature.push_back(cosalpha); eachPointFeature.push_back(sinalpha); eachPointFeature.push_back(cosbeta); //creating empty spaces for cosine and sine betas for future assignment eachPointFeature.push_back(sinbeta); vector<vector<float> > vicinity; float vicinityTrajLen = 0.0f; for(int v=f-halfWindowSize;v<=f+halfWindowSize;++v) { vicinity.push_back(concatenatedCoord[v]); if(v<(f+halfWindowSize)) { vicinityTrajLen += (sqrt(((concatenatedCoord[v+1][1]-concatenatedCoord[v][1])*(concatenatedCoord[v+1][1]-concatenatedCoord[v][1]))+((concatenatedCoord[v+1][0]-concatenatedCoord[v][0])*(concatenatedCoord[v+1][0]-concatenatedCoord[v][0])))); } } findVicinityBoundingBox(vicinity,xMin,yMin,xMax,yMax); bbWidth = xMax - xMin; bbHeight = yMax - yMin; if(fabs(bbHeight+bbWidth)<EPS) { aspect = 0.0; } else { aspect = (bbHeight-bbWidth)/(bbHeight+bbWidth); } eachPointFeature.push_back(aspect); maxOfWidthHeight = ( bbWidth > bbHeight) ? bbWidth : bbHeight; if(fabs(maxOfWidthHeight) < EPS) { curliness = 0.0f; } else { curliness = (vicinityTrajLen / maxOfWidthHeight) - 2; } eachPointFeature.push_back(curliness); computeLinearityAndSlope(vicinity,linearity,slope); eachPointFeature.push_back(linearity); eachPointFeature.push_back(slope); if(penUpPointsIndices[currPenUpPointIndex] == (f-halfWindowSize)) { ispenup = 1; ++currPenUpPointIndex; } else { ispenup = 0; } eachPointFeature.push_back(ispenup); //currently assuming pen-up strokes are not resampled floatFeatureValues.push_back(eachPointFeature); } //duplicating first and last features vector<float> firstFeaturePoint = floatFeatureValues[0]; floatFeatureValues.insert(floatFeatureValues.begin(),1,firstFeaturePoint); vector<float> lastFeaturePoint = floatFeatureValues[floatFeatureValues.size()-1]; floatFeatureValues.insert(floatFeatureValues.end(),1,lastFeaturePoint); for(int ff=1;ff<(floatFeatureValues.size()-1);++ff) { floatFeatureValues[ff][4] = (floatFeatureValues[ff-1][2]*floatFeatureValues[ff+1][2]) + (floatFeatureValues[ff-1][3]*floatFeatureValues[ff+1][3]); floatFeatureValues[ff][5] = (floatFeatureValues[ff-1][2]*floatFeatureValues[ff+1][3]) - (floatFeatureValues[ff-1][3]*floatFeatureValues[ff+1][2]); } //removing the extraneous feature points at the beginning and end floatFeatureValues.erase(floatFeatureValues.begin(),floatFeatureValues.begin()+1); floatFeatureValues.pop_back(); for(int a=0;a<floatFeatureValues.size();++a) { NPenShapeFeature* ptrFeature = new NPenShapeFeature(); ptrFeature->setX(floatFeatureValues[a][0]); ptrFeature->setY(floatFeatureValues[a][1]); ptrFeature->setCosAlpha(floatFeatureValues[a][2]); ptrFeature->setSinAlpha(floatFeatureValues[a][3]); ptrFeature->setCosBeta(floatFeatureValues[a][4]); ptrFeature->setSinBeta(floatFeatureValues[a][5]); ptrFeature->setAspect(floatFeatureValues[a][6]); ptrFeature->setCurliness(floatFeatureValues[a][7]); ptrFeature->setLinearity(floatFeatureValues[a][8]); ptrFeature->setSlope(floatFeatureValues[a][9]); if(fabs(floatFeatureValues[a][10]-1.0f) < EPS) { ptrFeature->setPenUp(true); } else { ptrFeature->setPenUp(false); } outFeatureVec.push_back(LTKShapeFeaturePtr(ptrFeature)); ptrFeature = NULL; } LOG(LTKLogger::LTK_LOGLEVEL_DEBUG) << "Exiting " << "NPenShapeFeatureExtractor::extractFeatures()" << endl; return SUCCESS; }