Webcam Laughing Man face overlay (MediaPipe + OpenCV + Pillow)
Project description
laughing-man
Webcam Laughing Man face overlay (Ghost in the Shell style) using MediaPipe BlazeFace, OpenCV, and Pillow.
Install
From PyPI
Stable releases are published on PyPI:
pip install laughing-man
With uv you can use:
uv pip install laughing-man
After installing, run laughing-man or laughing-man --help (the laughing-man console script is on your PATH).
From source (development)
You need uv on your PATH. Clone the repository:
git clone https://github.com/rnorris7756/laughing-man.git
cd laughing-man
Using direnv (recommended)
direnv loads the repo’s .envrc automatically when you cd into the project (after you allow it once per machine). That keeps the development environment consistent without manually activating a venv each time:
- Install direnv and hook it into your shell (Bash, Zsh, Fish, etc.).
- In the repo root, run
direnv allowso.envrcis trusted. - The next time the environment loads,
.envrcwill:- create
.venvand runuv sync --group devif the venv does not exist yet (installs runtime + dev dependencies fromuv.lock); sourcethat venv whenever you are inside the directory;- run
uv run pre-commit installif the Git pre-commit hook is missing (so Ruff and ty match CI before each commit).
- create
After that, use laughing-man or uv run laughing-man as usual; commands see the activated environment while you stay in the tree.
Without direnv
Install dependencies and the pre-commit hook yourself:
uv sync --group dev
uv run pre-commit install
uv run laughing-man
Run uv run pre-commit install once per clone so Ruff and ty run before each commit (same checks as CI). Git invokes hooks with uv on your PATH.
Virtual webcam (Discord, OBS, browsers)
Use --virtual-cam to expose the composited video as a camera other apps can select.
Linux: v4l2loopback
The virtual device is provided by the v4l2loopback kernel module. Load it before starting the app (often required once per boot):
sudo modprobe v4l2loopback
You can create a named device on a fixed number (example):
sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="LaughingMan"
Then point the CLI at that device if needed:
laughing-man --virtual-cam --v4l2-device /dev/video10
Use --no-preview to stream only to the virtual camera (no OpenCV window); stop with Ctrl+C.
If the module loads at boot and grabs /dev/video0, the real webcam may move to /dev/video1. The CLI defaults to --camera auto, which on Linux picks the first /dev/video* that is not a v4l2loopback output (opening loopback for capture can crash OpenCV). You can also pin the real device with --camera /dev/video1 or load loopback on a fixed high number: sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="LaughingMan".
Package names vary by distro (e.g. v4l2loopback-dkms on Debian/Ubuntu).
Other platforms
On Windows and macOS, pyvirtualcam may use OBS Virtual Camera or other backends when available.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file laughing_man-1.2.3.tar.gz.
File metadata
- Download URL: laughing_man-1.2.3.tar.gz
- Upload date:
- Size: 466.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc8f3aeee7a3ea95e0edd865a916288bea5a0a70e0bb2a669fca97c78a387acd
|
|
| MD5 |
d3e1b6f8bad41289e944cda92c59e1c6
|
|
| BLAKE2b-256 |
67cad2b523c8ec585b282645bfc52620193e419def0b9e97419686fdd3073070
|
Provenance
The following attestation bundles were made for laughing_man-1.2.3.tar.gz:
Publisher:
release.yml on rnorris7756/laughing-man
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
laughing_man-1.2.3.tar.gz -
Subject digest:
cc8f3aeee7a3ea95e0edd865a916288bea5a0a70e0bb2a669fca97c78a387acd - Sigstore transparency entry: 1328792054
- Sigstore integration time:
-
Permalink:
rnorris7756/laughing-man@6e0ffc14e4e1ed49f112dfc4b944e8d7d71efb16 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/rnorris7756
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6e0ffc14e4e1ed49f112dfc4b944e8d7d71efb16 -
Trigger Event:
push
-
Statement type:
File details
Details for the file laughing_man-1.2.3-py3-none-any.whl.
File metadata
- Download URL: laughing_man-1.2.3-py3-none-any.whl
- Upload date:
- Size: 327.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1eeefcb7b25df5cb1e99baa8b48525601b15f8bfbbed1d340972e274b2391a57
|
|
| MD5 |
3cae01a827f5e567bc9ae7f76e89c7f0
|
|
| BLAKE2b-256 |
0dab671a8230cafebf85a1e99691d9b4c06a6ca1aa5d8f369327881b320d0aeb
|
Provenance
The following attestation bundles were made for laughing_man-1.2.3-py3-none-any.whl:
Publisher:
release.yml on rnorris7756/laughing-man
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
laughing_man-1.2.3-py3-none-any.whl -
Subject digest:
1eeefcb7b25df5cb1e99baa8b48525601b15f8bfbbed1d340972e274b2391a57 - Sigstore transparency entry: 1328792104
- Sigstore integration time:
-
Permalink:
rnorris7756/laughing-man@6e0ffc14e4e1ed49f112dfc4b944e8d7d71efb16 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/rnorris7756
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@6e0ffc14e4e1ed49f112dfc4b944e8d7d71efb16 -
Trigger Event:
push
-
Statement type: