Пример #1
0
  void cvUpdateTracks(CvBlobs const &blobs, CvTracks &tracks, const double thDistance, const unsigned int thInactive, const unsigned int thActive)
  {
    CV_FUNCNAME("cvUpdateTracks");
    __CV_BEGIN__;

    unsigned int nBlobs = blobs.size();
    unsigned int nTracks = tracks.size();

    // Proximity matrix:
    // Last row/column is for ID/label.
    // Last-1 "/" is for accumulation.
    CvID *close = new unsigned int[(nBlobs+2)*(nTracks+2)]; // XXX Must be same type than CvLabel.

    try
    {
      // Inicialization:
      unsigned int i=0;
      for (CvBlobs::const_iterator it = blobs.begin(); it!=blobs.end(); ++it, i++)
      {
	AB(i) = 0;
	IB(i) = it->second->label;
      }

      CvID maxTrackID = 0;

      unsigned int j=0;
      for (CvTracks::const_iterator jt = tracks.begin(); jt!=tracks.end(); ++jt, j++)
      {
	AT(j) = 0;
	IT(j) = jt->second->id;
	if (jt->second->id > maxTrackID)
	  maxTrackID = jt->second->id;
      }

      // Proximity matrix calculation and "used blob" list inicialization:
      for (i=0; i<nBlobs; i++)
	for (j=0; j<nTracks; j++)
	  if (C(i, j) = (distantBlobTrack(B(i), T(j)) < thDistance))
	  {
	    AB(i)++;
	    AT(j)++;
	  }

      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      // Detect inactive tracks
      for (j=0; j<nTracks; j++)
      {
	unsigned int c = AT(j);

	if (c==0)
	{
	  //cout << "Inactive track: " << j << endl;

	  // Inactive track.
	  CvTrack *track = T(j);
	  track->inactive++;
	  track->label = 0;
	}
      }

      // Detect new tracks
      for (i=0; i<nBlobs; i++)
      {
	unsigned int c = AB(i);

	if (c==0)
	{
	  //cout << "Blob (new track): " << maxTrackID+1 << endl;
	  //cout << *B(i) << endl;

	  // New track.
	  maxTrackID++;
	  CvBlob *blob = B(i);
	  CvTrack *track = new CvTrack;
	  track->id = maxTrackID;
	  track->label = blob->label;
	  track->minx = blob->minx;
	  track->miny = blob->miny;
	  track->maxx = blob->maxx;
	  track->maxy = blob->maxy;
	  track->centroid = blob->centroid;
	  track->lifetime = 0;
	  track->active = 0;
	  track->inactive = 0;
	  tracks.insert(CvIDTrack(maxTrackID, track));
	}
      }

      // Clustering
      for (j=0; j<nTracks; j++)
      {
	unsigned int c = AT(j);

	if (c)
	{
	  list<CvTrack*> tt; tt.push_back(T(j));
	  list<CvBlob*> bb;

	  getClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);

	  // Select track
	  CvTrack *track;
	  unsigned int area = 0;
	  for (list<CvTrack*>::const_iterator it=tt.begin(); it!=tt.end(); ++it)
	  {
	    CvTrack *t = *it;

	    unsigned int a = (t->maxx-t->minx)*(t->maxy-t->miny);
	    if (a>area)
	    {
	      area = a;
	      track = t;
	    }
	  }

	  // Select blob
	  CvBlob *blob;
	  area = 0;
	  //cout << "Matching blobs: ";
	  for (list<CvBlob*>::const_iterator it=bb.begin(); it!=bb.end(); ++it)
	  {
	    CvBlob *b = *it;

	    //cout << b->label << " ";

	    if (b->area>area)
	    {
	      area = b->area;
	      blob = b;
	    }
	  }
	  //cout << endl;

	  // Update track
	  //cout << "Matching: track=" << track->id << ", blob=" << blob->label << endl;
	  track->label = blob->label;
	  track->centroid = blob->centroid;
	  track->minx = blob->minx;
	  track->miny = blob->miny;
	  track->maxx = blob->maxx;
	  track->maxy = blob->maxy;
	  if (track->inactive)
	    track->active = 0;
	  track->inactive = 0;

	  // Others to inactive
	  for (list<CvTrack*>::const_iterator it=tt.begin(); it!=tt.end(); ++it)
	  {
	    CvTrack *t = *it;

	    if (t!=track)
	    {
	      //cout << "Inactive: track=" << t->id << endl;
	      t->inactive++;
	      t->label = 0;
	    }
	  }
	}
      }
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      for (CvTracks::iterator jt=tracks.begin(); jt!=tracks.end();)
	if ((jt->second->inactive>=thInactive)||((jt->second->inactive)&&(thActive)&&(jt->second->active<thActive)))
	{
	  delete jt->second;
	  tracks.erase(jt++);
	}
	else
	{
	  jt->second->lifetime++;
	  if (!jt->second->inactive)
	    jt->second->active++;
	  ++jt;
	}
    }
    catch (...)
    {
      delete[] close;
      throw; // TODO: OpenCV style.
    }

    delete[] close;

    __CV_END__;
  }
Пример #2
0
void cvUpdateTracks(CvBlobs &b, CvTracks &t, const double thDistance, const unsigned int thInactive)
{
  CV_FUNCNAME("cvUpdateTracks");
  __BEGIN__;

  unsigned int nBlobs = b.size();
  unsigned int nTracks = t.size();

  // Proximity matrix:
  // Last row/column is for ID/label.
  // Last-1 "/" is for accumulation.
  CvID *close = new unsigned int[(nBlobs+2)*(nTracks+2)]; // XXX Must be same type than CvLabel.

  // Access to matrix
#define C(blob, track) close[((blob) + (track)*(nBlobs+2))]
  // Access to accumulators
#define AB(label) C((label), (nTracks))
#define AT(id) C((nBlobs), (id))
  // Access to identifications
#define IB(label) C((label), (nTracks)+1)
#define IT(id) C((nBlobs)+1, (id))
  // Access to registers
#define B(label) b[IB(label)]
#define T(id) t[IT(id)]

  try
  {
    // Inicialization:
    unsigned int i=0;
    for (CvBlobs::const_iterator it = b.begin(); it!=b.end(); ++it, i++)
    {
      AB(i) = 0;
      IB(i) = it->second->label;
    }

    CvID maxTrackID = 0;

    unsigned int j=0;
    for (CvTracks::const_iterator jt = t.begin(); jt!=t.end(); ++jt, j++)
    {
      AT(j) = 0;
      IT(j) = jt->second->id;
      if (jt->second->id > maxTrackID)
	maxTrackID = jt->second->id;
    }

    // Proximity matrix calculation:
    for (i=0; i<nBlobs; i++)
      for (j=0; j<nTracks; j++)
      {
	if (C(i, j) = (distantBlobTrack(B(i), T(j)) < thDistance))
	{
	  AB(i)++;
	  AT(j)++;
	}
      }

    // Run over tracks:
    for (j=0; j<nTracks; j++)
    {
      //unsigned int c = C(nBlobs, j);
      unsigned int c = AT(j);

      if (c == 1)
      {
	// Match track-blob
	
	// Search for the blob
	for (i=0; (i<nBlobs)&&(!C(i, j)); i++) {}

	// Update track
	CvBlob *blob = B(i);
	CvTrack *track = T(j);
	track->label = blob->label;
	track->centroid = blob->centroid;
	track->minx = blob->minx;
	track->miny = blob->miny;
	track->maxx = blob->maxx;
	track->maxy = blob->maxy;
	track->inactive = 0;
      }
      else if (c > 1)
      {
	// Track divides
	CvTrack *track = T(j);
	track->inactive++;
	track->label=0;

	// Create new tracks
	for (i=0; i<nBlobs; i++)
	{
	  if (C(i, j))
	  {
	    maxTrackID++;
	    CvBlob *blob = B(i);
	    CvTrack *track = new CvTrack;
	    track->id = maxTrackID;
	    track->label = blob->label;
	    track->minx = blob->minx;
	    track->miny = blob->miny;
	    track->maxx = blob->maxx;
	    track->maxy = blob->maxy;
	    track->centroid = blob->centroid;
	    track->inactive = 0;
	    t.insert(CvIDTrack(maxTrackID, track));
	  }
	}
      }
      else // if (c == 0)
      {
	// Inactive track
	CvTrack *track = T(j);
	track->inactive++;
	track->label = 0;
      }
    }

    // Run over blobs:
    for (i=0; i<nBlobs; i++)
    {
      //unsigned int c = C(i, nTracks);
      unsigned int c = AB(i);

      if (c == 0)
      {
	// New track
	maxTrackID++;
	CvBlob *blob = B(i);
	CvTrack *track = new CvTrack;
	track->id = maxTrackID;
	track->label = blob->label;
	track->minx = blob->minx;
	track->miny = blob->miny;
	track->maxx = blob->maxx;
	track->maxy = blob->maxy;
	track->centroid = blob->centroid;
	track->inactive = 0;
	t.insert(CvIDTrack(maxTrackID, track));
      }
      else if (c > 1)
      {
	// Tracks joins
	
	// New track
	maxTrackID++;
	CvBlob *blob = B(i);
	CvTrack *track = new CvTrack;
	track->id = maxTrackID;
	track->label = blob->label;
	track->minx = blob->minx;
	track->miny = blob->miny;
	track->maxx = blob->maxx;
	track->maxy = blob->maxy;
	track->centroid = blob->centroid;
	track->inactive = 0;
	t.insert(CvIDTrack(maxTrackID, track));
	
	// Others tracks inactives
	for (j=0; j<nTracks; j++)
	{
	  T(j)->inactive++;
	  T(j)->label = 0;
	}
      }
    }

    for (CvTracks::iterator jt=t.begin(); jt!=t.end();)
      if (jt->second->inactive>=thInactive)
      {
	delete jt->second;
	t.erase(jt++);
      }
      else
	++jt;
  }
  catch (...)
  {
    delete[] close;
    throw; // TODO: OpenCV style.
  }

  delete[] close;

  __END__;
}