Commit Graph
629 Commits
Author SHA1 Message Date
Nguyen Van NamandGitHub 8234965ee8 fix: clamp video frame seek index (#1790)
Prevent get_video_frame() from seeking to invalid frame positions.

The default frame_number=0 now resolves to the first frame instead of -1, and oversized frame requests clamp to the final valid frame instead of seeking past the end. Empty or invalid videos now return None safely after releasing the capture.

Affected files: capturer.py

Signed-off-by: Nguyen Van Nam <nam.nv205106@gmail.com>
2026-07-23 22:16:38 +08:00
DopanandGitHub ab64c186ec Merge pull request #1879 from dunegym/fix/openvino-dll-loading
fix: resolve OpenVINO DLL loading on Windows for OpenVINOExecutionProvider
2026-07-19 15:12:49 +08:00
Makaru b8e781e539 chore: remove trailing whitespace 2026-07-19 12:20:54 +08:00
KRSHHandGitHub ff7ee0d219 Revise Quickstart section in README 2026-07-19 00:25:10 +05:30
Nguyen Van NamandGitHub 8d727eba3e fix: bound face-cluster count by available embeddings (#1793)
`find_cluster_centroids()` iterates `k` from 1..`max_k` unconditionally. If `len(embeddings) < max_k`, `KMeans(n_clusters=k)` will raise `ValueError` when `k` exceeds the number of samples. This is an unhandled crash path on small datasets.


Affected files: cluster_analysis.py

Signed-off-by: Nguyen Van Nam <nam.nv205106@gmail.com>
2026-07-14 23:55:23 +08:00
Cocoon-BreakandGitHub eba2a958d3 fix: skip empty face clusters in default_target_face (#1757)
Skip face clusters when no best face was detected, preventing a NoneType error while preserving normal face-detection behavior.

Closes #1755
2026-07-14 23:51:43 +08:00
dunegym 14ba4f9c0b fix: centralize OPENVINO_PROVIDER_CONFIG and log SystemExit
Address Sourcery review feedback on PR #1879:

- Move OPENVINO_PROVIDER_CONFIG from _onnx_enhancer.py to
  platform_info.py (a leaf module with no modules.* imports), so
  the enhancer and face_swapper no longer import each other just to
  share a constant. _onnx_enhancer re-exports it; face_swapper now
  imports it at module top level instead of inside get_face_swapper().
- Narrow run.py's SystemExit handling: catch SystemExit separately
  and print a [startup] message so the failure is visible instead
  of being swallowed alongside ImportError/FileNotFoundError.
2026-07-12 15:16:18 +08:00
dunegym 7d2d7fb1f3 fix: address PR review feedback — SystemExit, AUTO device, thread timing
- Catch SystemExit from add_openvino_libs_to_path() so a missing
  OpenVINO installation never causes a hard exit on Windows
- Replace hard-coded GPU+FP16 with AUTO:GPU,NPU,CPU device priority,
  letting OpenVINO pick the best available accelerator
- Extract shared OPENVINO_PROVIDER_CONFIG constant to avoid
  duplication between _onnx_enhancer and face_swapper
- Defer thread-suggestion evaluation until after execution_providers
  is assigned, fixing a latent timing bug that affected OpenVINO,
  CUDA, and DML thread hints
2026-07-11 12:45:00 +08:00
noahximusandGitHub 57c4c32377 Merge pull request #1876 from ElKhalil19/main 2026-07-07 04:55:43 +08:00
El Khalil d00b09f5d8 docs: update manual installation to use shallow clone (#1866) 2026-07-03 19:54:39 +01:00
dunegym 897dc21da4 fix: resolve OpenVINO DLL loading on Windows for OpenVINOExecutionProvider
- Add add_openvino_libs_to_path() call in run.py before any ONNX
  InferenceSession creation to register openvino.dll directory
- Detect and advertise OpenVINOExecutionProvider in platform_info
  banner and accelerator label
- Prioritize openvino over dml in suggest_default_execution_provider
- Configure OpenVINO EP with GPU + FP16 device options for optimal
  performance (~13 FPS on Intel GPU vs ~1 FPS CPU fallback)
- Set thread hint to 1 when OpenVINO EP is active
2026-06-28 21:46:55 +08:00
Kenneth EstanislaoandGitHub 834092c891 Update Quick Start section to v2.7 RC6 2026-06-24 18:15:40 +08:00
Kenneth EstanislaoandGitHub da0672ad6b Enhance README with details on pre-built versions
Updated the README to clarify the benefits of pre-built versions and optimizations for hardware.
2026-06-24 18:14:59 +08:00
Kenneth Estanislao 834bc43768 Support non-ascii characters 2026-06-14 20:18:56 +08:00
DopanandGitHub 3b69413d61 Merge pull request #1845 from maxwbuckley/ruff-code-health
Add ruff CI gate and fix deterministic lint issues
2026-06-01 00:50:59 +08:00
Kenneth EstanislaoandGitHub 07e2e960c8 Update Quick Start version from v2.7 RC1 to v2.7 RC2 2026-05-24 18:55:35 +08:00
Max BuckleyandClaude Opus 4.7 ba27b75265 Use astral-sh/ruff-action for inline PR annotations
Swap the manual pip install + ruff check steps for astral-sh/ruff-action@v4.0.0.
Same pinned ruff 0.15.7, but with --output-format=github so violations appear
as inline annotations on the PR diff instead of a flat log.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 15:50:44 +02:00
Max BuckleyandClaude Opus 4.7 cfa8123b67 Add ruff CI gate and fix deterministic lint issues
Introduces pyproject.toml + .github/workflows/ruff.yml that gate
E701, E711, E712, F401, F541 on every PR and push to main.

Fixes the existing findings for those rules:
- Remove unused imports (sklearn.silhouette_score, numpy in several
  files, typing.Optional, get_one_face, gpu_cvt_color, sys,
  insightface.face_align)
- Annotate the intentional tkinter_fix side-effect import with
  `# noqa: F401`
- Split multi-statement `if x: y` one-liners onto separate lines
- Replace `state == True` / `state == False` with truthiness checks
- Drop `f` prefix from f-strings with no placeholders

F841 (unused-variable), E402 (module-level-import-not-at-top), and
F821 (undefined-name) are left out of the gate for now — they surface
real findings (including a latent NameError in face_swapper.py) that
require human review to fix safely.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 15:44:31 +02:00
DopanandGitHub 08b2dd2526 Merge pull request #1844 from hklcf/fix/bugfix-batch
lgtm
2026-05-23 16:54:41 +08:00
hklcf 886e64b320 Fix: resolve 5 confirmed bugs (imwrite_unicode, macOS memory, face_analyser None crash, silent sys.exit, core memory calc) 2026-05-23 10:37:20 +08:00
Kenneth EstanislaoandGitHub aa6f2cbade Update version from v2.7 beta to v2.7 RC1 in README 2026-05-21 05:11:41 +08:00
Kenneth EstanislaoandGitHub a21ccf488c Update version number in README.md to 2.1.6 2.7-RC1 2026-05-18 04:15:01 +08:00
Kenneth Estanislao ca8e39e3bb Fix mouth mask 2026-05-18 02:11:04 +08:00
Kenneth Estanislao 0e97e474e4 better swapping 2026-05-18 01:40:01 +08:00
Kenneth Estanislao 9c67a7aacc fixed poisson blend 2026-05-18 01:36:24 +08:00
DopanandGitHub 4a674d33ef Merge pull request #1826 from obook/pr/preload-nvidia-libs-linux
Pre-load NVIDIA shared libraries on Linux
2026-05-17 00:04:06 +08:00
Olivier Booklage 682450755f Avoid duplicating LD_LIBRARY_PATH entries
Skip prepending a directory that is already on LD_LIBRARY_PATH, so a
repeated import of run.py does not bloat the variable.

Addresses review feedback on #1826.
2026-05-16 14:57:02 +02:00
Olivier Booklage 12a3f6a007 Pre-load NVIDIA shared libraries on Linux
Mirrors the Windows preload block from #1775. When onnxruntime-gpu is
installed via pip with nvidia-cudnn-cu12, the .so files sit under
venv/lib/pythonX.Y/site-packages/nvidia/<pkg>/lib/ and the dynamic
linker never sees them. LD_LIBRARY_PATH cannot be set after Python
starts.

Pre-loads every lib*.so* via ctypes.CDLL with RTLD_GLOBAL before
onnxruntime opens its CUDA provider. Also extends LD_LIBRARY_PATH so
child processes (ffmpeg) inherit the path.

Fixes "libcudnn.so.9: cannot open shared object file" on pip-only
Linux installs.
2026-05-16 14:45:54 +02:00
Kenneth EstanislaoandGitHub cede099ccb Update version number in README.md to 2.1.5 2026-05-15 16:33:57 +08:00
Kenneth Estanislao 81a1986ef8 Changed to pyqtUI
Standardizing the UI from quickstart to github version
2026-05-15 16:33:27 +08:00
Kenneth Estanislao ed758eb693 Speed optimization 2026-05-15 15:53:55 +08:00
Kenneth Estanislao 9c5f01c7f1 some fix for face enhancers 2026-05-15 15:13:57 +08:00
Kenneth Estanislao 8bdc348779 Update .gitignore 2026-05-15 14:52:56 +08:00
MakaruandGitHub e34d204c2e Merge pull request #1803 from zuyua9/fix/get-one-face-detected-faces-zuyua9
fix(face): reuse pre-detected face list

comment: tested, all good
2026-05-08 10:20:56 +08:00
zuyua9 d1376b07d1 fix(face): avoid hiding invalid face inputs 2026-05-08 01:50:25 +08:00
zuyua9 5deadaf428 fix(face): reuse pre-detected face list 2026-05-08 01:35:55 +08:00
Kenneth EstanislaoandGitHub 2fba52e11b Merge pull request #1782 from iikuzmychov/fix/black-border-paste-back 2026-04-29 22:31:09 +08:00
Ihor KuzmychovandGitHub 0926b65aaf Merge branch 'hacksider:main' into fix/black-border-paste-back 2026-04-23 19:58:12 +02:00
Ihor Kuzmychov 297acded3b fix: use BORDER_REPLICATE for face warp to eliminate black border 2026-04-23 19:42:32 +02:00
KRSHHandGitHub 014bce0704 Delete PERFORMANCE.md
Removing Claude session summary
2026-04-23 22:12:55 +05:30
KRSHHandGitHub c962399669 Delete REVIEW_TODOS.md 2026-04-23 22:11:53 +05:30
Kenneth EstanislaoandGitHub 2dd42dfc75 Merge pull request #1777 from maxwbuckley/coreml-scalar-gather-fix
Keep GFPGAN on ANE: widen scalar Gather indices for CoreML EP
2026-04-22 22:17:34 +08:00
Kenneth EstanislaoandGitHub c38d669f7c Merge pull request #1776 from maxwbuckley/paste-back-optimization
Paste-back: O(crop_area) compositing + uint8 cv2 SIMD blend
2026-04-22 22:14:45 +08:00
Max Buckley 890a6d41b6 onnx_optimize: widen scalar Gather indices for CoreML EP
ORT's CoreML EP GatherOpBuilder::IsOpSupportedImpl explicitly rejects
rank-0 (scalar) index tensors. StyleGAN-derived models (GFPGAN's 1024
variant has 16 of them, one per style-code slice) hit this in the
generator, and the resulting CPU fallbacks split the CoreML subgraph
into multiple partitions with boundary crossings on every inference.

Add a load-time ONNX rewrite that promotes each scalar index to [1] and
squeezes the added axis on the Gather output — semantically identical
but CoreML-compatible. GFPGAN now runs as a single CoreML partition with
zero CPU-fallback nodes; inference drops from ~87 ms to ~81 ms on an
M-series Mac.

The fix has been filed upstream as microsoft/onnxruntime#28180 — the
existing code comment in gather_op_builder.cc already describes this
exact workaround, it just isn't applied. Once the upstream fix ships
and the ORT floor is raised, this pass can be deleted.
2026-04-22 14:08:18 +02:00
Max Buckley f95a0bb7fb Make square aligned-face assumption explicit in _fast_paste_back
Addresses Sourcery feedback on PR #1776: _get_soft_alpha caches a single
NxN template keyed by N, which is correct for the inswapper model
(128x128 aligned-face space) but would silently mis-warp if a caller
ever passed a non-square aligned face. Assert the shape instead of
silently assuming it.
2026-04-22 13:40:18 +02:00
Max Buckley e957a7f4dd Move BGR→RGB after resize in preview display path
The processing thread was running cvtColor on the full-resolution 1920×1080
frame before queueing it for display. Since the display thread immediately
resizes the frame to the preview window (~5× smaller pixel count), doing
the colour conversion on the resized buffer is cheaper overall.

Processing thread now queues BGR; display thread resizes then cvtColor.
2026-04-22 13:31:11 +02:00
Kenneth EstanislaoandGitHub 19416cb3cb Merge pull request #1775 from maxwbuckley/unify-mac-windows
Apple Silicon + Windows CUDA perf: 4-5x FPS, wider capture, platform routing
2026-04-22 18:38:32 +08:00
Max Buckley cbf0859347 Paste-back blend: uint8 cv2 SIMD, no float32 round-trip
Both face_swapper._fast_paste_back and face_enhancer._paste_back were
doing a numpy float32 round-trip per frame: convert the target crop and
the warped face to float32, blend, clip, cast back to uint8. That's four
crop-sized allocations plus unvectorized elementwise math.

Replace with a fused uint8 blend using cv2.merge + cv2.multiply + cv2.add,
which cv2 dispatches to SIMD (NEON on Apple Silicon / AVX on x86). Stored
alpha templates switched from float32 [0, 1] to uint8 [0, 255] so no
conversion is needed per frame. CUDA paths also simplified — upload uint8
alpha (less bandwidth) and scale on device.

Micro-bench on 1000x1000 RGB crop:
  current (float32 numpy): 9.43 ms
  cv2 uint8 fused:         1.16 ms  (8.1× faster, max diff 2/255)

Visual diff is imperceptible (quantization noise in the last step).
2026-04-22 12:05:39 +02:00
Max Buckley a6c99607fc Cut paste-back from quartic to linear in face size
_fast_paste_back used to erode and Gaussian-blur the warped alpha mask in
output coordinates with kernel sizes proportional to the on-screen face
bbox. That made the per-frame cost ~O(area * k^2) — a face filling half
the frame took ~8x the compositing work of one filling a quarter, which
is why FPS fell off when leaning into the camera.

Instead, build a feathered alpha template once at aligned-face resolution
(128x128 for inswapper) and warp the soft mask per-frame. The affine
transform preserves the relative feather width, so the visual output is
equivalent; the per-frame cost is now O(crop_area) with no size-scaled
erode/blur and no size-scaled padding.

Also collapses the CPU fallback onto the same shape — it previously did
a full-frame warpAffine twice per call, which scaled with the whole
frame instead of the face crop.
2026-04-22 11:58:02 +02:00
Max BuckleyandClaude Opus 4.7 0a87d63560 Address PR #1775 review: pipelined-detection race and CUDA-graph monkey-patch
- core._run_pipe_pipeline: hand the background detector its own copy of
  the frame. The frame processors mutate in place via paste-back, which
  was racing with concurrent face detection on the same buffer.
- face_swapper._init_cuda_graph_session: replace the
  `swapper.session.run` monkey-patch with a `_CudaGraphSessionAdapter`
  that proxies every attribute to the underlying session and only
  overrides `.run()`. Guarded so repeat init does not double-wrap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:45:59 +02:00