/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLCV/src/ICLCV/PositionTracker.cpp ** ** Module : ICLCV ** ** Authors: Christof Elbrechter, Robert Haschke ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #include #include #include /** new data | o o x(t) o o -------------------------+----------------------- o o o o | d d d d d | o o o o | d ... | x(t-3) x(t-2) x(t-1) ลท(t)| | o o o o | | o o o o | | Data[0] Data[1] ... | Dist[0], Dist[1], ... Data Dist /\ vecPredict */ using namespace std; using namespace icl::utils; using namespace icl::core; namespace icl{ namespace cv{ namespace positiontracker{ const int X = 0; const int Y = 1; const int BLIND_VALUE = 9999; } using namespace positiontracker; #define SAY(X) void show_vec(const std::vector &v, const std::string &s){ // {{{ open printf("%s[%d][ ",s.c_str(),(unsigned int)v.size()); for(unsigned int i=0;i > m[2]){ // {{{ open int DIM = m[0][0].size(); for(int d=0;d void removeElemsFromVector(std::vector &v,const std::vector &rows){ // {{{ open vector newV;//(v.size()-rows.size()); int r=0,vidx=0; for(; vidx<(int)(v.size()) && r<(int)rows.size() ; vidx++){ if(rows[r]!=vidx){ newV.push_back(v[vidx]);// [newvidx++] = v[vidx]; }else{ r++; } } for(;vidx<(int)v.size();vidx++){ newV.push_back(v[vidx]); } v=newV; } // }}} template void removeRowsFromDataMatrix(std::deque > *m,const std::vector &rows){ // {{{ open /// rows must be sorted ! for(int d=0; d <= 1; d++){ std::deque > &md = m[d]; for(int x=0;x<3;x++){ vector &v = md[x]; removeElemsFromVector(v,rows); /* vector newV(v.size()-rows.size()); for(int r=0,vidx=0,newvidx=0;vidx<(int)v.size();vidx++){ if(rows[r]!=vidx){ newV[newvidx++] = v[vidx]; }else{ r++; } } v=newV; */ } } } // }}} template void PositionTracker::pushData(valueType *xys, int n){ // {{{ open Vec x(n),y(n); for(int i=0;i void PositionTracker::pushData(std::vector points){ // {{{ open int n = points.size(); Vec x(n),y(n); for(int i=0;i Array2D createDistMat(const vector a[2], const vector b[2]){ // {{{ open ICLASSERT( a[X].size() == b[X].size() ); // DEBUG if( a[X].size() != b[X].size() ) printf("error: %d != %d \n",a[X].size(),b[X].size()); int dim = (int)a[X].size(); Array2D m(dim,dim); for(int i=0;i inline vector predict(int dim, std::deque > &data, const vector &good){ // {{{ open vector pred; for(int y=0 ; y < dim; ++y){ //if(y>=(int)good.size()) printf("!!!!!!!!!!!!!! waring dim=%d good.size = %d \n",dim,good.size()); switch(good[y]){ case 1: pred.push_back( data[2][y] ); break; case 2: pred.push_back( Extrapolator::predict( data[1][y], data[2][y]) ); break; default: pred.push_back( Extrapolator::predict( data[0][y], data[1][y], data[2][y]) ); break; } } // ok old pred.push_back( Extrapolator::predict( data[0][y], data[1][y], data[2][y] ) ); return pred; } // }}} inline vector get_n_new_ids(const vector ¤tIDS, int n, icl::cv::IDAllocationMode iaMode, int& lowestUnusedID){ // {{{ open vector ids; set lut; switch(iaMode){ case allocateFirstFreeIDs: for(unsigned int i=0;i void push_and_rearrange_data(int dim, std::deque > data[2], const vector &assignment, const vector newData[2]){ // {{{ open vector arrangedData[2] = {vector(dim),vector(dim)}; for(int i=0;i void push_data_intern_diff_zero(int dim, std::deque > data[2], vector &assignment, vector newData[2], vector &good){ // {{{ open vector pred[2] = { predict(dim,data[X],good), predict(dim,data[Y],good) }; Array2D distMat = createDistMat( pred , newData ); assignment = HungarianAlgorithm::apply(distMat); push_and_rearrange_data(dim, data, assignment, newData); for(unsigned int i=0;i inline valueType distance(valueType x1, valueType y1, valueType x2, valueType y2){ return (valueType) sqrt( pow((double)(x1-x2),2) + pow((double)(y1-y2),2) ); } template bool push_data_first_optimized_try(int dim, std::deque > data[2], vector &assignment, vector newData[2], vector &good, valueType threshold){ // {{{ open vector xsOld(dim); vector ysOld(dim); for(int y=0 ; y < dim; ++y){ xsOld[y] = data[0][2][y]; ysOld[y] = data[1][2][y]; } vector &xsNew = newData[0]; vector &ysNew = newData[1]; vector assigned(dim,false); vector newAssignment(dim,-1); // printf("==================== step ============\n"); //printf("optimzation ... for %d centers\n",dim); for(int i=0;i::max(); int minIdx = -1; for(int j=0;j void push_data_intern_diff_gtz(int DIFF, deque > data[2], vector &ids, vector &assignment, vector newData[2], vector &good){ // {{{ open // new data contains less points -> enlarge new new data for(int i=0;i pred[2] = { predict(dim,data[X],good), predict(dim,data[Y],good) }; Array2D distMat = createDistMat( pred , newData ); assignment = HungarianAlgorithm::apply(distMat); push_and_rearrange_data(dim, data, assignment, newData); vector delRows; for(int i=0;i void push_data_intern_diff_ltz(int DIFF, deque > data[2], vector &ids, vector &assignment, vector newData[2], vector &good, icl::cv::IDAllocationMode iaMode, int &lowestUnusedID){ // {{{ open DIFF *= -1; // now positive for(int j=0;j pred[2] = { predict(dim,data[X],good), predict(dim,data[Y],good) }; /// restore good good.resize(good.size()-DIFF); Array2D distMat = createDistMat( pred , newData ); assignment = HungarianAlgorithm::apply(distMat); /// //vector newDataCols; vector newDataColsValues[2]; for(int x=0;x= dim-DIFF){ newDataColsValues[X].push_back(newData[X][ assignment[x] ]); newDataColsValues[Y].push_back(newData[Y][ assignment[x] ]); } } if((int)newDataColsValues[X].size() != DIFF){ printf("WARNING: newDataColsValues[X].size()[%d] is != DIFF[%d]",(int)newDataColsValues[X].size(),DIFF); } vector newIDS = get_n_new_ids(ids,DIFF,iaMode, lowestUnusedID); for(int i=0;i void push_data_intern_first_step(deque > data[2], vector &ids, vector &assignment, vector newData[2], vector &good){ // {{{ open for(int i=0;i<3;i++){ data[X].push_back(newData[X]); data[Y].push_back(newData[Y]); } ids.resize(newData[X].size()); for(unsigned int i=0;i void PositionTracker::pushData(const Vec &dataXs, const Vec &dataYs){ // {{{ open ICLASSERT_RETURN( dataXs.size() > 0 ); ICLASSERT_RETURN( dataXs.size() == dataYs.size() ); Vec newData[2] = {dataXs, dataYs}; if(!m_matData[X].size()){ push_data_intern_first_step(m_matData, m_vecIDs, m_vecCurrentAssignment, newData, m_vecGoodDataCount); return; } const int DATA_MATRIX_HEIGHT = (int)(m_matData[X][0].size()); const int NEW_DATA_DIMENSION = (int)(dataXs.size()); const int DIFF = DATA_MATRIX_HEIGHT - NEW_DATA_DIMENSION; if(DIFF < 0){ push_data_intern_diff_ltz(DIFF,m_matData, m_vecIDs, m_vecCurrentAssignment, newData,m_vecGoodDataCount, m_IDAllocationMode, m_currentID); }else if(DIFF > 0){ push_data_intern_diff_gtz(DIFF,m_matData, m_vecIDs, m_vecCurrentAssignment, newData,m_vecGoodDataCount); }else{ if(m_bTryOptimize && m_tThreshold > 0){ bool succ = push_data_first_optimized_try(DATA_MATRIX_HEIGHT,m_matData,m_vecCurrentAssignment,newData,m_vecGoodDataCount,m_tThreshold); if(!succ){ push_data_intern_diff_zero(DATA_MATRIX_HEIGHT,m_matData, m_vecCurrentAssignment, newData,m_vecGoodDataCount); } }else{ push_data_intern_diff_zero(DATA_MATRIX_HEIGHT,m_matData, m_vecCurrentAssignment, newData,m_vecGoodDataCount); } } } // }}} // {{{ old code /* if(!m_matData[X].size()){ // first step for(int i=0;i<3;i++){ m_matData[X].push_back(dataXs); m_matData[Y].push_back(dataYs); } } m_matData[X][0].size(),m_matData[X][1].size(),m_matData[X][2].size(), m_matData[Y][0].size(),m_matData[Y][1].size(),m_matData[Y][2].size()); //static const valueType BLIND_VALUE = valueType(999); //const int DATA_MATRIX_HEIGHT = (int)(m_matData[X][0].size()); //const int NEW_DATA_DIMENSION = (int)(dataXs.size()); //const int DIFF = DATA_MATRIX_HEIGHT - NEW_DATA_DIMENSION; // create a working copy of the new data Vec newData[2] = {dataXs, dataYs}; if(DIFF > 0){ // redundant // new data contains less points -> enlarge new new data for(int i=0;i::predict( m_matData[X][0][y], m_matData[X][1][y], m_matData[X][2][y] ) ); vecPrediction[Y].push_back( Extrapolator::predict( m_matData[Y][0][y], m_matData[Y][1][y], m_matData[Y][2][y] ) ); } Array2D distMat(DATA_AND_MATRIX_DIM,DATA_AND_MATRIX_DIM); for(int x=0;x::apply(distMat); // add the new data column -> by assingned data elements if(DIFF > 0){ vector delRows; for(int i=0;i newDataCols; for(int i=0;i= DATA_AND_MATRIX_DIM+DIFF){ newDataCols.push_back(i); //ERROR not i but assignment[i] !! } } ICLASSERT( (int)newDataCols.size() == -DIFF ); for(int i=0;i<(-DIFF);i++){ for(int j=0;j<3;j++){ m_matData[X][j][DATA_AND_MATRIX_DIM+DIFF-i] = newData[X][newDataCols[i]]; m_matData[Y][j][DATA_AND_MATRIX_DIM+DIFF-i] = newData[Y][newDataCols[i]]; } } } /// rearrange the new data arrays vector rearrangedData[2] = { vector(DATA_AND_MATRIX_DIM), vector(DATA_AND_MATRIX_DIM)} ; for(int i=0;i < DATA_AND_MATRIX_DIM ;i++){ rearrangedData[X][i] = newData[X][ m_vecCurrentAssignement[i] ]; rearrangedData[Y][i] = newData[Y][ m_vecCurrentAssignement[i] ]; } if(DIFF > 0){ rearrangedData[X].resize(DATA_AND_MATRIX_DIM-DIFF); rearrangedData[Y].resize(DATA_AND_MATRIX_DIM-DIFF); } m_matData[X].push_back( rearrangedData[X] ); m_matData[Y].push_back( rearrangedData[Y] ); m_matData[X].pop_front(); m_matData[Y].pop_front(); */ // }}} template int PositionTracker::getID(valueType x, valueType y){ // {{{ open vector &rX = m_matData[X][2]; vector &rY = m_matData[Y][2]; for(unsigned int i=0;i int PositionTracker::getID(int index){ // {{{ open if(index >= 0 && index < (int)m_vecCurrentAssignment.size()){ return m_vecIDs[ m_vecCurrentAssignment[index] ]; }else{ return -1; } } // }}} template ICLCV_API class PositionTracker; template ICLCV_API class PositionTracker; //template class PositionTracker; } // namespace cv }