Обработка видео с IP камеры

Простейшие вопросы в области инженерной разработки
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3709
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2021
Благодарил (а): 4 раза
Поблагодарили: 52 раза
Контактная информация:

Re: Обработка видео с IP камеры

Сообщение dadreamer »

lam писал(а): 13 окт 2021, 13:41решал проблему с помощью VLC плейера. Пока не уткнулся в загрузку процессора.
А можно на код взглянуть? Получение rtsp-потока через эти инструменты? У меня в одном из проектов было получение потока с шести видеокамер одновременно. VLC нормально справлялся.
lam
beginner
beginner
Сообщения: 11
Зарегистрирован: 23 сен 2021, 09:13
Версия LabVIEW: 2021
Контактная информация:

Re: Обработка видео с IP камеры

Сообщение lam »

Полностью использовал Ваше решение с "VLC Callback test (64-bit)".
Пока не могу понять, как подключить ещё камеры. Может подскажите.
Но поток с одной камеры с разрешением 640*480 и частотой кадров 20 fps., нагружает процессор I3 c 16 Gb ОЗУ на 24%.
Снижение частоты кадров, конечно, решает проблему. При 5 fps загрузка падает до 9-10%.
Но как будут обрабатываться параллельно несколько потоков? Плюс мне нужна потом еще обработка полученного сигнала. (правда только одного выбранного).
Пробовал вариант с помощью стороннего ПО увидеть IP камеру как Directshow. Камера появилась в NI MAX, заработали функции IMAQ, но загрузка на процессор еще больше.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3709
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2021
Благодарил (а): 4 раза
Поблагодарили: 52 раза
Контактная информация:

Re: Обработка видео с IP камеры

Сообщение dadreamer »

lam писал(а): 18 окт 2021, 08:09Пока не могу понять, как подключить ещё камеры. Может подскажите.
Для подключения дополнительных камер нужно перекомпилировать callback-библиотеку (VLCCB.dll). В примере она может работать только с одним потоком. В принципе, там ничего сложного. Вот код для работы с шестью потоками:

Код: Выделить всё

library VLCCB;

uses
  SysUtils,
  Classes;

{$R *.res}

var
// В массив по этому указателю будем получать кадры из видео, а потом перекидывать в LabVIEW
pixels1: PChar = nil;
pixels2: PChar = nil;
pixels3: PChar = nil;
pixels4: PChar = nil;
pixels5: PChar = nil;
pixels6: PChar = nil;

// -------- Поток 1  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock1(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels1; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock1(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display1(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr1(Ptr: PChar); cdecl;
begin
pixels1 := Ptr; //запоминаем указатель на массив
end;

// -------- Поток 2  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock2(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels2; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock2(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display2(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr2(Ptr: PChar); cdecl;
begin
pixels2 := Ptr; //запоминаем указатель на массив
end;

// -------- Поток 3  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock3(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels3; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock3(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display3(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr3(Ptr: PChar); cdecl;
begin
pixels3 := Ptr; //запоминаем указатель на массив
end;

// -------- Поток 4  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock4(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels4; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock4(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display4(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr4(Ptr: PChar); cdecl;
begin
pixels4 := Ptr; //запоминаем указатель на массив
end;

// -------- Поток 5  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock5(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels5; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock5(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display5(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr5(Ptr: PChar); cdecl;
begin
pixels5 := Ptr; //запоминаем указатель на массив
end;

// -------- Поток 6  -------- //

// Callback вызывается VLC плеером перед рендером кадра
function lock6(data: Pointer; p_pixels: PPointer): Pointer; cdecl;
begin
p_pixels^ := pixels6; // просто указываем плееру, куда положить текущий кадр
Result := nil;
end;


// Вызывается плеером после lock
procedure unlock6(data: Pointer; id: Pointer; ipixels: PPointer); cdecl;
begin
//
end;

// Вызывается плеером после unlock
procedure display6(data: Pointer; id: Pointer); cdecl;
begin
//
end;

procedure SetPtr6(Ptr: PChar); cdecl;
begin
pixels6 := Ptr; //запоминаем указатель на массив
end;

exports
lock1 name 'lock1',
unlock1 name 'unlock1',
display1 name 'display1',
SetPtr1 name 'SetPtr1',
lock2 name 'lock2',
unlock2 name 'unlock2',
display2 name 'display2',
SetPtr2 name 'SetPtr2',
lock3 name 'lock3',
unlock3 name 'unlock3',
display3 name 'display3',
SetPtr3 name 'SetPtr3',
lock4 name 'lock4',
unlock4 name 'unlock4',
display4 name 'display4',
SetPtr4 name 'SetPtr4',
lock5 name 'lock5',
unlock5 name 'unlock5',
display5 name 'display5',
SetPtr5 name 'SetPtr5',
lock6 name 'lock6',
unlock6 name 'unlock6',
display6 name 'display6',
SetPtr6 name 'SetPtr6';

begin
end.
Я использовал среду Delphi, можете сделать на Сях или на чём-то другом. Либо, как вариант, "грязный" хак - можете просто сделать копию VLCCB.dll с новым именем (повторять это для каждой камеры). Тогда не придётся ничего перекомпилировать.

Дальше в программе на :labview: :
1. Инициализация (показано для двух потоков, остальные - по аналогии)
2021-10-18_13-06-44.jpg
2. Получение данных (тоже для двух потоков, остальные аналогично)
2021-10-18_13-08-50.jpg
3. Финализация (для первого потока, остальные - по аналогии)
2021-10-18_13-10-41.jpg
4. Выгрузка библиотеки из памяти
2021-10-18_13-11-24.jpg
lam писал(а): 18 окт 2021, 08:09Но как будут обрабатываться параллельно несколько потоков?
Попробуйте провести эксперимент. Откройте несколько VLC-плееров и в каждом запустите трансляцию rtsp-потока. Посмотрите загрузку ЦП.
lam
beginner
beginner
Сообщения: 11
Зарегистрирован: 23 сен 2021, 09:13
Версия LabVIEW: 2021
Контактная информация:

Re: Обработка видео с IP камеры

Сообщение lam »

Спасибо. Буду разбираться с С+ компилятором. Не очень понял логику работы по Вашим скриншотам.
Одновременно идет отображение только одного потока? Как то не совсем разобрался со структурой События.
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3709
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2021
Благодарил (а): 4 раза
Поблагодарили: 52 раза
Контактная информация:

Re: Обработка видео с IP камеры

Сообщение dadreamer »

lam писал(а): 20 окт 2021, 12:15Буду разбираться с С+ компилятором.
Попробуйте хотя бы с двумя камерами через этот способ, должно быть проще и быстрее.
dadreamer писал(а): 18 окт 2021, 11:28Либо, как вариант, "грязный" хак - можете просто сделать копию VLCCB.dll с новым именем (повторять это для каждой камеры). Тогда не придётся ничего перекомпилировать.
lam писал(а): 20 окт 2021, 12:15Одновременно идет отображение только одного потока? Как то не совсем разобрался со структурой События.
Нет, одновременно можно выводить изображения со скольки угодно потоков. Циклы же параллельные. Большую часть времени цикл крутится "вхолостую" и постоянно (раз в 40 мс) заходит в кадр Timeout. С помощью встроенной функции MoveBlock вычитываются данные потока по заданному указателю и выводятся на индикатор. Иногда может прийти команда из других параллельных циклов на захват изображения (пользовательское событие Snap). В этом случае данные также вычитываются с помощью MoveBlock и записываются в очередь, которая проверяется в других циклах. Этот кадр с User Event опционален и нужен только для дальнейшей обработки данных с конкретной видеокамеры.

К сожалению, всю программу выложить не могу, большая и завязана на железо.
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Для чайников»