Пример #1
0
        async Task <Video> Analyze(string path) => await Task.Run(() =>
        {
            try
            {
                BlobCountingObjectsProcessing processingAlgorithm = new BlobCountingObjectsProcessing()
                {
                    MinObjectsHeight = 35,
                    MinObjectsWidth  = 35
                };
                MotionDetector detector = new MotionDetector(new TwoFramesDifferenceDetector(), processingAlgorithm);

                VideoFileReader reader = new VideoFileReader();
                List <Segment> markers = new List <Segment>();

                reader.Open(path);      // Opens video file

                progressBar.Value = 0;
                Invoke(new Action(() => progressBar.Maximum = (int)(reader.FrameCount / reader.FrameRate - 1)));

                bool isMoving = false;
                Segment temp  = new Segment();

                //Algorythm
                for (int k = 1; k < (int)(reader.FrameCount / reader.FrameRate); k++) // Loop processes every second
                {
                    for (int step = 0; step < 2; step++)                              // Processes two halfs of the current second
                    {
                        detector.ProcessFrame(reader.ReadVideoFrame());               // Processes frame
                        for (int i = 1; i < (int)(reader.FrameRate / 2); i++)         // Skips other frames
                        {
                            reader.ReadVideoFrame();
                        }
                    }
                    GC.Collect();                                          // Releases memory

                    if (processingAlgorithm.ObjectsCount > 0 && !isMoving) // If there's any new moving object - creates new segment
                    {
                        isMoving   = true;
                        temp.Start = k - 1;
                    }
                    else if (processingAlgorithm.ObjectsCount == 0 && isMoving) // If there's both opened segment and no moving objects - closes segment
                    {
                        isMoving = false;
                        temp.End = k;
                        markers.Add(temp);
                        temp = new Segment();
                    }

                    Invoke(new Action(() =>     // Updates progress bar
                    {
                        progressBar.Value++;
                        percentage.Text = $"{Math.Round((float)progressBar.Value / progressBar.Maximum * 100)}%";
                    }));

                    cts.Token.ThrowIfCancellationRequested();
                }

                // Markers post-processing
                for (int k = 0; k < markers.Count; k++)
                {
                    if (markers[k].Duration < 3)     // Deletes segments if they last less than 3 seconds
                    {
                        markers.RemoveAt(k--);
                    }
                }

                for (int k = 1; k < markers.Count; k++)
                {
                    if (Segment.AbsoluteDistanceBetweenSegments(markers[k - 1], markers[k]) <= 5)
                    {
                        markers[k - 1].End = markers[k].End;     // Joins two segments if between them is less than 5 seconds
                        markers.RemoveAt(k--);
                    }
                }

                Video video = new Video()
                {
                    Path    = path,
                    Name    = new FileInfo(path).Name,
                    Markers = markers
                };

                // Writing data to disk
                File.WriteAllText(path + ".data", JsonConvert.SerializeObject(video));

                return(video);
            }
            catch (OperationCanceledException)
            {
                cts = new CancellationTokenSource();
                return(null);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, e.GetType().ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error);

                return(null);
            }
        });