Перейти к содержимому
Compvision.ru
Gleb Matveev

Проектирование системы видеонаблюдения (вопросы архитектуры)

Recommended Posts

Здравствуйте, уважаемые форумчане!

Сильно не пинайте, первый пост. Скорее всего где-то что-то не правильно понимаю, поэтому и обращаюсь к Вам за помощью!

Обдумываю поставленную задачу и никак не могу разложить все мысли по полочкам. Возникает уйма вопросов, которые просто не умещаются в голове!) Надеюсь, кто-нибудь поможет понять что к чему и правильно ли я мыслю!

Пока экспериментирую с помощью Visual Studio 2013 + OpenCV 2.4.8, двух web-камер и одной ip-камеры Evidence.

Все камеры я подключал и выводил в PictureBox'ы, пробовал вести запись в *.avi. Всё получается. Код простой прилагаю.

В планах написать ПО, состоящее фактически из двух приложений: сервер и клиент.

Задача сервера стартовать при запуске ОС, считывать конфигурационный файл, и исходя из настроек начинать обрабатывать потоки с камер (под обработкой я имею ввиду, например, запись, поиск в кадрах определенных заданных вещей, подготовка видеопотока для передачи по сети клиенту и так далее).

Задача клиента просто смотреть потоки из сети.

Такое разделение хочется сделать, потому что для сервера отводится мощная машина, а для клиента не очень, и всю нагрузку хочется спихнуть серверу.

Собственно вопросы:

01. Строкой

CvVideoWriter *writer = cvCreateVideoWriter(filename, CV_FOURCC('X','V','I','D'), fps, size, 1);

мы сохраняем видеопоток в формат *.avi. А возможно ли сохранить поток в первозданном виде? Т.е. что идет с камеры то и сохраняем. Например, моя камера Evidence гонит два потока, MJPEG и H.264. Можно ли сохранить второй поток в каком-либо "чистом" виде, при необходимости проигрывать, а уж если пользователь захотел сохранить в более популярный формат, то дать ему такую возможность?

02. Передача по сети видеопотоков от сервера клиенту организовать с помощью сокетов? Есть ли в этом смысл? Будет ли такой способ достаточно разгружать клиент или проще будет с клиента смотреть камеры напрямую по ip-адресам с помощью OpenCV?

03. Многопоточность. Самый волнующий вопрос. С одной камерой всё легко и просто. А как быть, когда камер становится порядка десяти?

Просто пишем много раз (грубо говоря):

CvCapture* capture1 = cvCreateCameraCapture(rtsp://192.168.0.201);

CvCapture* capture2 = cvCreateCameraCapture(rtsp://192.168.0.202);

и так далее?

Или нужно обрабатывать каждую камеру в отдельном потоке?

И как быть с задачами, которые возлагаются на сервер?

Тоже по потокам - запись отдельно, обработка отдельно?

Пока всё что напридумывал))

Как говорится наболело) Буду рад любым ответам и помощи!

Заранее спасибо!

video.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ответы:

1. Для того, чтобы сохранить поток в первозданном виде, надо получить поток в первозданном виде. В OpenCV такой возможности нет, можно получить только декодированные кадры.

Чтобы минимизировать потери качества при сжатии используй (ваш КО) при сохранении такой же кодек, каким было закодировано видео камерой: CV_FOURCC('M','J','P','G'), CV_FOURCC('H','2','6','4'). *.avi - это просто популярный контейнер для видео и аудио, к формату записываемых данных он отношения не имеет.

2. Да, передачу с помощью сокетов, это нормально. Если хочешь смотреть реальное видео с ip-камеры на клиенте, то для сервера было бы легче вообще в этом не участвовать, смотри сразу с ip-камеры.

3. Многопоточность в твоём случае надо использовать и на сервере, и на клиенте. Скорее всего оптимальным будет обрабатывать видео с каждой камеры в отдельном потоке, а вот операции с одним видео на потоки не дробить.

Теперь в общем скажу, раз уж у меня есть за плечами восьмилетний опыт разработки системы видеонаблюдения.

Достаточно оптимальный способ работы с видео одной ip-камеры, которая отдаёт два видеопотока: один с большим разрешением и сжатый "тяжёлым" кодеком (h.264), а второй с меньшим разрешением (mjpeg).

1. По сети приходят сжатые кадры, для сохранения в архив их лучше получать самому и, не трогая, сразу писать в архив. Серверу при этом вообще никаких напрягов, главное быстрый жёсткий диск тут. Сохраняется обычно видеопоток с большим разрешением, чтобы при наличии инцидента после можно было разобрать детали.

2. На клиентские машины также отсылаются кадры, непосредственно полученные от камер: их сервер не перекодирует - зачем?

3. Какое видео отсылать для отображения? Тут происходит тонкая балансировка: если размер окошка примерно равен разрешению второго потока (или клиент не тянет отображение большого разрешения), то отсылается он. Если окошко увеличивается, растягивается, то отсылается поток с большим разрешением. всем этим процессом управляет клиент, он отсылает серверу, какого качества видео для какого канала ему надо в данный момент времени. На практике это выглядит примерно так: у охранника на мониторах отображается, ммм, 20 камер равномерной плиткой - он получает видео маленького разрешения. Вдруг он замечает подозрительный объект, растягивает окошко (или оно само при сработке детектора движения увеличивается), клиент отсылает запрос серверу на изменение размера, сервер для этой камеры шлёт поток с высоким разрешением. Охранник спокойно разглядывает мелкие детали. Окно уменьшили - поток переключился на меньший, разгружая систему.

4. Для анализа видео на сервере можно использовать как видео большого разрешения, так и маленького. Скорее так: чаще используют маленького, кроме особых случаев. Снижаются затраты на декодирование, меньше работы для детектора движения и прочих алгоритмов.

Заметь, только 4-й пункт требует от сервера декодирование полученного видео, только в этом случае есть смысл использовать OpenCV для захвата. Зачастую сервер вообще не производит декодирование, так как современные ip-камеры обладают не сильно убогими детекторами движения с возможностью настройки зон детекции. А некоторые камеры вообще являются комбайнами: детектор движения, детектор оставленных предметов, пересечение линии, зоны, сопровождение повороткой... В таких случаях сервера просто напросто осуществляют функции по хранению, распределению прав, сетевой балансировке, осуществляют общую логику работы и т.п. И это глобальный тренд уже в течение минимум 5-ти лет, небольшие системы видеонаблюдения сегодня не нуждаются в своей видеоаналитике, а используют только встроенную в камеры.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо за быстрый и столь развернутый ответ!

Приятно слушать, что говорит опытный человек!

1. По сети приходят сжатые кадры, для сохранения в архив их лучше получать самому и, не трогая, сразу писать в архив.

Это я как раз и имел ввиду! К сожалению не хватает знаний...

Не подскажите какие-либо средства, чтобы осуществлять захват/сохранение/просмотр видеопотока в таком виде в котором его посылает сама камера.

В каком направлении двигаться?

3. Какое видео отсылать для отображения? Тут происходит тонкая балансировка: если размер окошка примерно равен разрешению второго потока (или клиент не тянет отображение большого разрешения), то отсылается он. Если окошко увеличивается, растягивается, то отсылается поток с большим разрешением.

Согласен с Вами! Так и планировал реализовывать. Уже встречался с подобным алгоритмом в работающих проектах.

3. Многопоточность в твоём случае надо использовать и на сервере, и на клиенте. Скорее всего оптимальным будет обрабатывать видео с каждой камеры в отдельном потоке, а вот операции с одним видео на потоки не дробить.

То есть что-то вроде этого псевдокода?

На стороне сервера:


НовыйПоток1

	{

	Пока (включен канал)

		{

		ЗахватКадра(камера1);

			{

			Возврат кадр;

			}


		Если (записывать видео == да)

			{

			ЗаписьКадра(кадр);

			}


		Если (анализировать видео == да)

			{

			АнализКадра(кадр);

			}

		}

	}

	

НовыйПоток2

...

//аналогично для второй камеры?

На стороне клиента:

НовыйПоток3

	{

	Пока (включен канал)

		{

		Если (отображать одну камеру == да)

			{

			ЗахватКадра(камера1.поток1);

				{

				Возврат кадр;

				}

			ОтображениеКадра(кадр);

			}


		Если (отображать много камер == да)

			{

			ЗахватКадра(камера1.поток2);

				{

				Возврат кадр;

				}

			ОтображениеКадра(кадр);

			}

		}

	}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Это я как раз и имел ввиду! К сожалению не хватает знаний...

Не подскажите какие-либо средства, чтобы осуществлять захват/сохранение/просмотр видеопотока в таком виде в котором его посылает сама камера.

В каком направлении двигаться?

Мы всё делали на асинхронных сокетах и вручную разбирали rtsp-протокол. Этот подход вполне подходит для большой конторы с опытными программистами. А так... Надо посмотреть, может ли ffmpeg захватывать и парсить rtsp, а дальше выдавать исходные данные. Если может, то вариант очень хороший.

То есть что-то вроде этого псевдокода?

Да, что-то типа этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Наткнулся на либу, реализующую RTMP, может пригодится: http://rtmpdump.mplayerhq.hu/librtmp.3.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Заметил что стандартный gdi+ метод вывода через picturebox жутко медленный даже если зумить или растягивать кринку методами opencv. Собственно интересно кто как выводит картинку и какой способ самый быстрый(только под винду).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Заметил что стандартный gdi+ метод вывода через picturebox жутко медленный даже если зумить или растягивать кринку методами opencv. Собственно интересно кто как выводит картинку и какой способ самый быстрый(только под винду).

А через OpenGL не вариант? Должно по идее быть быстрее всего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да я сейчас directx пробую, сам вывод при любом размере как входного так и выходного(размер окна) изображения порядка 1мс что радует. Но вот копирование из iplimage в формат directx при 720p уже порядка 7мс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да я сейчас directx пробую, сам вывод при любом размере как входного так и выходного(размер окна) изображения порядка 1мс что радует. Но вот копирование из iplimage в формат directx при 720p уже порядка 7мс.

Хм...не знаю как там в DirectX, но в OpenGL только cv::flip (чтобы там все лежало по столбцам) сделать надо и потом cv::Mat сразу копировать в память GPU. Чисто теоретически можно и этого не делать, если написать шейдер, который будет точки cv::Mat прямо на GPU переводить в нужный формат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Заметил что стандартный gdi+ метод вывода через picturebox жутко медленный даже если зумить или растягивать кринку методами opencv.

это про видео? если нет, то можно использовать двойной буффер.

и зачем растягивать методами opencv? можно же просто выделять рект в памяти и кидать на форму.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Мы выводили именно через Direct3D: создавали D3D surface, лочили его и копировали туда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Для видео но наложением результатов обработки.

и зачем растягивать методами opencv? можно же просто выделять рект в памяти и кидать на форму.
я под .net пишу там такое можно сделать только через костыли. А ресайз средствами opencv потому что если это делать средствами самого .net то время самого ресайза вырастает до 100мс. возможно это косяк .net и в с++ такого нет.

Мы выводили именно через Direct3D: создавали D3D surface, лочили его и копировали туда

а какое у вас время копирования было?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не помню уже. Но всё силььно зависело от видеокарты, памяти на ней, системной памяти... Кадр преимущественно использовали в YUV формате, который приходил от декодера: он и поо размеру меньши, и в видеопамять копируеттся быстрее, и для обработки приятней простого RGB.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×