PimpedWebcam project added

epvpn
kln 2020-05-08 18:41:29 +02:00
parent 6a46ee3eea
commit 68454e306e
4 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,179 @@
---
title: Pimp my webcam (stream)
author: kaqu
status: Aktiv
difficulty: einfach
time: ~1h
date: 2020-05-07
image: /images/PimpedWebcam/webcam_modified.jpg
keywords: webcam, opencv, akvcam
---
## Motivation ##
In unserer wöchentlichen Videokonferenz ('Corona') hat Kresse vor ca. 10 Tagen etwas über 'webcamoid' erzählt.
Das klang interessant! Gleich am nächsten Tag habe ich mir die Installation (auf Mint 19.3) vorgenommen, scheiterte aber
(nach erfolgreichem make) zunächst am 'make install' für akvcam mit einer obskuren Fehlermeldung
(file crypto irgendwas not found???).
Also wieder deinstalliert mit 'make uninstall', das klappte einwandfrei. Trotzdem gab ich zunächst auf ...
Am übernächsten Tag hatte ich mir vorgenommen, die Sache genauer zu untersuchen. Wie sich herausstellte,
war bis auf diese 'überflüssige' Fehlermeldung alles ok!
Das Kernelmodul 'akvcam' installiert zwei zusätzliche - virtuelle - Video-Devices, eins zum Reinschreiben ('output'),
eins zum Auslesen ('capture'). Wenn man jetzt den originalen Webcam-Stream mit einem Programm entgegen nimmt
und ggf. verfremdet ('pimped') kann man diesen an den Videoport zum Reinschreiben übergeben und an den
Videoport zum Auslesen ('virtual camera') einen beliebigen Client für die Wiedergabe hängen!
Streamflow also wie folgt:
Webcam->/dev/video(x)->Bsp. 'webcamoid' u.ä.->/dev/video(n)->akvcam->/dev/video(n+1)->z.Bsp. Browser (Jitsi)
Zum Testen nehme ich 'guvcview', danach kann man mit dem Browser (WebRTC) dieses virtuelle Gerät ebenfalls nutzen
(Nicht: Parallel!). Komplett störungsfrei funktioniert z.Bsp. Jitsi derzeit (5/2020) im Chromium-Browser, in Brave
geht nur die Kachelanzeige, im Firefox klappt es mal/mal nicht ...
In der Ausgangskonstellation habe ich 'webcamoid' getestet. Nett (viele parametrierbare Effekte), aber irgendwie
sinnlos! Wie wäre es stattdessen mit eigenem 'Aufbrezeln' mittels OpenCV/Python?
In der Nutzungsanleitung zu 'akvcam' wird gezeigt, wie man (testweise) Streams an das Videodevice schicken kann,
d.h. so einen Stream müsste man nur selbst produzieren, ins Device schreiben - et voilà, ein selbstgebauter
'custom' Stream!
Ein wenig Internet-Recherche ergab: Video Frames können aus OpenCV/Python über stdout als Bytes direkt ausgegeben
werden (ja, auch auf die Konsole ... ;). Damit stehen einfachen Manipulationen Tür und Tor offen!
Hier mal die Resultate, zwecks Vergleich
vorher:
<img style="max-width: 300px"
alt="ohne"
src="/images/PimpedWebcam/webcam_blank.jpg"
/>
und nachher:
<img style="max-width: 300px"
alt="ohne"
src="/images/PimpedWebcam/webcam_modified.jpg"
/>
Hint: Die Kamera war wohl abgeklebt ...
## Installationshinweise ##
1. Zunächst muß akvcam installiert werden (https://github.com/webcamoid/akvcam). Einfach mit git clonen oder
als ZIP runterladen (dann entpacken im eigenen Benutzerverzeichnis).
2. Verzeichnis umbenennen auf akvcam
3. cd ~/akvcam/src
4. make (Übersetzen sollte einwandfrei durchlaufen ...)
5. sudo make install (hier kommt die überflüssige Fehlermeldung)
6. sudo depmod -a
7. ls /lib/modules/$(uname -r)/extra/akvcam.ko* (Prüfen, ob im Zielverzeichnis angekommen ...)
8. sudo mkdir -p /etc/akvcam (Konfigurationsdatei erstellen)
9. sudo touch /etc/akvcam/config.ini
10. config.ini editieren (Daten siehe https://github.com/webcamoid/akvcam/blob/master/ports/ci/travis/config.ini)
11. sudo chmod -vf 600 /etc/akvcam/config.ini
12. ls /dev/video* (Bekannte Videoports des eigenen Rechners merken)
13. sudo modprobe videodev
14. sudo insmod akvcam.ko (Jetzt Kernelobject aktivieren)
15. ls /dev/video* (Neu hinzu gekommene - virtuelle - Videoports gehören zur akvcam)
16. cat /dev/urandom > /dev/video4 (White noise kann z.Bsp. mit 'guvcview' getestet werden)
17. cat /dev/video5 (Test: Stream von virtuellem Gerät auf Konsole ausgeben ...)
18. sudo apt install virtualenv (Falls für Python keine virtuellen Umgebung zur Verfügung stehen ...)
19. virtualenv cv --python="python3" (Ansonsten eins für OpenCV vorbereiten)
20. source cv/bin/activate (Aktivieren nicht vergessen!)
21. pip3 install opencv-python (Nur in die virtuelle Umgebung OpenCV installieren)
22. python3 -c "import cv2" (Und testen ...)
## Programmaufteilung ##
Da ich die (virtuelle) Kamera nicht immer aktiv haben möchte (wer weiss, vielleicht war die 'crypto'
Fehlermeldung das letzte Röcheln des integrierten Bitcoin-Schürf-Clients ...), habe ich ein bash-Script
vorgesehen mit folgendem Ablauf:
1. akvcam Kernelmodul aktivieren
2. 'cv' python environment aktivieren
3. Python Script laufen lassen mit Ausgabeumleitung an ersten virtuellen Videoport
4. Extern --> Webcam-Applikation (guvcview, browser etc.) an zweiten virtuellen Videoport
5. Extern --> Webcam-Applikation besser als erstes wieder stoppen ...
6. Benutzerabbruch im Script erfolgt mit Strg-C
7. akvcam (die virtuellen Kameras) werden wieder entladen (System wieder sauber!)
virtcam.sh:
echo "Installing video4 (output) / video5 (capture) virtual devices ..."
cd ~/akvcam/src
sudo modprobe videodev
sudo insmod akvcam.ko
echo "Starting 'stream modifier' application ..."
echo "Activating (cv) environment ..."
source ~/cv/bin/activate
cd ~/cv
ls /dev/video?
python3 funcam.py > /dev/video4 # video4 is output device -> video4 is capture
echo "Removing virtual (camera) devices ..."
sudo rmmod akvcam.ko
echo "Done."
Die eigentliche Action erfolgt im Python-Script ('funcam.py'):
import numpy as np
import datetime, time
import sys
import cv2
# Hint: print() to stderr (fh#2) as the actual video stream goes to stdout (fh#1)!
print("funcam started ...",file=sys.stderr)
cap = cv2.VideoCapture(0) # TODO: You have to verify, if /dev/video0 is your actual webcam!
if not cap.isOpened(): # if not open already
cap.open() #make sure, we will have data
# Adjust channel resolution & use actual
cap.set(3, 640)
cap.set(4, 480)
while(cap.isOpened()):
try:
ret, frame = cap.read()
if ret==True:
frame4 = cv2.cvtColor(frame.copy(),cv2.COLOR_BGRA2RGB) # Correct color space
# Now: The fun stuff! -------------------------------------------------------------------------------------------
# ... <your job in here, use cv2.line/cv2.rectangle etc. freely but be careful w/ time consuming operations!> ...
# As a sample, we display the current time
t = time.strftime("%H:%M:%S", time.localtime())
cv2.putText(frame4, t, (505,472), (cv2.FONT_HERSHEY_DUPLEX), 1.4, (0, 0, 0), 4, cv2.LINE_AA)
# End of fun stuff! ---------------------------------------------------------------------------------------------
# Write raw output (pipe/redirect to video device externally!)
sys.stdout.buffer.write(frame4.tobytes())
else:
break
except:
break
cap.release()
print("\nfuncam terminated.",file=sys.stderr)
## Arbeitsablauf ##
1. Bash Script 'funcam.sh' laufen lassen (in Terminalfenster)
2. Client starten, für Videokonferenzen (z.Bsp. mit Jitsi) Browser mit passendem Link starten
3. ... Blabla, Bullshit ... Bingo! ...
4. Client beenden
5. Im Terminalfenster Script ordentlich beenden (mit Strg-C!)
Und hier ein klein wenig 'Live' zum Anfixen mit einfachen Effekten:
<video width="640" height="480" controls>
<source src="/images/PimpedWebcam/webcam_fun.webm" type="video/webm">
</video>
## Was bleibt zu tun? ##
- Projekt auf unser git schmeissen
- Parametrierbarkeit herstellen (Koordinaten, Daten etc.)
- Modularisieren, Refactoring ...
- Virtuelle Webcam (video<x>) automatisch ermitteln (im Bash-Script)
- Greenscreen zwecks Einblendung beliebiger Hintergründe ermöglichen
- Andere Auflösungen - insbesondere 1280x720 - möglich?
- ... whatever ...

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB