Выбрать главу

self.send_response(200)

self.send_header('Content-type', 'image/jpg')

self.end_headers()

f = open('image.jpg', 'rb')

self.wfile.write(f.read())

f.close()

except:

pass

return

with open('index.html', 'r') as imgfile:

self.send_response(200)

self.send_header('Content-type', 'text/html')

self.end_headers()

data = imgfile.read()

self.wfile.write(data)

if __name__ == "__main__":

# Start photos shooting

cmd = 'fswebcam -r 640x480 --loop 10 image.jpg'

photoThread = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)

# Start server

server_address = ('', 8000)

httpd = HTTPServer(server_address, Server)

print 'Starting httpd...'

try:

httpd.serve_forever()

except:

pass

# Close photo shooting

os.kill(photoThread.pid, signal.SIGINT)

Как можно видеть, все вполне просто. Если в строке запроса присутствует “image.jpg”, мы загружаем картинку, иначе “index.html”. Изменить частоту обновления изображений можно, поменяв параметр loop, там же можно поменять и разрешение.

Все готово - запускаем python web.py, и с любого браузера можем зайти на страницу http://192.168.0.104:8000 (адрес может быть другим) и увидеть картинку с камеры. Это можно будет сделать и удаленно, если настроить статический IP адрес и перенаправление порта 8000 на роутере.

Чтобы сервер автоматически стартовал при запуске Raspberry Pi, нужно будет добавить строку вызова в /etc/rc.local, например так:

cd /home/pi/Documents/Cam

python /home/pi/Documents/Cam/web.py &

Важно: поскольку сервер постоянно сохраняет изображения локально на карте памяти, это негативно скажется на ее ресурсе - количество операций записи для карт памяти ограничено. Если планируется постоянное использование такого сервера, рекомендуется создать RAM-диск в памяти и указать путь к нему в настройках fswebcam и index.html. Настройку RAM-диска желающие могут найти в онлайн-руководствах по Raspberry Pi.

4.13. Интервальная съемка (time-lapse photo)

С помощью fswebcam несложно делать серию фото, например каждые 5 секунд. Это позволяет делать интересные кадры, например для записи движения Луны или облаков.

Команда для запуска выглядит так:

fswebcam -l 10 -r 1280x720 test-%Y-%m-%d--%H-%M-%S.jpg

Здесь “-l 10” задает временной интервал, “-r 1280x720” задает разрешение, имя файла “test-%Y-%m-%d--%H-%M-%S.jpg” задает шаблон даты и времени.

Можно указывать разные форматы шаблонов даты-времени, воспользовавшись таблицей:

%d

День месяца [01..31]

%H

Час [00..23]

%I

Час в 12-часовом формате [00..12]

%j

День [001..366]

%m

Месяц [01..12]

%M

Минута [00..59]

%S

Секунда [00..59]

%W

Номер недели в году [00..53]

%w

День [0(Вс)..6]

%y

Год, 2х значное число [00..99]

%Y

Год, 4х значное число

Соответственно, при запуске вышеприведенной команды в текущей папке будут создаваться файлы вида test-2018-02-25--12-39-40.jpg, test-2018-02-25--12-40-50.jpg, test-2018-02-25--12-40-00.jpg и т.д. Потом их можно склеить в видео с помощью специальных утилит.

4.14. Подключаемся к камере с помощью OpenCV

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

Для работы с изображениями есть полезная библиотека OpenCV. Для ее установки введем команду: sudo apt-get install python-opencv.

Теперь всего лишь в несколько строк кода, мы можем написать свой аналог fswebcam:

import cv2

import time

cam = cv2.VideoCapture(0) #set the port of the camera as before

try:

count = 0

while True:

retval, image = cam.read() #return a True bolean and and the image if all go right

print count

cv2.imwrite("frame-%d.jpg" % count, image)

count += 1

time.sleep(0.5)

except:

pass

cam.release()

Как можно видеть, мы создаем объект cam = VideoCapture и с помощью функции cam.read читаем изображение. Оно уже хранится в памяти, нам не нужен промежуточный файл, и это большой плюс. В частности, его можно сохранить в папке, вызовом функции cv2.imwrite. Мы также можем сохранять не все изображения, а лишь в случае срабатывания внешнего триггера, например кнопки или реле.

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

Самостоятельная работа: сделать селфи-камеру на Raspberry Pi. Для этого добавить в вышеприведенный код чтения состояния кнопки, и писать изображение в файл только в том случае, если кнопка нажата.

4.15. Запускаем сервер видеотрансляции

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