VEIL is a target-aware video face-swap pipeline that preserves selected target identities and replaces non-target faces in video using face detection, tracking, recognition, and InSwapper.
VEIL processes an input video frame by frame. It detects faces with YOLO, tracks them with BoT-SORT, identifies protected target people with InsightFace/ArcFace embeddings, and swaps only non-target faces with a configured virtual face. Target identities are left unchanged.
The pipeline also writes per-frame tracking metadata, face metadata, logs, and an annotated output video. When a non-target face is too small, occluded, or otherwise unsuitable for swapping, VEIL falls back to blur instead of forcing a low-quality swap.
Source video: Magnific
Virtual face source: This Person Does Not Exist
veil/
├── README.md
├── media/
│ ├── input_test.gif
│ ├── fake_face.jpg
│ └── output_target5.gif
├── scripts/
│ └── download_weights.sh
└── models/
├── requirements.txt
├── boxmot/
│ └── models/
└── veil/
├── main_hybrid.py
├── config.py
├── detector_tracker.py
├── face_identifier.py
├── face_inswapper.py
├── face_utils.py
├── metadata_manager.py
├── crop_manager.py
├── target/
├── virtual_face/
├── videos/
├── weights/
└── outputs/
- Python 3.10 or newer is recommended.
- Python dependencies are managed in
models/requirements.txt. - NVIDIA GPU + CUDA are recommended for practical runtime.
- CPU execution is possible by setting
device = "cpu"inmodels/veil/config.py, but it will be significantly slower. models/requirements.txtincludes ONNX Runtime GPU, CUDA, and TensorRT-related packages. VEIL uses the available provider stack and falls back when a provider is unavailable.curlorwgetis required forscripts/download_weights.sh.
git clone https://github.com/jiminbae/veil
cd veil
python -m venv .venv
source .venv/bin/activate
pip install -r models/requirements.txt
bash scripts/download_weights.shdownload_weights.sh downloads the required model files into models/veil/weights/:
yolo26x-face.ptinswapper_128.onnx
The BoT-SORT ReID weight is stored at models/boxmot/models/osnet_x0_25_msmt17.pt.
Place your files in these paths before running the pipeline:
- Input video:
models/veil/videos/test.mp4 - Protected target images:
models/veil/target/target* - Replacement face image:
models/veil/virtual_face/fake_face.jpg
Target images can be .jpg, .jpeg, .png, .bmp, or .webp. You can provide multiple target images as long as their filenames match target*.
Use clear target images where the protected person's face is visible and easy to detect. The replacement face image should also contain one clear face, preferably front-facing or near front-facing.
You can change these paths and thresholds in models/veil/config.py.
cd models/veil
python main_hybrid.pyEach run automatically chooses the next output index by scanning the existing files under outputs/.
VEIL writes generated files under models/veil/outputs/:
- Annotated result video:
outputs/result/output_target{N}.mp4 - Runtime log:
outputs/log/tracking_target{N}_log.txt - Face metadata:
outputs/metadata/face_metadata{N}.json - Tracking metadata:
outputs/metadata/tracking_metadata{N}.json
The result video includes face boxes and labels. The metadata files include frame numbers, raw track IDs, stable face IDs, bounding boxes, target match status, similarity scores, quality labels, and fallback reasons.
The main settings live in models/veil/config.py:
VIDEO_PATH: input video path.TARGET_DIRandTARGET_PATTERN: protected identity image gallery.TARGET_IMAGE_PATH: replacement face image used by InSwapper.ENABLE_FACE_SWAP: turn face swapping on or off.MAX_SWAP_FACES_PER_FRAME: cap the number of non-target faces swapped per frame.SIM_THRESHOLDandTARGET_THRESHOLD: identity matching thresholds.FACE_SWAP_BATCH_SIZE: batch size used by the swap stage.USE_BOTSORT_REID: enable or disable BoT-SORT ReID features.DETECTION_CONF: face detection confidence threshold.SWAP_MIN_FACE_SIZEandSWAP_MAX_FACE_AREA_RATIO: decide when a detected face is suitable for swapping.ENABLE_MOUTH_PASTE: keeps the original mouth area when blending a swapped face.
- Detect faces using YOLO face weights.
- Track face boxes across frames with BoT-SORT.
- Extract face embeddings with InsightFace/ArcFace.
- Match tracked faces against target images.
- Preserve target identities.
- Swap eligible non-target faces using
inswapper_128.onnx. - Apply blur fallback when swap quality would be unreliable.
- Save output video, logs, and metadata.
No target images found: add at least one image whose filename starts withtargetundermodels/veil/target/.No valid target embeddings loaded: the target image exists, but no face was detected. Try a clearer face image.Cannot open video: check that the input video exists atmodels/veil/videos/test.mp4, or updateVIDEO_PATHinconfig.py.Cannot read target image: checkmodels/veil/virtual_face/fake_face.jpg, or updateTARGET_IMAGE_PATHinconfig.py.
- GPU execution is enabled by default through
device = "cuda"inconfig.py. - ONNX Runtime uses the available provider stack, including TensorRT/CUDA when installed and available.
- Downloaded model weights, local input assets, outputs, logs, and metadata are ignored by git.
- Use VEIL only with appropriate consent and for lawful, responsible video processing.


