Линукс компьютеры с камерой

Web камера в Linux — как проверить?

В отличии от современных планшетов, в которые web-камера, как правило, встроена и такое у планшетов является нормой, на стационарном компьютере web камеры нет, да и на ноутбуках они не всегда есть.

Поэтому по умолчанию во многих версиях Linux не установлен изначально софт для работы с web-камерой. Но эта проблема легко решается, Web камера в Linux может работать на УРА.

Существует USB-стандарт UVC (USB Video Class), определяющий потоковое видео и делающий применение Web-камер столь же простым как использование носителей флеш-USB и жестких дисков, позволяя одному драйверу работать с разными Web-камерами.

Таким образом в Ubuntu автоматически функционирует большинство Web-камер (если только не все).

Быстрый способ убедиться в работоспособности вашей Web-камеры — установить и запустить программу Cheese, выбрав в меню команды Приложения | Стандартные | Терминал (Applications | Accessories | Terminal) и введя строки:

После запуска программа будет выглядеть так:

Команда в первой строке установит программу (и запросит у вас ваш пароль в Ubuntu), а вторая (которую вы должны выполнить, когда завершится установка) запустит программу для Web-камеры и выведет на экран окно, подобное показан.

Когда вы убедитесь, что ваша Web-камера работает, можно закрыть программу Cheese, но имеет смысл сохранить ее на вашем компьютере, потому что это отличная утилита для записи видео и получения фотографий.

Программа проста в установке и с ней легко разобраться. Но если у вас не что-то не получится, то пишите в комментариях, помогу чем могу!

Установка USB камеры в Linux Ubuntu

Источник

Работа с usb видеокамерой в Linux. Часть 2

Продолжаем цикл статей про программирование видеокамеры в Linux. В первой части [1], мы рассмотрели механизм открытия и считывания первичных параметров видеоустройства. Была написана простенькая утилита catvd. Сегодня расширим функционал нашей маленькой программы , но сначала надо написать обертку для функции ioctl.

Эта обертка позволяет прервать программу если была ошибка и показать сообщение.

&nbsp&nbspПопробуем считать картинку с камеры и сохранить в файл.

метод readFrame — отвечает за чтение и обработку полученого изображения.
методы initMMAP(), freeMMAP() — создание/очистка буфера памяти устройства.
методы startCapturing(), stopCapturing() — включение/выключение режима streaming у видеоустройства. Наличие этих функций, у камеры, можно проверить флагом V4L2_CAP_STREAMING [*].

&nbsp&nbspРазберем метод initMMAP

функция VIDIOC_REQBUFS [↓] позволяет проинициализировать буфер памяти внутри устройства. Структура v4l2_requestbuffers задает параметры инициализации

&nbsp&nbspПосле того, как буфер был проинициализирован, его надо отобразить на область памяти (mapping).
Функция VIDIOC_QUERYBUF [↓] позволяет считать параметры буфера, которые будут использоваться для создания memory-mapping области. Структура v4l2_buffer большая, опишу необходимые поля:

системная функция mmap() [3] позволяет отображать файл или область памяти устройств в оперативную память. Для использования mmap() необходимо подключить

&nbsp&nbspДалее необходимо переключить камеру в режим захвата.

Функция VIDIOC_QBUF [↓] ставит буфер в очередь обработки драйвером устройства. Поля используются такие же, как и для VIDIOC_REQBUFS или VIDIOC_QUERYBUF.
Функция VIDIOC_STREAMON[↓] включает камеру в режим захвата.

&nbsp&nbspТеперь камера включена и захватывает изображения. Но картинку еще надо получить.

Функция VIDIOC_DQBUF[↓] освобождает буфер из очереди обработки драйвера. В результате можем получить ошибку EAGAIN. Ничего опасного в этом нет, надо еще раз вызвать VIDIOC_DQBUF. Это происходит потому, что драйвер еще обрабатывает запрос и не может освободить буфер из очереди. При успешном выполнении этой функции, мы получаем в «руки» нашу картинку. В самом начале статьи, в коде был добавлен итератор. Итератор позволяет проследить сколько итераций вхолостую проходит цикл до успешного выполнения VIDIOC_DQBUF.

Вывод программы следующий

Из «iter == 831013» видно — картинка скидывается в буфер довольно долго. Для ускорения можно использовать несколько буферов и вытаскивать картинку с первого свободного и т.д.

&nbsp&nbspСегодня была рассмотрена инициализация буфера памяти и чтения из него картинки. Изображение сохраняется в raw формате. Можно открыть программой Shotwell. В следующей статье будет рассмотрен вывод изображению в текстуру (через SDL2), затронуты некоторые форматы изображения и настройки камеры.

Источник

Захват видео с USB камер на устройствах под управлением Linux

Предыстория

  1. Видео в разрешении FullHD (1920Х1080) или HD (1280х720) и нормальная частота кадров (чтобы можно было играть).
  2. Игрушку я планировал отдать детям, поэтому нужен был автостарт и поддержка подключения/отключения камеры.

В общем хотелось что-то вроде этого:

Ограничения

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

  1. Хороший WiFi сигнал.
  2. Ограниченное число подключений, приоритет отдавался случаю, когда есть всего один клиент.
  3. Камера поддерживает режим MJPG.
Читайте также:  Как активировать windows 10 education

HW и SW

Предварительный анализ

Код UVC драйвера оказался готов к добавлению различного рода “специальных” решений, и я легко нашел место, где надо скорректировать размер буфера (функция uvc_fixup_video_ctrl()). Более того, драйвер поддерживает набор quirks, которые позволяют поддерживать камеры с разного рода отклонениями от стандарта UVC. В общем, разработчики драйвера сделали лучшее, что возможно для поддержки зоопарка камер.

Добавив коррекцию размера буфера, я получил стабильную работу в режиме 1280х720 и даже в режиме 1920х1080. Ура! Половина задачи решена!

В поисках новых приключений

Немного порадовавшись первой удаче, я вспомнил, что mjpg-streamer далек от совершенства. Наверняка можно сделать что-то простое, не такое универсальное как mjpg-streamer, но более подходящее для моих условий. Так я решил сделать uvc2http.

В mjpg-streamer мне не понравилось использование нескольких потоков и копирование буферов. Это определило архитектуру решения: 1 поток и никакого копирования. Используя non-blocking IO, это делается достаточно просто: захватываем кадр и без копирования отсылаем его клиенту. Есть небольшая проблема: пока мы отсылаем данные из буфера, мы не можем вернуть буфер обратно в очередь. А пока буфер не в очереди, драйвер не может положить в него новый кадр. Но если размер очереди > 1, то это становится возможным. Число буферов определяет максимальное количество подключений, которое можно гарантированно обслуживать. Т.е., если я хочу гарантированно поддерживать 1 клиента, то 3-х буферов достаточно (в один буфер пишет драйвер, из второго отсылаем данные, третий в запасе, чтобы избежать конкуренции с драйвером за буфер при попытке получить новый кадр).

Uvc2http

Uvc2http состоит из двух компонентов: UvcGrabber и HttpStreamer. Первый отвечает за получение буферов (кадров) из очереди и возврат их обратно в очередь. Второй отвечает за обслуживание клиентов по HTTP. Есть еще немного кода, который связывает эти компоненты. Подробности можно посмотреть в исходниках.

Неожиданная проблема

Все было замечательно: приложение работало и в разрешении 1280х720 выдавало 20+ кадров/сек. Я делал косметические изменения в коде. После очередной порции изменений я замерил частоту кадров. Результат был удручающий — меньше 15 кадров. Я бросился искать, что же привело к деградации. Я потратил, наверное, 2 часа в течение которых частота уменьшалась с каждым замером до значения 7 кадров/сек. В голову лезли разные мысли о деградации из-за долгой работы роутера, из-за его перегрева. Это было что-то непонятное. В какой-то момент я отключил стримминг и увидел, что просто один захват (без стримминга) давал те же 7 кадров. Я даже начал подозревать проблемы с камерой. В общем какая-то чушь. Дело было вечером и камера, повернутая в окно, показывала что-то серое. Дабы сменить мрачное изображение я повернул камеру внутрь комнаты. И, о чудо! Частота кадров увеличилась до 15 и я все понял. Камера автоматически подстраивала время экспозиции и в какой-то момент это время стало больше длительности кадра при заданной частоте. За эти два часа случилось следующее: сначала плавно темнело (это был вечер), а потом я повернул камеру внутрь освещенной комнаты. Направив камеру на люстру я получил 20+ кадров/сек. Ура.

Другие проблемы и нюансы использования

Результаты

Ниже табличка с результатами сравнения mjpg-streamer и uvc2http. Если коротко — есть значительный выигрыш в потреблении памяти и небольшой выигрыш в частоте кадров и загрузке CPU.

1280×720 1920×1080
VSZ, KB, 1 client VSZ, KB, 2 clients CPU, %, 1 client CPU, %, 2 clients FPS, f/s, 1 client FPS, f/s, 2 clients VSZ, KB, 1 client VSZ, KB, 2 clients CPU, %, 1 client CPU, %, 2 clients FPS, f/s, 1 client FPS, f/s, 2 clients
Mjpg-streamer 16860 19040 26 43 17.6 15 25456 25812 28 50 13.8 10
uvc2http 3960 3960 26 43 22 19.6 7576 7576 28 43 15.5 12.2

Ну и конечно же видео, которое я сделал вместе с детьми:

Фото получившегося танка (получилось что-то вроде цыганской телеги):

Использование

Исходники находятся здесь. Для использования на PC Linux надо всего лишь собрать (при условии что вы не хотите патчить драйвер UVC). Утилита собирается с помощью CMake стандартным способом. Если же надо использовать в OpenWRT, то надо сделать дополнительные шаги:

  1. Скопировать содержимое директории OpenWrt-15.05 в корень репозитория OpenWRT. Эти файлы только для OpenWRT 15.05. Они описывают новый пакет для OpenWRT и патч для драйвера UVC.
  2. Если ваша камера также возвращает завышенный размер необходимого буфера, то надо добавить использование quirk UVC_QUIRK_COMPRESSION_RATE для вашей камеры в файле uvc_driver.c. Для этого надо сделать собственный патч для драйвера UVC. Как это сделать, описано здесь wiki.openwrt.org/doc/devel/patches. Вам необходимо добавить описание вашей камеры в массив uvc_ids. В качестве примера можно посмотреть на описание моей камеры:
  • Настроить сборку OpenWRT стандартный методом (http://wiki.openwrt.org/doc/howto/build). При настройке необходимо выбрать пакет uvc2http в меню Multimedia.
  • Собрать пакет uvc2http или полный образ (обязательно если вам необходим патч драйвера) для вашей целевой платформы. Если установить утилиту как пакет, то она будет запускаться при старте.
  • Установить пакет на устройство/обновить систему
  • Читайте также:  Где хранится загрузчик windows

    Что дальше

    Решение состоит из двух частей: патч драйвера и другой алгоритм стримминга. Патч драйвера можно было бы включить в новую версию ядра линукса, но это спорное решение, так как оно основано на предположении о минимальном коэффициенте сжатия. Утилита же, на мой взгляд, хорошо подходит для использования на слабых системах (игрушках, домашних системах видеонаблюдения), и ее можно немного улучшить, добавив возможность задавать настройки камеры через параметры.

    Алгоритм стримминга можно улучшить так как есть запас по загрузке CPU и по ширине канала (я легко получал с роутера 50+ MBit подключая десяток клиентов). Также можно добавить поддержку звука.

    Источник

    Большой брат в Linux или видеонаблюдение своими руками

    Большой брат в Linux или видеонаблюдение своими руками.

    После переезда в новый офис, дабы не расслаблять сотрудников, было решено
    установить систему видеонаблюдения. Но, как обычно, основным условием было:
    дешево и сердито 🙂 После обдумывания и подсчетов было решено остановиться на
    следующем:
    IP камеры и компьютер в качестве регистратора.
    Для начала попробовали небезызвестный ZoneMinder. Но отчего-то с 9 камерами он
    грузил систему нещадно. После некоторой борьбы с ним, было решено отказаться от
    него. Поискав на просторах Internet была найдена программка под названием
    motion (http://www.lavrsen.dk/twiki/bin/view/Motion/WebHome). Почитав немного
    про нее, было решено остановиться на ней.
    Итак, у нас были IP камеры, компьютер в качестве регистратора, motion в
    качестве софта и желание подружить весь этот колхоз 🙂
    И что же умеет motion из того, что нам надо? 🙂
    1. Работа с камерами, подключенными через карты захвата либо с IP камерами.
    2. Выполнять скрипты при наступлении и окончании события.

    Ну чтож, приступим. Для начала попробуем с одной камерой 🙂
    Устанавливаем motion.
    Далее, в папке /etc/motion/ копируем файл с конфигурацией (motion.conf) в файл
    для нашей камеры, например motion1.conf. А теперь начинаем его править под
    себя:
    1. закомментируем строчку
    videodevice /dev/video0
    2. в строке netcam_url прописываем URL для доступа к нашей камере. Мы
    использовали IP камеры Axis, модель 207 (со встроенным микрофоном).
    Для нашего случая выглядело так:
    netcam_url
    http://camera_ip/axis-cgi/mjpg/video.cgi?resolution=640×480
    где camera_ip — IP адрес камеры 🙂
    3. далее находим строку target_dir — здесь указываем путь к папке, где будем
    хранить данные с камеры.
    4. а теперь начинается самое интересное. Находим строку on_event_start. Здесь
    мы прописываем команду, которая будет выполняться при наступлении события, то
    есть при движении. Что нам это дает? А дает нам это то, что мы не будем
    постояно вести запись, а только по необходимости — есть движение, идет запись,
    закончилось, остановились и мы. Таким образом получается экономия. Для
    сравнения — у нас ведется запись с 10 камер — цветная картинка 640х480 со
    звуком, записи хранятся 21 день и все это дело занимает на диске в среднем 135
    GB, а всесте с фото, которые делает motion около 200 GB.
    5. следующая строка: on_event_end — это для команды, отрабатывающей по
    окончанию события.
    6. И еще один нюанс, motion поднимает небольшой http сервер, а так как для
    каждой камеры запускается своя инстанция программы с отдельным конфигом, то
    важно, чтобы он слушал на разных портах. Для этого проверяем, чтобы следующие
    строки отличались в каждом файле:
    webcam_port и control_port
    Для примера: для первой камеры ставим значения
    webcam_port 8081
    control_port 8080
    для второй
    webcam_port 8083
    control_port 8082
    и так далее.

    Это в принципе основные изменения. Думаю при внимательном прочтении конфига вы
    сами найдете нужные вам параметры, так как там все довольно хорошо
    задокументировано.

    Теперь вернемся к скриптам, которые отрабатывают при начале и окончании
    события.
    Так как нам надо писать видео с камеры, то для этого я использовал mencoder.
    В папке /root/bin/ создаем скрипты recordstart.sh и recordstop.sh, которые
    будут запускаться при наступлеии и окончании события соответсвенно.
    Давайте заглянем внутрь recordstart.sh:

    [root@video bin]# cat /root/bin/recordstart.sh
    #!/bin/bash

    # We are using two variables
    # 1 — camera name
    # 2 — directory name (where file will be stored)

    # Generate filename
    start=«cam$<1>»
    dt=`date +%Y%m%d%H%M%S`
    FILENAME=»$-$

    .avi»
    echo $FILENAME

    if [ «$1» -eq 218 ]
    then
    `/usr/bin/mencoder -ovc copy -oac pcm -delay 1.5 -mc 10 -o
    /video/motion/$2/$FILENAME rtsp://192.168.95.218/mpeg4/media.amp > /dev/null`
    elif [ «$1» -eq 219 ]
    then
    `/usr/bin/mencoder -ovc copy -oac pcm -delay 1.5 -mc 10 -o
    /video/motion/$2/$FILENAME rtsp://192.168.95.219/mpeg4/media.amp > /dev/null`
    else
    `/usr/bin/mencoder -ovc copy -oac pcm -mc 10 -o /video/motion/$2/$FILENAME
    rtsp://192.168.95.$1/mpeg4/media.amp > /dev/null`
    fi

    Скрипт принимает два параметра:
    1 — имя камеры, хотя имя не совсем верно, так как это последний октет из IP
    адреса камеры. То есть, как в нашем случае (мы используем 95 подсеть — 192.168.95.0/24). Таким образом, при передаче значения 211 — будет ясно, что
    хотим обратиться к камере с IP 192.168.95.211
    2 — директория, где будет храниться записанный файл. Сделано для того, чтобы
    легче было искать. Опять же в нашем случае: имеется папка /video/motion в
    которой хранятся записи, но для того, чтобы не мешать все в кучу, она содержит
    поддиректории зон: kuhnya, balkon и т.д. Значит при передаче значения balcon — запись будеть производиться в директорию /video/motion/balkon.

    Читайте также:  Windows не удалось подготовить компьютер что делать

    Итак, при вызове скрипта в виде /root/bin/recordstart.sh 211 balkon — скрипт
    будет писать с камеры с IP 192.168.95.211 в директорию /video/motion/balkon.
    Надеюсь тут все более-неменее ясно 🙂

    Как видно, вначале мы генерируем уникальное имя для файла, в который будем
    писать, которое состоит из следующих частей:
    start — номер камеры, вернее последний октет из ее IP с предшествующим ей cam.
    dt — текущая дата в формате ГГГГММДДччммсс.
    Пример имени файла: cam218-20090924131847.avi — то есть, пишется с камеры с IP
    192.168.95.218, дата начала: 2009 год, 09 месяц, 24 число, 13 часов, 18 минут,
    47 секунд.

    Небольшое пояснение: так уж оказалось, что у нас разные модели камер, которые
    предоставляют разные способы доступа к потоку видео данных, из-за этого
    пришлось ввести в скрипте проверки.
    Теперь пройдемся по mencoder-у:
    -ovc copy — означает, что видеоряд копируем, так как с камеры сразу идет в
    mpeg4
    -oac pcm — какой кодек использовать для звуковой дорожки, если камера позволяет
    писать звук.
    -mc 10 — Максимальная величина корректировки A-V синхронизации на один кадр (в
    секундах)
    -delay 1.5 — Задержка в мс, которая должна вноситься в каждый канал

    Если у вас проблемы с синхронизацией видео и звукового ряда, тогда надо менять
    значения для последних двух параметров — mc и delay.
    Для теста можно использовать mplayer.

    Ну вот, теперь при наступлении события, мы можем запускать данный скрипт.
    Таким образом в конфиге для motion для нашей камеры прописываем в строке
    on_event_start что-то похожее:
    on_event_start «/root/bin/recordstart.sh 210 koridor1»

    И он начнет писать :)))
    Но ведь это все еще надо остановить :)))
    Для этого используем второй скрипт /root/bin/recordstop.sh.

    [root@video bin]# cat /root/bin/recordstop.sh
    #!/bin/bash

    # We are using one variable
    # 1 — camera name

    # Get string with mencoder process PID
    MPID=`ps ax | grep mencoder | grep cam$ <1>| awk ‘< print $1 >‘`

    # Kill process
    `kill -15 $MPID`

    Скрипт принимает один параметр — все тот же последний октет из IP адреса
    камеры.

    Соответсвенно в строке on_event_end файла конфигурации прописываем что-то
    вроде:
    on_event_end «/root/bin/recordstop.sh 210»

    Ну вот примерно и все, что касается конфигурации.
    Теперь перейдем к рутинным операциям 🙂
    У меня используются две, которые отрабатывают по крону.
    1. Удаляет устаревшие файлы, которые страрше 21 дня.
    2. Объединяет все файлы за день в один.

    Рассмотрим скрипт для чистки. У меня он располагается в директории /root/sbin
    и,
    для того, чтобы враги не догадались, называется clean.sh

    ]# cat /root/sbin/clean.sh
    #!/bin/sh

    /bin/find /video/balkon -name «*.*» -mtime +21 -delete
    /bin/find /video/motion/balkon -name «*.*» -mtime +21 -delete

    В первой директории хранятся фотографии, сделанные motion — это параметр из
    файла конфигурации в строке target_dir.
    Вторая директория — куда пишется видео, запущенное из скрипта recordstart.sh

    А вот второй скрипт посложнее.
    [root@video

    ]# cat /root/sbin/concatfiles.py
    import os, stat, types, commands

    workDir = ‘/video/motion/’
    dirs = os.listdir(workDir)
    oldDate = summaryFile = summaryFileTmp = »
    for dir in dirs:
    filesList = os.listdir(workDir + dir)
    filesList.sort()
    for file in filesList:
    tmpN = file.split(‘.’)
    nm = tmpN[0]
    tmpN = nm.split(‘-‘)
    if tmpN[0] != ‘S’:
    nm = tmpN[1]
    year = nm[0:4]
    month = nm[4:6]
    day = nm[6:8]
    date = year + month + day
    if oldDate != date:
    summaryFile = workDir + dir + ‘/S-‘ + tmpN[0] + ‘-‘ + year +
    month + day + ‘.avi’
    summaryFileTmp = workDir + dir + ‘/S-‘ + tmpN[0] + ‘-‘ + year +
    month + day + ‘-tmp.avi’
    #conactenate files
    command = ‘/usr/bin/mencoder -oac copy -ovc copy ‘ + workDir +
    dir + ‘/’ + tmpN[0] + ‘-‘ + date + ‘*.avi -o ‘ + summaryFileTmp
    os.system(command)
    #fix key frame
    command = ‘ffmpeg -i ‘ + summaryFileTmp + ‘ -ss 0.04 -vcodec
    copy -acodec copy -vcodec copy -acodec copy ‘ + summaryFile
    os.system(command)
    #remove tmp file
    command = ‘/bin/rm -f ‘ + summaryFileTmp
    os.system(command)
    #remove old files
    command = ‘/bin/rm -f ‘ + workDir + dir + ‘/’+ tmpN[0] + ‘-‘ +
    date + ‘*.avi’
    os.system(command)
    oldDate = date

    Это для объединения коротких роликов за день в один суммарный. (Для тех кто не
    в курсе — он на питоне).
    Единственное, что нужно менять — это переменная workDir — путь, куда mencoder
    пишет свои файлы, все из того же recordstart.sh

    Прописываем их в крон на выполнение раз в сутки, желательно ночью, пока карета
    не превратится в тыкву 🙂

    Запускаем motion следующим образом:
    motion -c /path/to/config/file

    где
    /path/to/config/file — путь к нашему файлу с конфигом 🙂

    А далее запускаем их при загрузке системы.

    Ну вот наверное и все 🙂
    Если будут вопросы — задавайте 🙂

    UPD: будьте внимательны с скриптом на питоне, так как сбилась вся
    табуляция, что для него очень критично.

    Источник

    Оцените статью