public void EmguCvCaptureVideoStream(string url, Action <Emgu.CV.Mat> action) { using Emgu.CV.VideoCapture capture = new Emgu.CV.VideoCapture(url, Emgu.CV.VideoCapture.API.Any); if (capture.IsOpened == false) { return; } using Emgu.CV.Mat frame = capture.QueryFrame(); while (_stopPlay == false) { if (capture.Read(frame)) //capture.Retrieve(frame)// 无法继续读取 { if (!frame.IsEmpty) { action?.Invoke(frame); } } } frame.Dispose(); capture.Dispose(); }
public async void start() { if (didStart) { return; } if (this.CarDidEnter == null) { CarDidEnter = CarDidEnterDefault; } if (this.CarDidLeave == null) { CarDidLeave = CarDidLeaveDefault; } if (this.CarProcessingDone == null) { CarProcessingDone = CarProcessingDoneDefault; } //flag to note process started to prevent changing peramaters that would break the processing didStart = true; //sets up the image matrixs for the input raw and output processed Emgu.CV.Mat iMatrix = new Emgu.CV.Mat(); Emgu.CV.Mat oMatrix = new Emgu.CV.Mat(); await Task.Run(() => { //creates a window if desired, window for testing purposes if (showWindow) { Emgu.CV.CvInvoke.NamedWindow("Car Detection Test", Emgu.CV.CvEnum.NamedWindowType.FreeRatio); } //This async task continually pulls the video frame to be processed. Task.Run(() => { for (; ;) { try { if (didStop) { return; } vCapture.Read(iMatrix); if (iMatrix == null) { iMatrix.Dispose(); iMatrix = null; return; } if (iMatrix.IsEmpty) { iMatrix.Dispose(); iMatrix = null; return; } //System.Console.Out.WriteLine(iMatrix.Size.ToString()); // Emgu.CV.CvInvoke.WaitKey((int)(1000/(fps))); //double FrameRate = vCapture.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps); //System.Diagnostics.Debug.WriteLine(FrameRate); if (fps > 0) { Thread.Sleep((int)(1000.0 / fps)); } } catch (Exception e) { return; } } }); //This async task continually process the pulled frames for (; ;) { try { //If the matrix used to store the frames is not empty if (iMatrix == null) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } if (!iMatrix.IsEmpty) { didEnter = true; if (didStop) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } //Converts the contents of the imatrix to greyscale, export results to omatrix //this is to ensure proper processing Emgu.CV.CvInvoke.CvtColor(iMatrix, oMatrix, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray); //Uses the cascade xml file provided in the initalizer to draw rectangles arround possible canditates. Rectangle[] rects = casc.DetectMultiScale(oMatrix, 1.01, 5, new Size(700, 700), new Size(1100, 1100)); //removes the image from the out matrix if one exists to make room for the new one. if (oMatrix == null) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } if (oMatrix.IsEmpty) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } for (int i = 0; i < oMatrix.Total.ToInt32(); i++) { oMatrix.PopBack(1); } //sets inital value to zero int carsInFrame = 0; //loops through all of the rectangles in the discorvered object array foreach (Rectangle rect in rects) { //draws the rectangles on the imatrix image for display if we wish to show the window //we use imatrix as it is in color if (showWindow) { var x = rect.X; var y = rect.Y; var w = rect.Width; var h = rect.Height; Emgu.CV.CvInvoke.Rectangle(iMatrix, new Rectangle(x, y, w, h), new Emgu.CV.Structure.MCvScalar(50)); } //increase the number of cars in frame for each iteration carsInFrame++; } if (carsInFrame == numCarsInLot) { steady++; } else { steady = 0; } //update the number of cars numCarsInLot = carsInFrame; //if the number of cars has changed //call the proper delagte the necessary amount of times if (carsInFrame > oldNumCarsInLot && steady > 20) { for (int i = 0; i < carsInFrame - oldNumCarsInLot; i++) { dispatcher.Invoke(CarDidEnter, this); } oldNumCarsInLot = numCarsInLot; } if (carsInFrame < oldNumCarsInLot && steady > 20) { for (int i = 0; i < oldNumCarsInLot - carsInFrame; i++) { dispatcher.Invoke(CarDidLeave, this); } oldNumCarsInLot = numCarsInLot; } //if the show window flag is true we push the drawn images to the window if (showWindow) { if (iMatrix == null) { oMatrix.Dispose();; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } if (iMatrix.IsEmpty) { oMatrix.Dispose();; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } Emgu.CV.CvInvoke.Imshow("Car Detection Test", iMatrix); } //discard the now rendered frame if (iMatrix == null) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } if (iMatrix.IsEmpty) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } iMatrix.PopBack(1); //Distroys windows and stops loop if the escape key is pressed if (showWindow && Emgu.CV.CvInvoke.WaitKey(33) == 27) { if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } break; } if (didStop) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } } else if (didEnter) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } } catch (Exception e) { oMatrix.Dispose(); oMatrix = null; dispatcher.Invoke(CarProcessingDone, this); if (showWindow) { Emgu.CV.CvInvoke.DestroyAllWindows(); } return; } } }); }