0

我正在使用 OCR 开发 C# WPF 自动车牌识别。

流程是,我正在从视频流 MJPEG 中获取图片,并且应该将这些图片传递给 OCR 以获取车牌号和其他详细信息。

问题是:视频流产生大约 30 帧/秒,CPU 无法处理这么多的处理,处理 1 帧也需要大约 1 秒,而且当我在队列上获得很多帧时,CPU 会已使用 70%(Intel I7 4th G)。

任何人都可以提出解决方案和更好的实施方案。

//This is the queue where it will hold the frames 
        // produced from the video streaming(video_Newfram1)

        private readonly Queue<byte[]> _anpr1Produces = new Queue<byte[]>();


        //I am using AForg.Video to read the MJPEG Streaming
        //this event will be triggered for every frame
        private void video_NewFrame1(object sender, NewFrameEventArgs eventArgs)
        {

            var frameDataAnpr = new Bitmap(eventArgs.Frame);
            AnprCam1.Source = GetBitmapimage(frameDataAnpr);

            //add current fram to the queue 
            _anpr1Produces.Enqueue(imgByteAnpr);

            //this worker is the consumer that will 
            //take the frames from the queue to the OCR processing 
            if (!_workerAnpr1.IsBusy)
            {
                _workerAnpr1.RunWorkerAsync(imgByteAnpr);
            }
        }

        //This is the consumer, it will take the frames from the queue to the OCR

        private void WorkerAnpr1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                if (_anpr1Produces.Count <= 0) continue;
                BgWorker1(_anpr1Produces.Dequeue());
            }
        }

        //This method will process the frames that sent from the consumer
        private void BgWorker1(byte[] imageByteAnpr)
        {
            var anpr = new cmAnpr("default");
            var objgxImage = new gxImage("default");

            if (imageByteAnpr != null)
            {
                objgxImage.LoadFromMem(imageByteAnpr, 1);
                if (anpr.FindFirst(objgxImage) && anpr.GetConfidence() >= Configs.ConfidanceLevel)
                {
                    var vehicleNumber = anpr.GetText();
                    var vehicleType = anpr.GetType().ToString();
                    if (vehicleType == "0") return;

                    var imagename = string.Format("{0:yyyy_MMM_dd_HHmmssfff}", currentDateTime) + "-1-" +
                                    vehicleNumber + ".png";

                    //this task will run async to do the rest of the process which is saving the vehicle image, getting vehicle color, storing to the database ... etc
                    var tsk = ProcessVehicle("1", vehicleType, vehicleNumber, imageByteAnpr, imagename, currentDateTime, anpr, _anpr1Produces);

                }
                else
                {
                    GC.Collect();
                }
            }
        }
4

1 回答 1

1

你应该做的是:

首先,确定一个帧是否值得处理。如果您使用的是压缩视频流,通常可以快速读取帧的压缩大小。它存储当前帧与前一帧之间的差异。

当它很小时,变化不大(即:没有汽车开过)。

这是一种进行运动检测的低技术方法,甚至无需解码帧,而且速度应该非常快。

这样,您可能会决定在几毫秒内跳过 80% 的帧。

偶尔你会得到需要处理的帧。确保您可以缓冲足够的帧,以便在进行缓慢处理时可以继续录制。

接下来要做的是找到一个感兴趣的区域,并首先关注那些。您可以通过简单地查看颜色发生变化的区域来做到这一点,或者尝试找到矩形。

最后,如果您需要处理 30 fps,则一秒钟的处理速度很慢。你需要让事情变得更快,或者你必须建立一个巨大的缓冲区,并希望你能在路上很忙时赶上。

如果多个内核可用,请确保正确使用它们,但最后,知道图像的哪些部分不相关是提高性能的关键。

于 2017-02-20T02:34:40.493 回答