Работа с IP камерой. (IP camera)
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
Ага. Можно поменять тип данных в MoveBlock на одномерный массив, потом вместо вызова функций записи в пикчур - кидать в кластер с константами текущий массив. Внутри этих функций огромное количество повторяющихся операций с массивами...
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Первое сделал, а насчёт кластера что-то не совсем уяснил... Сейчас, по идее, нужно каждый 4*i - й элемент в массиве поменять с 1*i - м и решейпить в 2D. Но если опять это в эвенте делать, то будут пропуски.
- Вложения
-
- VLC Callback Test3.vi
- lv2011
- (44.17 КБ) 254 скачивания
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
Вот что получилось ))) Компактно и кушает ресурсов не очень много. Если поменять порядок цветов, помеченный красным, то вообще никаких преобразований не нужно!
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Я так раньше делал, у меня почему-то не работало. Хорошо, что у вас получилось :) Я вынес из библиотеки инициализацию области памяти, куда выполняется рендеринг. Теперь можно задавать ширину и высоту кадра в .
Код VLC_CB.dll:
Исходник:
FP и BD:
VI:
Краткие пояснения я дал на рисунке блочной диаграммы. Стрелками показаны места, на которые следует обратить внимание: запуск плеера (libvlc_media_player_play) должен быть вызван после того, как в callback-библиотеку передан указатель с помощью SetPtr - это реализовано через провод error in/out; освобождение области памяти для рендеринга должно быть выполнено после остановки воспроизведения (libvlc_media_player_stop) - это реализовано вторым кадром Flat Sequence Structure. Желающие могут переделать структуру приложения с учётом описанных рекомендаций.
Код VLC_CB.dll:
Код: Выделить всё
#include "stdafx.h"
#include "extcode.h"
// В массив по этому указателю будем получать кадры из видео, а потом перекидывать в LabVIEW
unsigned char *pixels = NULL;
LVBoolean DoPost = LVFALSE;
LVUserEventRef Ref = 0;
extern "C" {
__declspec (dllexport) void * lock(void *data, void **p_pixels);
__declspec (dllexport) void unlock(void *data, void *id, void *const *ipixels);
__declspec (dllexport) void display(void *data, void *id);
__declspec (dllexport) void EnablePost();
__declspec (dllexport) void DisablePost();
__declspec (dllexport) void SetEventRef(LVUserEventRef *UserEventRef);
__declspec (dllexport) void SetPtr(unsigned char *Ptr);
}
// Callback вызывается VLC плеером перед рендером кадра
__declspec (dllexport) void * lock(void *data, void **p_pixels)
{
*p_pixels = pixels; // просто указываем плееру, куда положить текущий кадр
return NULL;
}
// Вызывается плеером после lock
__declspec (dllexport) void unlock(void *data, void *id, void *const *ipixels)
{
if (DoPost && pixels)
{
PostLVUserEvent(Ref, (void *)ipixels);
}
}
// Вызывается плеером после unlock
__declspec (dllexport) void display(void *data, void *id)
{
//
}
__declspec (dllexport) void EnablePost()
{
DoPost = LVTRUE; //можно кидать кадры
}
__declspec (dllexport) void DisablePost()
{
DoPost = LVFALSE; //нельзя кидать кадры
}
__declspec (dllexport) void SetEventRef(LVUserEventRef *UserEventRef)
{
Ref = *UserEventRef; //запоминаем ссылку на event
}
__declspec (dllexport) void SetPtr(unsigned char *Ptr)
{
pixels = Ptr; //запоминаем указатель на массив
}
-
- advanced
- Сообщения: 150
- Зарегистрирован: 30 мар 2011, 22:41
- Награды: 1
- Версия LabVIEW: 8.2-2013
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
dadreamer, Borjomy_1, ну, мужчины, вы и круты... Жаль, только сейчас заметил эту тему. Завтра попробую малость похимичить еще чего-то, но не факт, что получится улучшить. Скорость действительно высока - уж поверьте, я имиджем не первый год занимаюсь.
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
ESeid, спасибо на добром слове )))
dadreamer, это выделение памяти должно помочь в ситуации, когда не совпадает формат кадра с предполагаемым размером... Сегодня принесли вторую камеру. Никаких с ней проблем подключиться - только адресную строку поменял. А вот с разрешением (на версии 2 Вашего примера) есть проблемка. У камеры разрешение 1280х1024. Когда выставляю эти значения в константах Labview падает. А на разрешении 1280х720 она работает. Завтра попробую на вашей третьей версии.
И еще одно замечание. Оно относится скорее к Dll VLC... Дело в том, что присутствует примерно секундная задержка в изображении. Для систем мониторинга это не страшно. Но у меня задача совместить изображение и оцифрованные значения сигналов через АЦП. Если ее нельзя убрать, то хотя-бы надо знать, насколько она стабильна, чтобы ее учесть. Откуда она вообще берется?
dadreamer, это выделение памяти должно помочь в ситуации, когда не совпадает формат кадра с предполагаемым размером... Сегодня принесли вторую камеру. Никаких с ней проблем подключиться - только адресную строку поменял. А вот с разрешением (на версии 2 Вашего примера) есть проблемка. У камеры разрешение 1280х1024. Когда выставляю эти значения в константах Labview падает. А на разрешении 1280х720 она работает. Завтра попробую на вашей третьей версии.
И еще одно замечание. Оно относится скорее к Dll VLC... Дело в том, что присутствует примерно секундная задержка в изображении. Для систем мониторинга это не страшно. Но у меня задача совместить изображение и оцифрованные значения сигналов через АЦП. Если ее нельзя убрать, то хотя-бы надо знать, насколько она стабильна, чтобы ее учесть. Откуда она вообще берется?
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Если у вас используется поток реального времени (rtsp, например), то задержка связана с кэшированием кадров в буфере проигрывателя. По умолчанию она составляет 1000 мс и соответствует вот этой опции: В эта опция находится здесь: (в моих примерах стоит 400 мс, но можно поставить и 300 мс; если ставить меньше, могут появиться пропуски кадров или артефакты на изображении)Borjomy_1 писал(а):Дело в том, что присутствует примерно секундная задержка в изображении. Откуда она вообще берется?
Можете поэкспериментировать с кэшем плеера сначала в самом VLC, а потом выставить этот параметр в . Полностью убрать эту задержку вряд ли получится, но снизить можно.
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
в моих примерах стоит 400 мс, но можно поставить и 300 мс;
Увы... уменьшать ее вредно, этот параметр менял. Будем просто учитывать.
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Проверил ради интереса, он просто работает медленнее, чем отдельный вызов MoveBlock, примерно в 1.77 раз (при 100 циклах копирования массива 1280 х 720 х 4 MoveBlock справляется за 81-82 мс, тогда как Get Array By Pointer - только за 144-145 мс). Причина в том, что при работае Get Array By Pointer выполняет ресайз входного массива до нужного размера (выделено розовым):Borjomy_1 писал(а):В первую очередь очень тормозит CIN GetArrayByPointer
Так что SetCINArraySize / NumericArrayResize в данном случае оказалась лишней, так как у нас массив постоянного размера и уже инициализирован в . Однако раньше в случаях, когда размер массива был заранее неизвестен, этот узел работал быстрее всех остальных способов, включая IMAQ MemPeek (когда-то даже составлял табличку с этими временами)./* CIN source file */
#include <string.h>
#include "extcode.h"
/* lv_prolog.h and lv_epilog.h set up the correct alignment for LabVIEW data. */
#include "lv_prolog.h"
/* Typedefs */
//Структура "2-мерный целочисленный массив"
typedef struct {
int32 dimSizes[2];
uInt8 Data[1];
} TD1;
typedef TD1 **TD1Hdl;
//Структура "Кластер error in/out"
typedef struct {
LVBoolean status;
int32 code;
LStrHandle source;
} LVError;
#include "lv_epilog.h"
extern "C"{
CIN MgErr CINRun(uInt64 *Ptr, int32 *ScanSize, int32 *NoScans, TD1Hdl Array, LVError *pError);
CIN MgErr CINProperties(int32 prop, void *data);
}
CIN MgErr CINRun(uInt64 *Ptr, int32 *ScanSize, int32 *NoScans, TD1Hdl Array, LVError *pError)
{
MgErr cinErr = noErr;
//установка размера выходного массива
if (cinErr = SetCINArraySize((UHandle)Array, 3, *ScanSize * *NoScans))
{
//запись информации об ошибке в структуру pError
char ErrorString[] = "Ошибка при установке размера выходного массива";
int32 len = strlen(ErrorString);
MgErr err = noErr;
if (err = NumericArrayResize(uB, 1, (UHandle*)&(pError->source), len))
goto out;
MoveBlock(ErrorString, LStrBuf(*(pError->source)), len);
LStrLen(*(pError->source)) = len;
pError->status = LVTRUE;
pError->code = 123456;
goto out;
}
//изменение информации об измерениях массива
(*Array)->dimSizes[0] = *NoScans;
(*Array)->dimSizes[1] = *ScanSize;
MoveBlock((UPtr)(*Ptr),(*Array)->Data,(*ScanSize * *NoScans)*sizeof(uInt8));
out:
return cinErr;
}
CIN MgErr CINProperties(int32 prop, void *data)
{
switch (prop) {
case kCINIsReentrant:
*(Bool32 *)data = TRUE;
return noErr;
}
return mgNotSupported;
}
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
У меня он давал процентов 20 загрузки процессора... Сейчас уровень не превышает 20% на все, включая сжатие кадра в JPEG с коэффициентом 0.75. Если запись в AVI средствами Vision, то 35%он просто работает медленнее, чем отдельный вызов MoveBlock, примерно в 1.77 раз
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Borjomy_1, эх, жаль, я стёр уже, не проверил загрузку ЦП. Но когда я выкинул функцию SetCINArraySize из кода, то время выполнения стало один-в-один с MoveBlock'ом. Так что очевидно, что на создание массива тратятся ресурсы.
upd:
Проверил всё же - в режиме Run Continuously MoveBlock расходует 12% ЦП, а Get Array By Pointer - 14%. Железо то же, что упоминал ранее. Не такая уж критичная разница.
типа такого:
upd:
Проверил всё же - в режиме Run Continuously MoveBlock расходует 12% ЦП, а Get Array By Pointer - 14%. Железо то же, что упоминал ранее. Не такая уж критичная разница.
типа такого:
А как вы определили, куда сколько % тратится?Borjomy_1 писал(а):Загрузка процессора составляет 40%, причем половина из этого приходится на CIN "Get Array By Pointer"
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
Закинул в Disable diagram, а массив оставил прежним. и сравнил загрузку.А как вы определили, куда сколько % тратится?
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
На домашнем ПК получаю точно такие же цифры:
Я никак не могу получить такие же цифры - чтоб сразу 20% заняло одно только копирование памяти. Что-то тут не ладно.
[b][color=#FF9900]dadreamer[/color][/b] писал(а):Проверил всё же - в режиме Run Continuously MoveBlock расходует 12% ЦП, а Get Array By Pointer - 14%.
У вас, м.б., в Disable оказалась также и мат. обработка?[b][color=#FF9900]Borjomy_1[/color][/b] писал(а):Закинул в Disable diagram, а массив оставил прежним. и сравнил загрузку.
Я никак не могу получить такие же цифры - чтоб сразу 20% заняло одно только копирование памяти. Что-то тут не ладно.
-
- doctor
- Сообщения: 2210
- Зарегистрирован: 28 июн 2012, 09:32
- Награды: 3
- Версия LabVIEW: 2009..2020
- Откуда: город семи холмов
- Благодарил (а): 27 раз
- Поблагодарили: 26 раз
Re: Работа с IP камерой. (IP camera)
Нет, выключал только одну функцию.
Наверное, у нас все таки разночтений нет. Порядок загрузки примерно одинаковый.
Наверное, у нас все таки разночтений нет. Порядок загрузки примерно одинаковый.
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 126 раз
- Контактная информация:
Re: Работа с IP камерой. (IP camera)
Сейчас специально вернулся к первому примеру.
Исходное состояние: Убрал весь вывод и обработку, оставил только копирование памяти: Замена на MoveBlock: Убрал весь вывод и обработку, оставил только копирование памяти: Вывод: результаты практически одинаковы, разница в 1%. Получаем, что вся нагрузка на ЦП идёт при обработке и выводе графики. Само копирование памяти играет очень незначительную роль (даже если учитывать выделение области под массив).
Так что я очень сомневаюсь, что вышеупомянутые 20% пришлись на копирование памяти. Если вы можете воспроизвести подобное поведение при копировании памяти, то просьба выложить такой ― буду тщательно изучать
Исходное состояние: Убрал весь вывод и обработку, оставил только копирование памяти: Замена на MoveBlock: Убрал весь вывод и обработку, оставил только копирование памяти: Вывод: результаты практически одинаковы, разница в 1%. Получаем, что вся нагрузка на ЦП идёт при обработке и выводе графики. Само копирование памяти играет очень незначительную роль (даже если учитывать выделение области под массив).
Так что я очень сомневаюсь, что вышеупомянутые 20% пришлись на копирование памяти. Если вы можете воспроизвести подобное поведение при копировании памяти, то просьба выложить такой ― буду тщательно изучать
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
- 13 Ответы
- 2497 Просмотры
-
Последнее сообщение Artem.spb
-
- 16 Ответы
- 3229 Просмотры
-
Последнее сообщение Artem.spb
-
- 4 Ответы
- 204 Просмотры
-
Последнее сообщение Andrew Lunev