(oder das Projekt, das früher als DeepBackSub bekannt war)
(Dank für die schönen Hintergründe geht an Mary Sabell und PhotoFunia)
backscrub ist unter der Apache-Lizenz 2.0 lizenziert. Weitere Informationen finden Sie in der LICENSE-Datei.
Abhängigkeiten installieren ( sudo apt install libopencv-dev build-essential v4l2loopback-dkms curl
).
Klonen Sie dieses Repository mit git clone --recursive https://github.com/floe/backscrub.git
. Um den Checkout zu beschleunigen, können Sie zusätzlich --depth=1
an git clone
übergeben. Dies ist in Ordnung, wenn Sie nur den Code herunterladen und erstellen möchten, für die Entwicklung wird dies jedoch nicht empfohlen.
Verwenden Sie cmake
, um das Projekt zu erstellen: Erstellen Sie einen Unterordner (z. B. build
), wechseln Sie in diesen Ordner und führen Sie Folgendes aus: cmake .. && make -j $(nproc || echo 4)
.
Veraltet : Eine weitere Möglichkeit, alles zu erstellen, besteht darin, make
im Stammverzeichnis des Repositorys auszuführen. Dadurch werden zwar alle Abhängigkeiten heruntergeladen und erstellt, es gibt jedoch einige Nachteile, wie z. B. fehlende Unterstützung für XNNPACK. Dies kann auch bei neueren Versionen von Tensorflow Lite zu Problemen führen, da die Upstream-Unterstützung für diese Option entfernt wurde. Die Nutzung erfolgt auf eigenes Risiko.
Laden Sie zunächst das v4l2loopback-Modul (zusätzliche Einstellungen sind erforderlich, damit Chrome funktioniert):
sudo modprobe v4l2loopback devices=1 max_buffers=2 exclusive_caps=1 card_label="VirtualCam" video_nr=10
Führen Sie dann Backscrub aus (-d -d für vollständiges Debuggen, -c für Erfassungsgerät, -v für virtuelles Gerät, -b für Hintergrundbild):
./backscrub -d -d -c /dev/video0 -v /dev/video10 -b ~/wallpapers/forest.jpg
Einige Kameras (wie z. B. Logitec Brio
) müssen die Videoquelle durch Übergabe von -f MJPG
auf MJPG
umstellen, damit höhere Auflösungen zur Verfügung stehen.
Richten Sie für die regelmäßige Verwendung eine Konfigurationsdatei /etc/modprobe.d/v4l2loopback.conf
ein:
# V4L loopback driver
options v4l2loopback max_buffers=2
options v4l2loopback exclusive_caps=1
options v4l2loopback video_nr=10
options v4l2loopback card_label="VirtualCam"
Um den Treiber beim Start automatisch zu laden, erstellen Sie /etc/modules-load.d/v4l2loopback.conf
mit dem folgenden Inhalt:
v4l2loopback
Getestet mit den folgenden Abhängigkeiten:
Getestet mit folgender Software:
-c read
)-c read
)In diesen modernen Zeiten, in denen jeder zu Hause sitzt und die ganze Zeit skypt/zoomt/webrtc-ing, war ich ein bisschen genervt davon, dass ich der Welt immer mein unordentliches Homeoffice zeigen musste. Skype verfügt über eine Funktion zum „Hintergrund verwischen“, aber das wird nach einer Weile langweilig (und es ist weniger privat, als ich persönlich gerne hätte). Zoom verfügt über einige eingebaute Hintergrundersetzungsdinge, aber ich berühre diese Software nicht mit einem Bargepole (und diese Funktion ist unter Linux sowieso nicht verfügbar). Deshalb habe ich beschlossen, zu prüfen, wie ich meine eigene Implementierung umsetzen kann, ohne auf eine bestimmte Videokonferenzsoftware angewiesen zu sein, die dies unterstützt.
Dieser ganze Kram umfasst drei Hauptschritte mit unterschiedlichem Schwierigkeitsgrad:
Ich habe zuvor viel mit Tiefenkameras gearbeitet, auch für die Hintergrundsegmentierung (siehe SurfaceStreams), also habe ich mir einfach eine übrig gebliebene RealSense-Kamera aus dem Labor geschnappt und es ausprobiert. Allerdings sind die Tiefendaten in einer überfüllten Büroumgebung ziemlich verrauscht, und egal wie ich die Kameraeinstellungen angepasst habe, es konnten keine Tiefendaten für meine Haare erzeugt werden ...? Ich sah aus wie ein mittelalterlicher Mönch, dem der Scheitel seines Kopfes abgehackt wurde, also ... als nächstes.
Siehe https://docs.opencv.org/3.4/d1/dc5/tutorial_background_subtraction.html für ein Tutorial. Sollte bei überwiegend statischen Hintergründen und kleinen sich bewegenden Objekten gut funktionieren, funktioniert jedoch nicht bei überwiegend statischen Personen vor einem statischen Hintergrund. Nächste.
Siehe https://docs.opencv.org/3.4/db/d28/tutorial_cascade_classifier.html für ein Tutorial. Funktioniert einigermaßen, erkennt aber offensichtlich nur das Gesicht und nicht den Rest der Person. Außerdem entspricht es nur ungefähr einer Ellipse, was am Ende eher seltsam aussieht. Nächste.
Ich habe viel Gutes über dieses Deep-Learning-Thema gehört, also versuchen wir es mal. Ich musste mich zunächst durch einen Haufen Frameworks (Keras, Tensorflow, PyTorch usw.) zurechtfinden, aber nachdem ich ein fertiges Modell zur semantischen Segmentierung auf Basis von Tensorflow Lite (DeepLab v3+) gefunden hatte, habe ich mich dafür entschieden.
Ich habe mir die entsprechenden Python-Beispiele, C++-Beispiele und Android-Beispiele angeschaut und darauf basierend zunächst eine Python-Demo zusammengestellt. Das lief mit etwa 2,5 FPS, was wirklich unglaublich langsam ist, also habe ich eine C++-Version erstellt, die 10 FPS ohne allzu große Handoptimierung schafft. Gut genug.
Ich habe auch eine mit TFLite konvertierte Version des Body-Pix-Modells getestet, aber die Ergebnisse unterschieden sich bei diesem Anwendungsfall nicht wesentlich von denen von DeepLab.
Vor Kurzem hat Google ein speziell für die Personensegmentierung trainiertes Modell veröffentlicht, das in Google Meet verwendet wird. Dies bietet sowohl hinsichtlich der Geschwindigkeit als auch der Genauigkeit eine weitaus bessere Leistung als DeepLab und ist daher jetzt die Standardeinstellung. Es ist eine benutzerdefinierte Operation aus dem MediaPipe-Framework erforderlich, die jedoch recht einfach zu integrieren war. Vielen Dank an @jiangjianping für den Hinweis in der entsprechenden Ausgabe.
Dies ist im Grunde eine Codezeile mit OpenCV: bg.copyTo(raw,mask);
Ich habe dir gesagt, dass das der einfache Teil ist.
Ich verwende v4l2loopback, um die Daten von meinem Userspace-Tool an jede Software weiterzuleiten, die ein V4L2-Gerät öffnen kann. Aufgrund der schönen Beispiele ist das nicht allzu schwierig, aber es gibt einige Haken, vor allem den Farbraum. Es bedurfte einiger Versuche, um ein gemeinsames Pixelformat zu finden, das von Firefox, Skype und guvcview akzeptiert wird: YUYV. Erfreulicherweise kann meine Webcam YUYV direkt als Rohdaten ausgeben, sodass ich mir einige Farbraumkonvertierungen erspare.
Der Datenfluss durch das gesamte Programm ist ungefähr wie folgt:
write()
Daten auf virtuelles Videogerät(*) Dies sind erforderliche Eingabeparameter für dieses Modell
Wie immer: Pull-Requests willkommen.
Informationen zu derzeit besprochenen/in Bearbeitung befindlichen Erweiterungen finden Sie unter „Probleme“ und „Pull-Anfragen“ und sehen Sie sich auch den experimental
Zweig an.
Von Firefox bevorzugte Formate: https://searchfox.org/mozilla-central/source/third_party/libwebrtc/webrtc/modules/video_capture/linux/video_capture_linux.cc#142-159
Wir wurden darüber informiert, dass einige Snap-Versionen von obs-studio
eine virtuelle Kamera, wie sie von backscrub
bereitgestellt wird, nicht erkennen/verwenden können. Bitte überprüfen Sie die Details für Problemumgehungen, falls dies auf Sie zutrifft.