GhostCam is a headless virtual camera service that reads a physical camera, applies AI segmentation, composites a new background, and publishes the result to a virtual camera such as UnityCapture.
GhostCam is intentionally built as a very lightweight virtual-camera pipeline. The goal is to avoid the usual heavy desktop stack and keep the runtime as small and direct as possible.
- No OBS dependency
- No GUI application shell
- No browser/Electron runtime
- No scene graph, source graph, or streaming studio layer
- Just camera input, segmentation, compositing, and virtual camera output
In practice, the current runtime is:
PyAVfor camera inputMediaPipefor person segmentationOpenCV-headless+NumPyfor compositingpyvirtualcamfor virtual camera output
So the accurate claim is: this is a very lightweight, no-OBS, headless architecture, not a zero-OpenCV architecture.
- Headless pipeline with no GUI requirement
- Background modes:
image,color,blur - Windows-friendly PM2 startup
- PowerShell helper script for start/stop/setup
- Edge darkening to reduce bright halo around hair and shoulders
On Windows with the current pyvirtualcam + unitycapture backend, GhostCam cannot reliably detect whether another app is actively consuming the virtual camera stream. That means the service may keep the physical camera open while it is running. If you want to fully restore the default camera, stop GhostCam first.
Install the UnityCapture driver if you have not already:
- Open
drivers/UnityCapture/Install/Install.batas Administrator. - Confirm that a virtual camera such as
Unity Video Captureappears in meeting apps.
pipx install .Update an existing install:
pipx install --force .python -m venv .venv
.venv\Scripts\python -m pip install --upgrade pip
.venv\Scripts\python -m pip install -r requirements.txtRecommended when you want to test parameters quickly.
ghostcam --input "video=Integrated Camera" --width 1280 --height 720 --fps 30 --background-mode image --background-image tests\test_background.webpThe default PM2 config is in ecosystem.config.js. It currently starts GhostCam with:
--background-mode color--background-color #ECE8E0--blur-strength 21
Start:
pm2 start ecosystem.config.jsView logs:
pm2 logs ghostcamStop:
pm2 stop ghostcam
pm2 delete ghostcamUse GhostCam.ps1 for local control:
powershell -ExecutionPolicy Bypass -File .\GhostCam.ps1 startStop GhostCam and restore the default camera path:
powershell -ExecutionPolicy Bypass -File .\GhostCam.ps1 stopSetup the local venv:
powershell -ExecutionPolicy Bypass -File .\GhostCam.ps1 setup--input: physical camera name/path. Windows example:video=Integrated Camera--width: output width--height: output height--fps: output frame rate
--background-mode: one ofimage,color,blur--background-image: path to the replacement image--background-color: solid background color in hex, for example#222222--blur-strength: odd blur kernel size; higher means stronger blur
Examples:
ghostcam --input "video=Integrated Camera" --background-mode image --background-image tests\test_background.webpghostcam --input "video=Integrated Camera" --background-mode color --background-color "#111111"ghostcam --input "video=Integrated Camera" --background-mode blur --blur-strength 31If Integrated Camera does not come back normally, stop GhostCam first:
powershell -ExecutionPolicy Bypass -File .\GhostCam.ps1 stopThat stop flow will:
- stop and delete the PM2
ghostcamprocess when present - kill any leftover
ghostcam.exe - kill leftover Python processes started by GhostCam
- restart common Windows camera host processes so other apps can reacquire the camera
- Optional background image asset: test_background.webp
- Default PM2 solid background color:
#ECE8E0
MIT