Проблемы с видеообработчиком OpenCV и детектором Alturos.Yolo

В данный момент работаю над программой распознования блоков с использованием библиотеки OpenCV (в качестве видеообработчика с использованием класса VideoCapture) и библиотеки детектора Alturos.Yolo (Использующим веса Yolov3).

Во время разработки модумя видеосчитывания возникла проблема, связанная с утечками памяти (картинка 1) , которые я не могу определить (недостаток знаний/проблемы внутри библиотеки).

Так же проблемы происходят при самой детекции, метод Alturos.Yolo.Detect() занимает от 181мс до 525мс (картинка 2), что очень замедляет картинку на выходе. Вопросы в следующем:

1)В чем может быть причина утечки? (Код прилагаю, пытался переписывать архитектуру и проводить Dispose() свойства pictureBox.Image, это снижало утечку, но:

  • при изменении размера выдавало постоянно ошибку
  • при увеличении окна утечка продолжалась)

2)Почему альторус (при использовании GPU) съедает 2-3 гб при инициализации и при детекции занимает ресурс процессора на 200-525 мс? Это проблема библиотеки или я что-то делаю не так по архитектуре?

3)Насколько имеет уничтожать ресурсы picturebox с помощью Dispose()?

4)Есть ли возможность выводить сначала картинку с видеообработчика и параллельно в другом потоке вести обработку? И насколько это может, в теории, исправить ситуацию?

Вот код:

    //Flags
    private string _videoPath;

    //Video data
    private VideoCapture _capture;
    private Thread _altorusThread;
    private YoloWrapper _wrapper;
    private int _fps;
private void _startVideo_Click(object sender, EventArgs e)
{
    if(_videoPath != null)
    {
        #region LegacyThreadAltorus
        //Проверкан на существование потока с Altorus
        if (_altorusThread == null)
        {
            _altorusThread = new Thread(() =>
            {
                while (true)
                {
                    if (_videoBox.InvokeRequired)
                    {
                        MethodInvoker mi = new MethodInvoker(() =>
                        {
                            _videoBox.Image = DetectFrame(StartVideo(_videoPath));
                            /*_videoBox.Image = BitmapConverter.ToBitmap(StartVideo(_videoPath));*/
                        });
                        mi.Invoke();
                    }
                    Cv2.WaitKey(_fps);
                }
            })
            {
                IsBackground = true,
                Name = "Altorus Thread"
            };
        }
        if(_altorusThread.ThreadState == (ThreadState.Background | ThreadState.Suspended))
        {
            _altorusThread.Resume();
        }
        else if(_altorusThread.ThreadState == (ThreadState.Background | ThreadState.Unstarted))
        {
            _altorusThread.Start();
        }
        #endregion
    }
    else
    {
        MessageBox.Show("Видео еще не загружено!");
    };
}        

private Bitmap DetectFrame(Mat mat)
{
    //Конвертация и подготовка средств отрисовки
    Bitmap finalImage = BitmapConverter.ToBitmap(mat);

    Graphics graphics = Graphics.FromImage(finalImage);
    Font font = new Font("Consolas", 18, FontStyle.Bold);
    SolidBrush brush = new SolidBrush(Color.White);

    Pen pen = new Pen(Color.Aqua, 2);

    //Детекция и отрисовка
    try
    {
        List<YoloItem> items = _wrapper.Detect(mat.ToBytes()).ToList();

        foreach (YoloItem item in items)
        {
            Point rectPoint = new Point(item.X, item.Y);
            Size rectSize = new Size(item.Width, item.Height);

            Rectangle rect = new Rectangle(rectPoint, rectSize);

            graphics.DrawRectangle(pen, rect);

            graphics.DrawString(item.Type, font, brush, rectPoint);
        }
        items.Clear();
    }
    catch(Exception e)
    {
        MessageBox.Show($"Error Altorus: {e}");
    }
    return finalImage;
}



 private Mat StartVideo(string path)
{
    if(_capture == null)
    {
        if(path != null)
        {
            _capture = new VideoCapture(path);
            _fps = (int)(1000 / _capture.Fps);
        }
        else
        {
            MessageBox.Show("Вы не выбрали видео!");
        }
    }

    Mat mat = new Mat();

    _capture.Read(mat);

    if (!mat.Empty())
    {
       /*_videoBox.Image = BitmapConverter.ToBitmap(mat);*/
       /*_videoBox.Image = DetectFrame(mat);*/
       return mat;
    }
    else
    {
       MessageBox.Show("Что-то пошло не так с загрузкой видео");
       return null;
    }
}

Утечка памяти Большая задержка процесса (до 500 бывает)

UPD1: Добавил глобальные переменные

UPD2: Ссылка на проект: https://dropmefiles.com/HzA4a

UPD3: Проблема с обработкой видео решилась (Спасибо, aepot), но altorus.yolo все еще съедает большую часть процессорного времени


Ответы (0 шт):