Beispiel #1
0
        public void FindObject_1stTracking()
        {
            // arrange - instantiate tracker
            InstantiateTracker();

            // arrange - load new/current frame
            Image <Gray, byte> currentFrame = new Image <Gray, byte>
                                              (
                Path.Combine(_resourceDir, "violeta_6.jpg")
                                              );

            // define expected - status and new/current bounding box
            MedianFlowTrackerStatus expectedStatus = MedianFlowTrackerStatus.OK;
            IBoundingBox            expectedBB     = new BoundingBox
                                                     (
                new PointF(100, 89),
                new SizeF(70, 40)
                                                     );

            // get actual
            IBoundingBox            actualBB     = _tracker.FindObject(currentFrame);
            MedianFlowTrackerStatus actualStatus = _tracker.Status;

            // assert
            Assert.AreEqual(expectedStatus, actualStatus);
            float overlap = actualBB.GetOverlap(expectedBB);

            Assert.AreEqual(0.95f, overlap, 0.05f);
        }
Beispiel #2
0
        public void FindObject_2ndTracking()
        {
            // arrange - instantiate tracker
            InstantiateTracker();

            // arrange - track for the first time
            Image <Gray, byte> currentFrame1 = new Image <Gray, byte>
                                               (
                Path.Combine(_resourceDir, "violeta_6.jpg")
                                               );

            _tracker.FindObject(currentFrame1);

            // arrange - prepare new/current frame for tracking the second time
            Image <Gray, byte> currentFrame2 = new Image <Gray, byte>
                                               (
                Path.Combine(_resourceDir, "violeta_7.jpg")
                                               );

            // define expected - status and new/current bounding box
            MedianFlowTrackerStatus expectedStatus = MedianFlowTrackerStatus.OK;
            float        expectedNccMedian         = 0.9f;
            IBoundingBox expectedBB = new BoundingBox
                                      (
                new PointF(111, 101),
                new SizeF(70, 40)
                                      );

            // get actual
            IBoundingBox            actualBB     = _tracker.FindObject(currentFrame2);
            MedianFlowTrackerStatus actualStatus = _tracker.Status;
            float actualNccMedian = _tracker.NccMedian;

            // assert
            Assert.AreEqual(expectedStatus, actualStatus);
            Assert.AreEqual(expectedNccMedian, actualNccMedian, 0.1f);
            float overlap = actualBB.GetOverlap(expectedBB);

            Assert.AreEqual(0.95f, overlap, 0.05f);
        }
Beispiel #3
0
        private void CalculateStatistics(VideoFile video)
        {
            // calculate true/false positives/negatives
            int truePositives  = 0;
            int falsePositives = 0;
            int trueNegatives  = 0;
            int falseNegatives = 0;

            for (int i = 1; i < video.FrameCount; i++)
            {
                IBoundingBox groundTruth = video.GroundTruth[i];
                IBoundingBox tldOutput   = video.TldOutputs[i];

                // object is visible
                if (groundTruth != null)
                {
                    // TLD found the object
                    if (tldOutput != null)
                    {
                        // object that TLD found is very close to ground truth
                        if (tldOutput.GetOverlap(groundTruth) > Utils.NudGetValueFloat(_nudRequiredOverlap))
                        {
                            truePositives++;
                        }
                        else
                        {
                            falsePositives++;
                            falseNegatives++;
                        }
                    }
                    // TLD didn't find the object
                    else
                    {
                        falseNegatives++;
                    }
                }

                // object is not visible
                else
                {
                    // TLD found the object
                    if (tldOutput != null)
                    {
                        falsePositives++;
                    }
                    // TLD didn't find the object
                    else
                    {
                        trueNegatives++;
                    }
                }
            }

            // display true/false positives/negatives
            _lblTruePositives.Text  = truePositives.ToString();
            _lblFalsePositives.Text = falsePositives.ToString();
            _lblTrueNegatives.Text  = trueNegatives.ToString();
            _lblFalseNegatives.Text = falseNegatives.ToString();

            // calculate precision and recall
            float precision = (float)truePositives / (truePositives + falsePositives);
            float recall    = (float)truePositives / (truePositives + falseNegatives);

            // display precision and recall
            _lblPrecision.Text = precision.ToString();
            _lblRecall.Text    = recall.ToString();
        }
Beispiel #4
0
        public void TrainDetector(Image <Gray, byte> currentFrame, IBoundingBox currentBb, out bool valid)
        {
            // if patch is outside the image
            if (!currentBb.InsideFrame(currentFrame.Size))
            {
                valid = false;
                return;
            }

            // get normalized image patch
            currentFrame.ROI = Rectangle.Round(currentBb.GetRectangle());
            Image <Gray, byte> currentPatch = currentFrame.Resize(_objectModel.PatchSize.Width, _objectModel.PatchSize.Height, INTER.CV_INTER_LINEAR);

            currentFrame.ROI = Rectangle.Empty;

            // if appearance changed too fast
            float pnnSimilarity, nnnSimilarity;

            if (_objectModel.RelativeSimilarity(currentPatch, out pnnSimilarity, out nnnSimilarity) < 0.5f)
            {
                valid = false;
                return;
            }
            if (nnnSimilarity > _sameSimilarityThreshold)
            {
                valid = false;
                return;
            }

            #region ensemble classifier

            // generate positive patches
            List <Image <Gray, byte> > positivePatchesForEnsemble = GeneratePatches(
                _ensembleClassifier.SmoothFrame,
                currentBb,
                _runtimePosPatchSynthesisInfo.EnsembleCount,
                _runtimePosPatchSynthesisInfo.WarpInfo,
                0,
                Size.Empty
                );

            // pick negative patches
            List <IBoundingBox> allEnsembleNegativeBbs = new List <IBoundingBox>();
            foreach (KeyValuePair <IBoundingBox, double> pair in _ensembleClassifier.PositivePosteriors)
            {
                IBoundingBox bb = pair.Key;
                if (bb.GetOverlap(currentBb) < _runtimeNegativePatchPickingInfo.Overlap)
                {
                    allEnsembleNegativeBbs.Add(bb);
                }
            }

            List <Image <Gray, byte> > negativePatchesForEnsemble = PickBoundingBoxesAndGeneratePatches(
                _ensembleClassifier.SmoothFrame,
                allEnsembleNegativeBbs,
                _runtimeNegativePatchPickingInfo.EnsembleCount,
                Size.Empty
                );

            // train ensemble classifier
            int bootstrap = 1;
            for (int i = 0; i < bootstrap; i++)
            {
                _ensembleClassifier.TrainWithUnseenPatches(positivePatchesForEnsemble, negativePatchesForEnsemble);
            }

            #endregion

            #region nn classifier

            // generate positive patches
            List <Image <Gray, byte> > positivePatchesForNn = GeneratePatches(
                currentFrame,
                currentBb,
                _runtimePosPatchSynthesisInfo.NnCount,
                _runtimePosPatchSynthesisInfo.WarpInfo,
                _runtimePosPatchSynthesisInfo.GaussianSigma,
                _objectModel.PatchSize
                );

            int width  = _objectModel.PatchSize.Width;
            int height = _objectModel.PatchSize.Height;
            for (int i = 0; i < positivePatchesForNn.Count; i++)
            {
                positivePatchesForNn[i] = positivePatchesForNn[i].Resize(width, height, INTER.CV_INTER_LINEAR);
            }

            /*
             * // pick negative patches
             * List<IBoundingBox> allNegativeNnBbs = new List<IBoundingBox>();
             * IBoundingBox[] allBoundingBoxes = _nnClassifier.ScanningWindowGenerator.ScanningWindows;
             * List<int> nnAcceptedPatches = _nnClassifier.AcceptedPatches;
             * int nnAcceptedPatchesCount = nnAcceptedPatches.Count;
             *
             * for (int i = 0; i < nnAcceptedPatchesCount; i++)
             * {
             *  int windowIndex = nnAcceptedPatches[i];
             *  IBoundingBox bb = allBoundingBoxes[windowIndex];
             *  if (bb.GetOverlap(currentBb) < _runtimeNegativePatchPickingInfo.Overlap)
             *  {
             *      allNegativeNnBbs.Add(bb);
             *  }
             * }
             *
             * List<Image<Gray, byte>> negativePatchesForNn = PickBoundingBoxesAndGeneratePatches(
             *  currentFrame,
             *  allNegativeNnBbs,
             *  _runtimeNegativePatchPickingInfo.NnCount,
             *  _objectModel.PatchSize
             * );
             */

            List <Image <Gray, byte> > negativePatchesForNn = PickFromList <Image <Gray, byte> >(negativePatchesForEnsemble, _runtimeNegativePatchPickingInfo.NnCount);
            for (int i = 0; i < negativePatchesForNn.Count; i++)
            {
                negativePatchesForNn[i] = negativePatchesForNn[i].Resize(_objectModel.PatchSize.Width, ObjectModel.PatchSize.Height, INTER.CV_INTER_LINEAR);
            }

            // train nn classifier (update object model)
            TrainNnClassifier(positivePatchesForNn, negativePatchesForNn);

            #endregion

            valid = true;

            currentFrame.ROI = Rectangle.Empty;
        }
Beispiel #5
0
        public static List <IBoundingBox> NonMaximalBoundingBoxSuppress(List <IBoundingBox> boundingBoxes)
        {
            // initialize clustering
            int[] clustering = new int[boundingBoxes.Count];
            for (int i = 0; i < clustering.Length; i++)
            {
                clustering[i] = -1;
            }
            SortedList <int, int> clusters     = new SortedList <int, int>();
            HashSet <int>         deadClusters = new HashSet <int>();

            #region cluster bounding boxes

            for (int i = 0; i < boundingBoxes.Count; i++)
            {
                IBoundingBox bb1 = boundingBoxes[i];

                // find maximally overlapping bb among remaining bbs
                int   maxOverlapBb = -1;
                float maxOverlap   = 0.0f;
                for (int j = i + 1; j < boundingBoxes.Count; j++)
                {
                    float overlap = bb1.GetOverlap(boundingBoxes[j]);
                    if (overlap > maxOverlap)
                    {
                        maxOverlapBb = j;
                        maxOverlap   = overlap;
                    }
                }

                // if maximal overlap is big enough, merge bbs
                if (maxOverlap > 0.5f)
                {
                    if (clustering[i] == -1)
                    {
                        if (clustering[maxOverlapBb] == -1)
                        {
                            int cluster;
                            if (deadClusters.Count == 0)
                            {
                                cluster = clusters.Count;
                            }
                            else
                            {
                                cluster = deadClusters.Min();
                                deadClusters.Remove(cluster);
                            }
                            clustering[i]            = cluster;
                            clustering[maxOverlapBb] = cluster;
                            clusters.Add(cluster, cluster);
                        }
                        else
                        {
                            clustering[i] = clustering[maxOverlapBb];
                        }
                    }
                    else
                    {
                        if (clustering[maxOverlapBb] == -1)
                        {
                            clustering[maxOverlapBb] = clustering[i];
                        }
                        else
                        {
                            // merge clusters
                            int cluster     = clustering[i];
                            int deadCluster = clustering[maxOverlapBb];
                            for (int k = 0; k < clustering.Length; k++)
                            {
                                if (clustering[k] == deadCluster)
                                {
                                    clustering[k] = cluster;
                                }
                            }
                            clusters.Remove(deadCluster);
                            deadClusters.Add(deadCluster);
                        }
                    }
                }

                // if maximal overlap is not big enough
                else
                {
                    if (clustering[i] == -1)
                    {
                        int cluster;
                        if (deadClusters.Count == 0)
                        {
                            cluster = clusters.Count;
                        }
                        else
                        {
                            cluster = deadClusters.Min();
                            deadClusters.Remove(cluster);
                        }
                        clustering[i] = cluster;
                        clusters.Add(cluster, cluster);
                    }
                }
            }

            #endregion

            #region turn clustered bounding boxes into single bounding boxes

            List <IBoundingBox> singleBoundingBoxes = new List <IBoundingBox>();
            foreach (KeyValuePair <int, int> pair in clusters)
            {
                // extract cluster
                int i = pair.Value;
                List <IBoundingBox> cluster = new List <IBoundingBox>();
                for (int j = 0; j < clustering.Length; j++)
                {
                    if (clustering[j] == i)
                    {
                        cluster.Add(boundingBoxes[j]);
                    }
                }

                // average bounding boxes in the cluster
                float centerX      = 0;
                float centerY      = 0;
                float sizeWidth    = 0;
                float sizeHeight   = 0;
                int   clusterCount = cluster.Count;
                for (int k = 0; k < clusterCount; k++)
                {
                    centerX    += cluster[k].Center.X;
                    centerY    += cluster[k].Center.Y;
                    sizeWidth  += cluster[k].Size.Width;
                    sizeHeight += cluster[k].Size.Height;
                }
                PointF center = new PointF(centerX / clusterCount, centerY / clusterCount);
                SizeF  size   = new SizeF(sizeWidth / clusterCount, sizeHeight / clusterCount);

                singleBoundingBoxes.Add(cluster[0].CreateInstance(center, size));
            }

            #endregion

            return(singleBoundingBoxes);
        }