Различные проблемы при получении кадров с IP-камер

У меня 2 IP камеры разных моделей и от одного производителя. Назовем их Cam1 и Cam2. Я хочу получить кадры с этих камер по их сетевому адресу, но есть некоторые проблемы.

Камера 1:

При использовании frame = capture.RetrieveBgrFrame(); frame всегда null.

При использовании frame = capture.QueryFrame(); frame — это ОК.

Cam2(в одной сети с моим ПК):

При использовании frame = capture.RetrieveBgrFrame(); frame всегда null.

При использовании frame = capture.QueryFrame(); WinForm зависает и компьютер (i7 3,3GHz, 6GB RAM) зависает.

Оба адреса потока в порядке. Я пытался открыть их с помощью VLC, а также с платформой OpenCV C++.

В чем здесь может быть проблема?

Вот код:

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.UI;

namespace IPcamera
{
    public partial class Form1 : Form
    {
        private Capture capture;
        private Image<Bgr, Byte> frame;

        public Form1()
        {
            InitializeComponent();

            try
            {
                capture = new Capture(camera_address);
            }
            catch (NullReferenceException exception)
            {
                MessageBox.Show(exception.Message);
            }

            if (capture != null)
            {
                Application.Idle += ProcessFrame;
            }
        }

        void ProcessFrame(object sender, EventArgs e)
        {
            frame = capture.RetrieveBgrFrame();
            if (frame != null)
            {
                pictureBox1.Image = frame.ToBitmap();
            }
        }
    }
}

person OpenMinded    schedule 18.03.2014    source источник


Ответы (2)


Обычно я не работаю с IP-камерами, но подозреваю, что они не начинают снимать изображения при инициализации. RetrieveBgrFrame() возвращает las-изображение, снятое камерой, поэтому, если я прав, RetrieveBgrFrame() вернет null, потому что камера не снимает изображения сама по себе. Попробуйте добавить обработчик ProcessFrame в захват события камеры.ImageGrabbed вместо Application.Idle и проверьте, что он вообще вызывается.

Насчет зависания, если это зависание "низкий fps", это может быть из-за медленной камеры или из-за попытки отправить большие изображения по медленной шине. Если он зависает навсегда, убедитесь, что нет другого приложения, которое может использовать эту камеру, и что вы освобождаете ресурсы (вы пытаетесь использовать cam1 перед cam2 или пробуете cam2 в новом запуске?)

person Evans    schedule 18.03.2014
comment
Благодарю за ваш ответ. ImageGrabbed никогда не поднимается для обоих потоков. WinForm полностью зависает, а другие приложения реагируют с задержкой. - person OpenMinded; 19.03.2014
comment
И вы используете cam2 в чистом прогоне или используете cam1, а затем переключаетесь на cam2? - person Evans; 19.03.2014
comment
Нет переключения, только чистый ход - person OpenMinded; 20.03.2014

Не могли бы вы заменить

 Application.Idle += ProcessFrame;

с участием

 capture.ImageGrabbed += ProcessFrame;

И тогда метод RetrieveBgrFrame() может вернуть кадр. Я так обычно делаю и проблем не было. Возможно, вам придется назначить изображение для pictureBox1.Image с помощью вызова.

 pictureBox1.Invoke((MethodInvoker) (() => pictureBox1.Image = frame.ToBitmap()));
person Tomek    schedule 07.12.2017