示例#1
0
 /// <summary>
 /// Updates list of tracks based on current blobs.
 /// </summary>
 /// <param name="blobs">List of blobs.</param>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="thDistance">Max distance to determine when a track and a blob match.</param>
 /// <param name="thInactive">Max number of frames a track can be inactive.</param>
 /// <param name="thActive">If a track becomes inactive but it has been active less than thActive frames, the track will be deleted.</param>
 /// <remarks>
 /// Tracking based on:
 /// A. Senior, A. Hampapur, Y-L Tian, L. Brown, S. Pankanti, R. Bolle. Appearance Models for
 /// Occlusion Handling. Second International workshop on Performance Evaluation of Tracking and
 /// Surveillance Systems &amp; CVPR'01. December, 2001.
 /// (http://www.research.ibm.com/peoplevision/PETS2001.pdf)
 /// </remarks>
 public static void UpdateTracks(CvBlobs blobs, CvTracks tracks, double thDistance, int thInactive, int thActive)
 {
     if (blobs == null)
     {
         throw new ArgumentNullException("blobs");
     }
     blobs.UpdateTracks(tracks, thDistance, thInactive, thActive);
 }
示例#2
0
 /// <summary>
 /// Prints tracks information.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="imgSource">Input image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="imgDest">Output image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="mode">Render mode. By default is CV_TRACK_RENDER_ID.</param>
 public static void RenderTracks(CvTracks tracks, Mat imgSource, Mat imgDest, RenderTracksMode mode)
 {
     if (tracks == null)
     {
         throw new ArgumentNullException(nameof(tracks));
     }
     tracks.Render(imgSource, imgDest, mode);
 }
示例#3
0
 /// <summary>
 /// Prints tracks information.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="imgSource">Input image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="imgDest">Output image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="mode">Render mode. By default is CV_TRACK_RENDER_ID.</param>
 /// <param name="font">OpenCV font for print on the image.</param>
 public static void RenderTracks(CvTracks tracks, IplImage imgSource, IplImage imgDest, RenderTracksMode mode, CvFont font)
 {
     if (tracks == null)
     {
         throw new ArgumentNullException("tracks");
     }
     tracks.Render(imgSource, imgDest, mode, font);
 }
示例#4
0
 /// <summary>
 /// Prints tracks information.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="imgSource">Input image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="imgDest">Output image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 public static void RenderTracks(CvTracks tracks, Mat imgSource, Mat imgDest)
 {
     if (tracks == null)
     {
         throw new ArgumentNullException("tracks");
     }
     tracks.Render(imgSource, imgDest);
 }
示例#5
0
 /// <summary>
 /// Prints tracks information.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="imgSource">Input image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="imgDest">Output image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 public static void RenderTracks(CvTracks tracks, IplImage imgSource, IplImage imgDest)
 {
     if (tracks == null)
     {
         throw new ArgumentNullException(nameof(tracks));
     }
     tracks.Render(imgSource, imgDest);
 }
示例#6
0
 /// <summary>
 /// Prints tracks information.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="imgSource">Input image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="imgDest">Output image (depth=IPL_DEPTH_8U and num. channels=3).</param>
 /// <param name="mode">Render mode. By default is CV_TRACK_RENDER_ID.</param>
 /// <param name="textColor"></param>
 /// <param name="fontFace"></param>
 /// <param name="fontScale"></param>
 /// <param name="thickness"></param>
 public static void RenderTracks(CvTracks tracks, Mat imgSource, Mat imgDest, RenderTracksMode mode,
                                 Scalar textColor, HersheyFonts fontFace = HersheyFonts.HersheySimplex, double fontScale = 1d, int thickness = 1)
 {
     if (tracks == null)
     {
         throw new ArgumentNullException(nameof(tracks));
     }
     tracks.Render(imgSource, imgDest, mode, textColor, fontFace, fontScale, thickness);
 }
示例#7
0
        private static void GetClusterForTrack(int trackPos, ProximityMatrix close,
                                               int nBlobs, int nTracks, CvBlobs blobs,
                                               CvTracks tracks, List <CvBlob> bb, List <CvTrack> tt)
        {
            for (int i = 0; i < nBlobs; i++)
            {
                if (close[i, trackPos] != 0)
                {
                    bb.Add(blobs[i]);

                    int c = close.AB[i];

                    close[i, trackPos] = 0;
                    close.AB[i]--;
                    close.AT[trackPos]--;

                    if (c > 1)
                    {
                        GetClusterForBlob(i, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                    }
                }
            }
        }
示例#8
0
        private static void GetClusterForTrack(int trackPos, ProximityMatrix close,
                                               int nBlobs, int nTracks, CvBlobs blobs,
                                               CvTracks tracks, List <CvBlob> bb, List <CvTrack> tt)
        {
retry:
            var retryList = new List <int>();

            for (int i = 0; i < nBlobs; i++)
            {
                if (close[i, trackPos] != 0)
                {
                    int ib = close.IB[i];
                    bb.Add(blobs[ib]);

                    int c = close.AB[i];

                    close[i, trackPos] = 0;
                    close.AB[i]--;
                    close.AT[trackPos]--;

                    if (c > 1)
                    {
                        retryList.Add(i);
                        //GetClusterForBlob(i, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                    }
                }
            }

            if (retryList.Count > 0)
            {
                foreach (int i in retryList)
                {
                    GetClusterForBlob(i, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                }
                goto retry;
            }
        }
示例#9
0
        private static void GetClusterForBlob(int blobPos, ProximityMatrix close,
                                              int nBlobs, int nTracks, CvBlobs blobs, CvTracks tracks,
                                              List <CvBlob> bb, List <CvTrack> tt)
        {
            for (int j = 0; j < nTracks; j++)
            {
                if (close[blobPos, j] != 0)
                {
                    tt.Add(tracks[j]);

                    int c = close.AT[j];

                    close[blobPos, j] = 0;
                    close.AB[blobPos]--;
                    close.AT[j]--;

                    if (c > 1)
                    {
                        GetClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                    }
                }
            }
        }
示例#10
0
        /// <summary>
        /// Updates list of tracks based on current blobs.
        /// </summary>
        /// <param name="tracks">List of tracks.</param>
        /// <param name="thDistance">Max distance to determine when a track and a blob match.</param>
        /// <param name="thInactive">Max number of frames a track can be inactive.</param>
        /// <param name="thActive">If a track becomes inactive but it has been active less than thActive frames, the track will be deleted.</param>
        /// <remarks>
        /// Tracking based on:
        /// A. Senior, A. Hampapur, Y-L Tian, L. Brown, S. Pankanti, R. Bolle. Appearance Models for
        /// Occlusion Handling. Second International workshop on Performance Evaluation of Tracking and
        /// Surveillance Systems &amp; CVPR'01. December, 2001.
        /// (http://www.research.ibm.com/peoplevision/PETS2001.pdf)
        /// </remarks>
        public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive, int thActive)
        {
            if (tracks == null)
            {
                throw new ArgumentNullException("tracks");
            }

            int nBlobs  = this.Count;
            int nTracks = tracks.Count;

            if (nBlobs == 0)
            {
                return;
            }

            // Proximity matrix:
            // Last row/column is for ID/label.
            // Last-1 "/" is for accumulation.
            ProximityMatrix close = new ProximityMatrix(nBlobs, nTracks);

            // Initialization:
            int i = 0;

            foreach (CvBlob blob in Values)
            {
                close.AB[i] = 0;
                close.IB[i] = blob.Label;
                i++;
            }

            int maxTrackID = 0;
            int j          = 0;

            foreach (CvTrack track in tracks.Values)
            {
                close.AT[j] = 0;
                close.AT[j] = track.Id;
                if (track.Id > maxTrackID)
                {
                    maxTrackID = track.Id;
                }
                j++;
            }

            // Proximity matrix calculation and "used blob" list inicialization:
            for (i = 0; i < nBlobs; i++)
            {
                for (j = 0; j < nTracks; j++)
                {
                    CvBlob  b = this[close.IB[i]];
                    CvTrack t = tracks[close.IT[j]];
                    close[i, j] = (DistantBlobTrack(b, t) < thDistance) ? 1 : 0;
                    if (close[i, j] < thDistance)
                    {
                        close.AB[i]++;
                        close.AT[j]++;
                    }
                }
            }

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Detect inactive tracks
            for (j = 0; j < nTracks; j++)
            {
                int c = close[nBlobs, j];
                if (c == 0)
                {
                    //cout << "Inactive track: " << j << endl;

                    // Inactive track.
                    CvTrack track = tracks[j];
                    track.Inactive++;
                    track.Label = 0;
                }
            }

            // Detect new tracks
            for (i = 0; i < nBlobs; i++)
            {
                int c = close.AB[i];
                if (c == 0)
                {
                    //cout << "Blob (new track): " << maxTrackID+1 << endl;
                    //cout << *B(i) << endl;

                    // New track.
                    maxTrackID++;
                    CvBlob  blob  = this[i + 1];
                    CvTrack track = new CvTrack
                    {
                        Id       = maxTrackID,
                        Label    = blob.Label,
                        MinX     = blob.MinX,
                        MinY     = blob.MinY,
                        MaxX     = blob.MaxX,
                        MaxY     = blob.MaxY,
                        Centroid = blob.Centroid,
                        LifeTime = 0,
                        Active   = 0,
                        Inactive = 0,
                    };
                    tracks[maxTrackID] = track;
                }
            }

            // Clustering
            for (j = 0; j < nTracks; j++)
            {
                int c = close.AT[j];
                if (c != 0)
                {
                    List <CvTrack> tt = new List <CvTrack> {
                        tracks[j]
                    };
                    List <CvBlob> bb = new List <CvBlob>();

                    GetClusterForTrack(j, close, nBlobs, nTracks, this, tracks, bb, tt);

                    // Select track
                    CvTrack track = null;
                    int     area  = 0;
                    foreach (CvTrack t in tt)
                    {
                        int a = (t.MaxX - t.MinX) * (t.MaxY - t.MinY);
                        if (a > area)
                        {
                            area  = a;
                            track = t;
                        }
                    }

                    // Select blob
                    CvBlob blob = null;
                    area = 0;
                    foreach (CvBlob b in Values)
                    {
                        if (b.Area > area)
                        {
                            area = b.Area;
                            blob = b;
                        }
                    }

                    if (blob == null || track == null)
                    {
                        throw new NotSupportedException();
                    }

                    // Update track
                    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 != 0)
                    {
                        track.Active = 0;
                    }
                    track.Inactive = 0;

                    // Others to inactive
                    foreach (CvTrack t in tt)
                    {
                        if (t != track)
                        {
                            //cout << "Inactive: track=" << t->id << endl;
                            t.Inactive++;
                            t.Label = 0;
                        }
                    }
                }
            }
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            int[] trackKeys = new int[tracks.Count];
            tracks.Keys.CopyTo(trackKeys, 0);
            foreach (int tkey in trackKeys)
            {
                CvTrack t = tracks[tkey];
                if ((t.Inactive >= thInactive) ||
                    ((t.Inactive != 0) && (thActive != 0) && (t.Active < thActive)))
                {
                    tracks.Remove(tkey);
                }
                else
                {
                    t.LifeTime++;
                    if (t.Inactive == 0)
                    {
                        t.Active++;
                    }
                }
            }
        }
示例#11
0
 /// <summary>
 /// Updates list of tracks based on current blobs.
 /// </summary>
 /// <param name="tracks">List of tracks.</param>
 /// <param name="thDistance">Max distance to determine when a track and a blob match.</param>
 /// <param name="thInactive">Max number of frames a track can be inactive.</param>
 /// <remarks>
 /// Tracking based on:
 /// A. Senior, A. Hampapur, Y-L Tian, L. Brown, S. Pankanti, R. Bolle. Appearance Models for
 /// Occlusion Handling. Second International workshop on Performance Evaluation of Tracking and
 /// Surveillance Systems &amp; CVPR'01. December, 2001.
 /// (http://www.research.ibm.com/peoplevision/PETS2001.pdf)
 /// </remarks>
 public void UpdateTracks(CvTracks tracks, double thDistance, int thInactive)
 {
     UpdateTracks(tracks, thDistance, thInactive, 0);
 }
示例#12
0
        private static void GetClusterForBlob(int blobPos, ProximityMatrix close,
                                              int nBlobs, int nTracks, CvBlobs blobs, CvTracks tracks,
                                              List <CvBlob> bb, List <CvTrack> tt)
        {
retry:
            var retryList = new List <int>();

            for (int j = 0; j < nTracks; j++)
            {
                if (close[blobPos, j] != 0)
                {
                    int it = close.IT[j];
                    tt.Add(tracks[it]);

                    int c = close.AT[j];

                    close[blobPos, j] = 0;
                    close.AB[blobPos]--;
                    close.AT[j]--;

                    if (c > 1)
                    {
                        retryList.Add(j);
                        //GetClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                    }
                }
            }

            if (retryList.Count > 0)
            {
                foreach (int j in retryList)
                {
                    GetClusterForTrack(j, close, nBlobs, nTracks, blobs, tracks, bb, tt);
                }
                goto retry;
            }
        }