Skip to content

Instantly share code, notes, and snippets.

@hughpearse
Last active January 30, 2023 14:32
Show Gist options
  • Save hughpearse/2e4f90999a230bdff9ba823826a98a70 to your computer and use it in GitHub Desktop.
Save hughpearse/2e4f90999a230bdff9ba823826a98a70 to your computer and use it in GitHub Desktop.
desktop webcam app
#python37
# Author: Hugh Pearse
# Description: display webcam with background removal (body segmentation) in transparant window and follow mouse cursor
#
# Setup instructions:
# python -m venv sandbox
# sandbox\Scripts\activate
# pip install absl-py==1.4.0 astunparse==1.6.3 cachetools==5.3.0 certifi==2022.12.7 charset-normalizer==3.0.1 flatbuffers==23.1.21 gast==0.4.0 google-auth==2.16.0 google-auth-oauthlib==0.4.6 google-pasta==0.2.0 grpcio==1.51.1 h5py==3.8.0 idna==3.4 importlib-metadata==6.0.0 keras==2.11.0 libclang==15.0.6.1 Markdown==3.4.1 MarkupSafe==2.1.2 numpy==1.23.5 oauthlib==3.2.2 opencv-python==4.7.0.68 opt-einsum==3.3.0 packaging==20.9 Pillow==9.4.0 protobuf==3.19.6 pyasn1==0.4.8 pyasn1-modules==0.2.8 pyfakewebcam==0.1.0 pyparsing==3.0.9 PyQt5==5.15.8 PyQt5-Qt5==5.15.2 PyQt5-sip==12.11.1 requests==2.28.2 requests-oauthlib==1.3.1 rsa==4.9 six==1.16.0 tensorboard==2.11.2 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.1 tensorflow==2.11.0 tensorflow-estimator==2.11.0 tensorflow-hub==0.12.0 tensorflow-intel==2.11.0 tensorflow-io-gcs-filesystem==0.30.0 tensorflowjs==3.18.0 termcolor==2.2.0 tf-bodypix==0.4.2 tfjs-graph-converter==1.6.1 typing_extensions==4.4.0 urllib3==1.26.14 Werkzeug==2.2.2 wrapt==1.14.1 zipp==3.12.0
# python ./app.py
#
# Statically compile:
# open anaconda console
# sandbox\Scripts\activate
# pip install pyinstaller==5.7.0
# pyinstaller app.py -F --noconsole
# .\dist\app.exe
#
# References
# https://www.codepile.net/pile/ey9KAnxn
# https://github.com/nicknochnack/BodyPixBackgroundRemoval/blob/main/BodyPix%20Background%20Removal.ipynb
# https://pypi.org/project/tf-bodypix/
import sys
from PyQt5.QtGui import (QImage, QPixmap, QCursor)
from PyQt5.QtWidgets import (QWidget, QApplication, QVBoxLayout, QLabel)
from PyQt5.QtCore import (Qt, pyqtSignal, QThread)
import cv2
from tf_bodypix.api import download_model, load_model, BodyPixModelPaths
from time import sleep
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.VBL = QVBoxLayout()
self.FeedLabel = QLabel()
self.VBL.addWidget(self.FeedLabel)
self.Worker1 = Worker1()
self.Worker1.start()
self.Worker1.ImageUpdate.connect(self.ImageUpdateSlot)
self.setLayout(self.VBL)
def ImageUpdateSlot(self, Image):
self.FeedLabel.setPixmap(QPixmap.fromImage(Image))
cursor = QCursor()
cursor_pos = cursor.pos()
self.move(round( cursor_pos.x() - Image.width() / 2), round(cursor_pos.y()))
def CancelFeed(self):
self.Worker1.stop()
class Worker1(QThread):
ImageUpdate = pyqtSignal(QImage)
def run(self):
self.ThreadActive = True
Capture = cv2.VideoCapture(0)
self.bodypix_model = load_model(download_model(
BodyPixModelPaths.MOBILENET_FLOAT_50_STRIDE_16
))
while self.ThreadActive:
ret, frame = Capture.read()
width,height,dimension=frame.shape
newWidth, newHeight = round(width // 2), round(height // 2)
frame = cv2.resize(frame, (newHeight, newWidth))
if ret:
sleep(0.05)
result = self.bodypix_model.predict_single(frame)
mask = result.get_mask(threshold=0.5).numpy().astype(dtype='uint8')
mask = result.get_part_mask(mask, ["left_face","right_face"])
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
Image = cv2.bitwise_and(frame, frame, mask=mask)
FlippedImage = cv2.flip(Image, 1)
ConvertToQtFormat = QImage(FlippedImage.data, FlippedImage.shape[1], FlippedImage.shape[0], QImage.Format_RGBA8888)
Pic = ConvertToQtFormat.scaled(round(640/3), round(480/3), Qt.KeepAspectRatio)
self.ImageUpdate.emit(Pic)
def stop(self):
self.ThreadActive = False
self.quit()
if __name__ == "__main__":
App = QApplication(sys.argv)
Root = MainWindow()
Root.show()
sys.exit(App.exec())
@hughpearse
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment