Работа с IP камерой. (IP camera)

VISA, TCP/IP, USB, CAN, GPIB и подобные протоколы
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

Ага. Можно поменять тип данных в MoveBlock на одномерный массив, потом вместо вызова функций записи в пикчур - кидать в кластер с константами текущий массив. Внутри этих функций огромное количество повторяющихся операций с массивами...
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Первое сделал, а насчёт кластера что-то не совсем уяснил... :think: Сейчас, по идее, нужно каждый 4*i - й элемент в массиве поменять с 1*i - м и решейпить в 2D. Но если опять это в эвенте делать, то будут пропуски.
Вложения
VLC Callback Test3.vi
lv2011
(44.17 КБ) 254 скачивания
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

Вот что получилось ))) Компактно и кушает ресурсов не очень много. Если поменять порядок цветов, помеченный красным, то вообще никаких преобразований не нужно!
Вложения
Рабочий результат1.PNG
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Я так раньше делал, у меня почему-то не работало. Хорошо, что у вас получилось :) Я вынес из библиотеки инициализацию области памяти, куда выполняется рендеринг. Теперь можно задавать ширину и высоту кадра в :labview: .
Код 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; //запоминаем указатель на массив
}
Исходник:
VLC_CB3.rar
(309.21 КБ) 292 скачивания
FP и BD:
2015-03-24_20-51-19.jpg
2015-03-24_20-54-34.jpg
VI:
VLC_Callbacks.rar
lv2011
(36.68 КБ) 270 скачиваний
Краткие пояснения я дал на рисунке блочной диаграммы. Стрелками показаны места, на которые следует обратить внимание: запуск плеера (libvlc_media_player_play) должен быть вызван после того, как в callback-библиотеку передан указатель с помощью SetPtr - это реализовано через провод error in/out; освобождение области памяти для рендеринга должно быть выполнено после остановки воспроизведения (libvlc_media_player_stop) - это реализовано вторым кадром Flat Sequence Structure. Желающие могут переделать структуру приложения с учётом описанных рекомендаций.
ESeid

Автор
advanced
advanced
Сообщения: 150
Зарегистрирован: 30 мар 2011, 22:41
Награды: 1
Версия LabVIEW: 8.2-2013
Контактная информация:

Re: Работа с IP камерой. (IP camera)

Сообщение ESeid »

dadreamer, Borjomy_1, ну, мужчины, вы и круты... Жаль, только сейчас заметил эту тему. Завтра попробую малость похимичить еще чего-то, но не факт, что получится улучшить. Скорость действительно высока - уж поверьте, я имиджем не первый год занимаюсь.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

ESeid, спасибо на добром слове )))
dadreamer, это выделение памяти должно помочь в ситуации, когда не совпадает формат кадра с предполагаемым размером... Сегодня принесли вторую камеру. Никаких с ней проблем подключиться - только адресную строку поменял. А вот с разрешением (на версии 2 Вашего примера) есть проблемка. У камеры разрешение 1280х1024. Когда выставляю эти значения в константах Labview падает. А на разрешении 1280х720 она работает. Завтра попробую на вашей третьей версии.
И еще одно замечание. Оно относится скорее к Dll VLC... Дело в том, что присутствует примерно секундная задержка в изображении. Для систем мониторинга это не страшно. Но у меня задача совместить изображение и оцифрованные значения сигналов через АЦП. Если ее нельзя убрать, то хотя-бы надо знать, насколько она стабильна, чтобы ее учесть. Откуда она вообще берется?
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Borjomy_1 писал(а):Дело в том, что присутствует примерно секундная задержка в изображении. Откуда она вообще берется?
Если у вас используется поток реального времени (rtsp, например), то задержка связана с кэшированием кадров в буфере проигрывателя. По умолчанию она составляет 1000 мс и соответствует вот этой опции:
2015-03-25_11-30-21.jpg
В :labview: эта опция находится здесь:
2015-03-25_11-34-23.jpg
(в моих примерах стоит 400 мс, но можно поставить и 300 мс; если ставить меньше, могут появиться пропуски кадров или артефакты на изображении)
Можете поэкспериментировать с кэшем плеера сначала в самом VLC, а потом выставить этот параметр в :labview: . Полностью убрать эту задержку вряд ли получится, но снизить можно.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

в моих примерах стоит 400 мс, но можно поставить и 300 мс;

Увы... уменьшать ее вредно, этот параметр менял. Будем просто учитывать.
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Borjomy_1 писал(а):В первую очередь очень тормозит CIN GetArrayByPointer
Проверил ради интереса, он просто работает медленнее, чем отдельный вызов MoveBlock, примерно в 1.77 раз (при 100 циклах копирования массива 1280 х 720 х 4 MoveBlock справляется за 81-82 мс, тогда как Get Array By Pointer - только за 144-145 мс). Причина в том, что при работае Get Array By Pointer выполняет ресайз входного массива до нужного размера (выделено розовым):
/* 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;
}
Так что SetCINArraySize / NumericArrayResize в данном случае оказалась лишней, так как у нас массив постоянного размера и уже инициализирован в :labview: . Однако раньше в случаях, когда размер массива был заранее неизвестен, этот узел работал быстрее всех остальных способов, включая IMAQ MemPeek (когда-то даже составлял табличку с этими временами).
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

он просто работает медленнее, чем отдельный вызов MoveBlock, примерно в 1.77 раз
У меня он давал процентов 20 загрузки процессора... Сейчас уровень не превышает 20% на все, включая сжатие кадра в JPEG с коэффициентом 0.75. Если запись в AVI средствами Vision, то 35%
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Borjomy_1, эх, жаль, я :vi: стёр уже, не проверил загрузку ЦП. Но когда я выкинул функцию SetCINArraySize из кода, то время выполнения стало один-в-один с MoveBlock'ом. Так что очевидно, что на создание массива тратятся ресурсы.

upd:
Проверил всё же - в режиме Run Continuously MoveBlock расходует 12% ЦП, а Get Array By Pointer - 14%. Железо то же, что упоминал ранее. Не такая уж критичная разница.
:vi: типа такого:
99999.vi
lv2011
(46.11 КБ) 248 скачиваний
Borjomy_1 писал(а):Загрузка процессора составляет 40%, причем половина из этого приходится на CIN "Get Array By Pointer"
А как вы определили, куда сколько % тратится?
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

А как вы определили, куда сколько % тратится?
Закинул в Disable diagram, а массив оставил прежним. и сравнил загрузку.
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

На домашнем ПК получаю точно такие же цифры:
[b][color=#FF9900]dadreamer[/color][/b] писал(а):Проверил всё же - в режиме Run Continuously MoveBlock расходует 12% ЦП, а Get Array By Pointer - 14%.
[b][color=#FF9900]Borjomy_1[/color][/b] писал(а):Закинул в Disable diagram, а массив оставил прежним. и сравнил загрузку.
У вас, м.б., в Disable оказалась также и мат. обработка?

Я никак не могу получить такие же цифры - чтоб сразу 20% заняло одно только копирование памяти. Что-то тут не ладно.
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2207
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Работа с IP камерой. (IP camera)

Сообщение Borjomy_1 »

Нет, выключал только одну функцию.
Наверное, у нас все таки разночтений нет. Порядок загрузки примерно одинаковый.
Аватара пользователя
dadreamer

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

Re: Работа с IP камерой. (IP camera)

Сообщение dadreamer »

Сейчас специально вернулся к первому примеру.
Исходное состояние:
CIN_with_output.jpg
Убрал весь вывод и обработку, оставил только копирование памяти:
CIN_no_output.jpg
Замена на MoveBlock:
MB_with_output.jpg
Убрал весь вывод и обработку, оставил только копирование памяти:
MB_no_output.jpg
Вывод: результаты практически одинаковы, разница в 1%. Получаем, что вся нагрузка на ЦП идёт при обработке и выводе графики. Само копирование памяти играет очень незначительную роль (даже если учитывать выделение области под массив).

Так что я очень сомневаюсь, что вышеупомянутые 20% пришлись на копирование памяти. Если вы можете воспроизвести подобное поведение при копировании памяти, то просьба выложить такой :vi: ― буду тщательно изучать Изображение
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Коммуникация с приборами»