Przeglądając pudełko z „archiwalnymi sprzętami” trafiłem na 2 „dość archaiczne” (rozdzielczość 640×480) kamerki internetowe (USB), i tak sobie pomyślałem, że jak mają leżeć tak bezproduktywnie, to lepiej je do jakiejś pracy zaprząc, zwłaszcza że w duecie z Raspberry Pi można z tego zrobić prosty system monitorujący (choć patrząc na jakoś tych kamerek to raczej sztuka dla sztuki, niż realna potrzeba, ale może Wy w swoim pudełku znajdziecie macie lepsze ;-)).
Spis treści w artykule
Raspberry Pi i (web)kamera USB
Kwestia, nad którą chwilę się zastanawiałem to sposób działania takiego systemu – stały podgląd „na żywo”, za pomocą dedykowanej strony internetowej, lub zapis pojedynczych zdjęć w zdefiniowanych odstępach czasu.
Jeśli interesuje Was stały podgląd „na żywo”, to zachęcam do zainteresowania się programem „motion”. Ja zdecydowałem się na pojedyncze zdjęcia, do czego wykorzystam program „fswebcam”, który jest nie tylko bardzo prosty w obsłudze, ale i pozwala na wykorzystanie go w różnych skryptach.
Zgodna z Raspberry Pi kamerka USB
Po podłączeniu obu kamerek postanowiłem sprawdzić czy i jak zgłaszają się w systemie:
sudo lsusb
Jak widać obie kamerki są widoczne w systemie, a to już połowa sukcesu:
Bus 001 Device 008: ID 05a9:a518 OmniVision Technologies, Inc. D-Link DSB-C310 Webcam
[...]
Bus 009 Device 008: ID 0c45:6128 Microdia PC Camera (SN9C325 + OM6802)
Przy czym szybkie testy wykazały, że tylko druga kamerka działa, i zgłasza się w systemie:
RPi01: ls /dev/video0
/dev/video0
Może się zdarzyć, że choć kamerka będzie widoczna na liście urządzeń USB, to podczas próby skorzystania z niej system zwróci komunikat w stylu:
ls: cannot access /dev/video0: No such file or directory
Zanim zrezygnujecie polecam – z podłączoną kamerką – zrobić aktualizację systemu LINK, po czym zrestartować system.
fswebcam – Small and simple webcam software for *nix
Gdy kamerka jest widoczna w systemie, a do tego mamy dostęp do „urządzenia” (/dev/video0) możemy przystąpić do instalacji programu „fswebcam”:
sudo apt-get install fswebcam
Bezpośrednio po instalacji, bez żadnej konfiguracji możemy przystąpić do zapisywania zdjęć z kamerki:
fswebcam -r image.jpg
Jest to oczywiście podstawowe polecenie, i zdecydowanie warto rozbudować je o dodatkowe parametry, np.:
sudo fswebcam -r 640x480 --no-banner image.jpg
Powyższa komenda zapisze obraz „image.jpg” w aktualnym katalogu, o rozdzielczości 640×480 px (akurat tyle obsługuje podłączona do testów kamerka), bez dolnego paska z datą i godziną.
Webinsider.pl: sudo fswebcam -r 640x480 --no-banner image02.jpg
--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
--- Capturing frame...
Captured frame in 0.00 seconds.
--- Processing captured image...
Disabling banner.
Writing JPEG image to 'image02.jpg'.
A tutaj pełna lista dostępnych aktualnie parametrów i ustawień:
-?, --help Display this help page and exit.
-c, --config <filename> Load configuration from file.
-q, --quiet Hides all messages except for errors.
-v, --verbose Displays extra messages while capturing
--version Displays the version and exits.
-l, --loop <seconds> Run in loop mode.
-b, --background Run in the background.
-o, --output <filename> Output the log to a file.
-d, --device <name> Sets the source to use.
-i, --input <number/name> Selects the input to use.
-t, --tuner <number> Selects the tuner to use.
-f, --frequency <number> Selects the frequency use.
-p, --palette <name> Selects the palette format to use.
-D, --delay <number> Sets the pre-capture delay time. (seconds)
-r, --resolution <size> Sets the capture resolution.
--fps <framerate> Sets the capture frame rate.
-F, --frames <number> Sets the number of frames to capture.
-S, --skip <number> Sets the number of frames to skip.
--dumpframe <filename> Dump a raw frame to file.
-s, --set <name>=<value> Sets a control value.
--revert Restores original captured image.
--flip <direction> Flips the image. (h, v)
--crop <size>[,<offset>] Crop a part of the image.
--scale <size> Scales the image.
--rotate <angle> Rotates the image in right angles.
--deinterlace Reduces interlace artifacts.
--invert Inverts the images colours.
--greyscale Removes colour from the image.
--swapchannels <c1c2> Swap channels c1 and c2.
--no-banner Hides the banner.
--top-banner Puts the banner at the top.
--bottom-banner Puts the banner at the bottom. (Default)
--banner-colour <colour> Sets the banner colour. (#AARRGGBB)
--line-colour <colour> Sets the banner line colour.
--text-colour <colour> Sets the text colour.
--font <[name][:size]> Sets the font and/or size.
--no-shadow Disables the text shadow.
--shadow Enables the text shadow.
--title <text> Sets the main title. (top left)
--no-title Clears the main title.
--subtitle <text> Sets the sub-title. (bottom left)
--no-subtitle Clears the sub-title.
--timestamp <format> Sets the timestamp format. (top right)
--no-timestamp Clears the timestamp.
--gmt Use GMT instead of local timezone.
--info <text> Sets the info text. (bottom right)
--no-info Clears the info text.
--underlay <PNG image> Sets the underlay image.
--no-underlay Clears the underlay.
--overlay <PNG image> Sets the overlay image.
--no-overlay Clears the overlay.
--jpeg <factor> Outputs a JPEG image. (-1, 0 - 95)
--png <factor> Outputs a PNG image. (-1, 0 - 10)
--save <filename> Save image to file.
--exec <command> Execute a command and wait for it to complete.
Wykorzystanie w skryptach do stałego monitoringu (timelapse)
Jak wspomniałem na początku, zdecydowałem się na ten program, jak i typ zapisu, by móc zrzucać obraz z kamerki na żądanie, tylko wtedy gdy będzie taka potrzeba.
W tym celu przygotowałem sobie skrypt:
/usr/local/bin/foto
O takiej zawartości:
#!/bin/bash
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
sudo fswebcam -r 640x480 --no-banner -q /ścieżka/do/katalogu/webcam/$TIMESTAMP.jpg
exit
Dzięki czemu każdorazowe wpisanie w konsoli polecenia „foto” zapisze obraz z kamerki w zdefiniowanym katalogu, pod aktualną datą (rok-miesiąc-dzień_godz-min-sek.jpg).
W duecie z harmonogramem zadań (CRON)
Oprócz tego w prosty sposób, za pomocą systemowego harmonogramu zadań (CRON) można ustawić, by zdjęcie było wykonywane automatycznie, w wybranych odstępach czasu, np. co 5 minut:
*/5 * * * * root /usr/local/bin/foto
Broken pipe
Nie wiem czy to kwestia konkretnego modelu lub egzemplarza kamerki czy też tego, że do testów została ona podłączona do Raspberry Pi bezpośrednio, z pominięciem aktywnego HUBa USB, który mógłby kamerkę dodatkowo zasilać, ale co jakiś czas pojawiał się błąd, który blokował dalsze zrzuty z kamerki:
Error starting stream.
VIDIOC_STREAMON: Broken pipe
Najprostsze rozwiązanie – restart Raspberry Pi lub chwilowe wypięcie kamerki z portu USB. Działa, ale nie jest to najlepsze rozwiązanie…
Reset (urządzenia) USB
Chwile poszukałem jakiegoś prostego sposobu, jakby móc w takiej sytuacji w prosty i automatyczny sposób za pomocą jakiegoś polecenia zresetować konkretny port USB/konkretne urządzenie w systemie, ale jeśli już na coś trafiłem, to działało to z różną skutecznością, a tu chodzi o dzianie nie tylko skuteczne, ale i pewne.
Z pomocą przyszedł program napisany w języku C, który można pobrać na Malinę, skompilować i w razie potrzeby uruchomić:
sudo wget -c --no-check-certificate https://gist.githubusercontent.com/x2q/5124616/raw/bf21dbda4a67de2c2d15d6c66b1e1bd0b1db7e1b/usbreset.c -O /usr/local/bin/usbreset.c
sudo cc /usr/local/bin/usbreset.c -o /usr/local/bin/usbreset
sudo chmod +x /usr/local/bin/usbreset
Obsługa jest banalnie prosta, wystarczy znać… adres kamerki:
Webinsider: lsusb
Bus 001 Device 007: ID 0c45:6128 Microdia PC Camera (SN9C325 + OM6802)
W moim przypadku jest to „001” i „007”, a więc polecenie resetujące to:
Webinsider: sudo usbreset /dev/bus/usb/001/007
Resetting USB device /dev/bus/usb/001/007
Reset successful
Automatyzujemy całość
Ale skoro zależy nam na pełnej automatyzacji działania, to połączymy całość w jeden skrypt, a do tego dodamy powiadomienia na adres e-mail w przypadku błędu:
#!/bin/bash
DEV_VIDEO=/dev/video0
DEV_VIDEO_CRC=$(sudo ls /dev/video0)
[email protected]
FOTO_DIR=/ścieżka/do/katalogu/webcam
if [ "$DEV_VIDEO_CRC" == "$DEV_VIDEO" ]
then
echo "OK, robie foto"
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
sudo fswebcam -r 640x480 -d $DEV_VIDEO --no-banner -q $FOTO_DIR/$DATE.jpg
echo "Sprawdzam czy istnieje plik foto"
if [ ! -e $FOTO_DIR/$DATE.jpg ]
then
echo "Brak pliku foto, wysyłam e-mail"
echo -e "Subject: FOTO error\r\n\r\nSkrypt wykrył problem z zapisem pliku" | msmtp -t $EMAIL -d
else
echo "Plik foto OK"
fi
else
echo "Brak "$DEV_VIDEO", wysyłam e-mail"
echo -e "Subject: FOTO error\r\n\r\nSkrypt wykrył problem ze sprzętem" | msmtp -t $EMAIL -d
echo "Naprawiam:"
KEYWORD=Camera
LSUSB=$(lsusb | grep $KEYWORD)
DEVICE="/dev/bus/usb/"$(echo $LSUSB | grep "Camera " | awk '{print $2;}')"/"$(echo $LSUSB | grep "Camera " | awk '{print $4;}' | head -c 3)
echo "Naprawiam: "$LSUSB
echo "Resetuje: "$DEVICE
sudo /usr/local/bin/usbreset $DEVICE
fi
exit
Skrypt sprawdza czy w ogóle dostępne jest urządzenie DEV_VIDEO i jeśli wszystko jest OK, to przechodzi do zdjęcia i na tym kończy swoją pracę.
W przypadku gdy wykryje problem z urządzeniem DEV_VIDEO wykona reset urządzenia, co przynajmniej w moim przypadku skutecznie naprawia problem „pękniętej rury”. Dodatkowo skrypt sprawdza, czy po zapisaniu pliku jest on dostępny – np. jakby zasób dyskowy z jakichś przyczyn przestał być dostępny (przynajmniej dla skryptu).
- Home Assistant 2024.11, czyli „sekcje” domyślnym widokiem z opcją migracji, WebRTC oraz wirtualna kamera - 1970-01-01
- Black Friday w ZUS, czyli jest jeszcze kilka dni, by złożyć wniosek RWS i skorzystać z wakacji składkowych płacąc ZUS za grudzień 2024 - 1970-01-01
- Wakacje składkowe ZUS a zawieszenie działalności gospodarczej, czyli uważaj, bo być może nie będziesz mógł skorzystać (w 2024) - 1970-01-01
Artykuł super, dokładne opisy, niestety mam problem z realizacją. Z jakiegoś powodu nie mogę zainstalować fswebcam.
Najpierw dostaję pytanie:
„Install these packages without verification [y/N]?”, na które odpowiadam „y”,
a następnie otrzymuję komunikat:
„Err http://mirrordirector.raspbian.org/raspbian/ wheezy/main fswebcam armhf 20110717-1
404 Not Found
Failed to fetch http://mirrordirector.raspbian.org/raspbian/pool/main/f/fswebcam/fswebcam_20110717-1_armhf.deb 404 Not Found
E: Unable to fetch some archives, maybe run apt-get update or try with –fix-missing?”
Obawiam się, że coś się zmieniło z tym repozytorium, a w związku z tym pytanie jak można rozwiązać problem.
Z góry bardzo dziękuję,
W
A cały czas używasz starego Raspbiana, czyli opartego na Debian 7 (Wheezy)? Gdy mamy od niedawna już 10…