Merge branch 'main' into new_feature
						commit
						b31a3dc2bd
					
				
								
									
									
										
											23
										
									
									README.md
									
									
									
									
								
								
							
							
										
											23
										
									
									README.md
									
									
									
									
								|  | @ -30,6 +30,13 @@ By using this software, you agree to these terms and commit to using it in a man | |||
| 
 | ||||
| Users are expected to use this software responsibly and legally. If using a real person's face, obtain their consent and clearly label any output as a deepfake when sharing online. We are not responsible for end-user actions. | ||||
| 
 | ||||
| ## Exclusive v2.0 Quick Start - Pre-built (Windows) | ||||
| 
 | ||||
|   <a href="https://deeplivecam.net/index.php/quickstart"> <img src="media/Download.png" width="285" height="77" /> | ||||
| 
 | ||||
| ##### This is the fastest build you can get if you have a discrete NVIDIA or AMD GPU. | ||||
|   | ||||
| ###### These Pre-builts are perfect for non-technical users or those who don't have time to, or can't manually install all the requirements. Just a heads-up: this is an open-source project, so you can also install it manually. This will be 60 days ahead on the open source version. | ||||
| 
 | ||||
| ## TLDR; Live Deepfake in just 3 Clicks | ||||
|  | ||||
|  | @ -126,12 +133,20 @@ Place these files in the "**models**" folder. | |||
| 
 | ||||
| We highly recommend using a `venv` to avoid issues. | ||||
| 
 | ||||
| 
 | ||||
| For Windows: | ||||
| ```bash | ||||
| python -m venv venv | ||||
| venv\Scripts\activate | ||||
| pip install -r requirements.txt | ||||
| ``` | ||||
| For Linux: | ||||
| ```bash | ||||
| # Ensure you use the installed Python 3.10 | ||||
| python3 -m venv venv | ||||
| source venv/bin/activate | ||||
| pip install -r requirements.txt | ||||
| ``` | ||||
| 
 | ||||
| **For macOS:** | ||||
| 
 | ||||
|  | @ -172,10 +187,14 @@ pip install -r requirements.txt | |||
| 
 | ||||
| **CUDA Execution Provider (Nvidia)** | ||||
| 
 | ||||
| 1. Install [CUDA Toolkit 11.8.0](https://developer.nvidia.com/cuda-11-8-0-download-archive) | ||||
| 2. Install dependencies: | ||||
| 1. Install [CUDA Toolkit 12.8.0](https://developer.nvidia.com/cuda-12-8-0-download-archive) | ||||
| 2. Install [cuDNN v8.9.7 for CUDA 12.x](https://developer.nvidia.com/rdp/cudnn-archive) (required for onnxruntime-gpu): | ||||
|    - Download cuDNN v8.9.7 for CUDA 12.x | ||||
|    - Make sure the cuDNN bin directory is in your system PATH | ||||
| 3. Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| pip install -U torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128 | ||||
| pip uninstall onnxruntime onnxruntime-gpu | ||||
| pip install onnxruntime-gpu==1.16.3 | ||||
| ``` | ||||
|  |  | |||
|  | @ -0,0 +1,46 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Quelle x Ziel Zuordnung", | ||||
|     "select a source image": "Wähle ein Quellbild", | ||||
|     "Preview": "Vorschau", | ||||
|     "select a target image or video": "Wähle ein Zielbild oder Video", | ||||
|     "save image output file": "Bildausgabedatei speichern", | ||||
|     "save video output file": "Videoausgabedatei speichern", | ||||
|     "select a target image": "Wähle ein Zielbild", | ||||
|     "source": "Quelle", | ||||
|     "Select a target": "Wähle ein Ziel", | ||||
|     "Select a face": "Wähle ein Gesicht", | ||||
|     "Keep audio": "Audio beibehalten", | ||||
|     "Face Enhancer": "Gesichtsverbesserung", | ||||
|     "Many faces": "Mehrere Gesichter", | ||||
|     "Show FPS": "FPS anzeigen", | ||||
|     "Keep fps": "FPS beibehalten", | ||||
|     "Keep frames": "Frames beibehalten", | ||||
|     "Fix Blueish Cam": "Bläuliche Kamera korrigieren", | ||||
|     "Mouth Mask": "Mundmaske", | ||||
|     "Show Mouth Mask Box": "Mundmaskenrahmen anzeigen", | ||||
|     "Start": "Starten", | ||||
|     "Live": "Live", | ||||
|     "Destroy": "Beenden", | ||||
|     "Map faces": "Gesichter zuordnen", | ||||
|     "Processing...": "Verarbeitung läuft...", | ||||
|     "Processing succeed!": "Verarbeitung erfolgreich!", | ||||
|     "Processing ignored!": "Verarbeitung ignoriert!", | ||||
|     "Failed to start camera": "Kamera konnte nicht gestartet werden", | ||||
|     "Please complete pop-up or close it.": "Bitte das Pop-up komplettieren oder schließen.", | ||||
|     "Getting unique faces": "Einzigartige Gesichter erfassen", | ||||
|     "Please select a source image first": "Bitte zuerst ein Quellbild auswählen", | ||||
|     "No faces found in target": "Keine Gesichter im Zielbild gefunden", | ||||
|     "Add": "Hinzufügen", | ||||
|     "Clear": "Löschen", | ||||
|     "Submit": "Absenden", | ||||
|     "Select source image": "Quellbild auswählen", | ||||
|     "Select target image": "Zielbild auswählen", | ||||
|     "Please provide mapping!": "Bitte eine Zuordnung angeben!", | ||||
|     "At least 1 source with target is required!": "Mindestens eine Quelle mit einem Ziel ist erforderlich!", | ||||
|     "At least 1 source with target is required!": "Mindestens eine Quelle mit einem Ziel ist erforderlich!", | ||||
|     "Face could not be detected in last upload!": "Im letzten Upload konnte kein Gesicht erkannt werden!", | ||||
|     "Select Camera:": "Kamera auswählen:", | ||||
|     "All mappings cleared!": "Alle Zuordnungen gelöscht!", | ||||
|     "Mappings successfully submitted!": "Zuordnungen erfolgreich übermittelt!", | ||||
|     "Source x Target Mapper is already open.": "Quell-zu-Ziel-Zuordnung ist bereits geöffnet." | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Mapeador de fuente x destino", | ||||
|     "select a source image": "Seleccionar imagen fuente", | ||||
|     "Preview": "Vista previa", | ||||
|     "select a target image or video": "elegir un video o una imagen fuente", | ||||
|     "save image output file": "guardar imagen final", | ||||
|     "save video output file": "guardar video final", | ||||
|     "select a target image": "elegir una imagen objetiva", | ||||
|     "source": "fuente", | ||||
|     "Select a target": "Elegir un destino", | ||||
|     "Select a face": "Elegir una cara", | ||||
|     "Keep audio": "Mantener audio original", | ||||
|     "Face Enhancer": "Potenciador de caras", | ||||
|     "Many faces": "Varias caras", | ||||
|     "Show FPS": "Mostrar fps", | ||||
|     "Keep fps": "Mantener fps", | ||||
|     "Keep frames": "Mantener frames", | ||||
|     "Fix Blueish Cam": "Corregir tono azul de video", | ||||
|     "Mouth Mask": "Máscara de boca", | ||||
|     "Show Mouth Mask Box": "Mostrar área de la máscara de boca", | ||||
|     "Start": "Iniciar", | ||||
|     "Live": "En vivo", | ||||
|     "Destroy": "Borrar", | ||||
|     "Map faces": "Mapear caras", | ||||
|     "Processing...": "Procesando...", | ||||
|     "Processing succeed!": "¡Proceso terminado con éxito!", | ||||
|     "Processing ignored!": "¡Procesamiento omitido!", | ||||
|     "Failed to start camera": "No se pudo iniciar la cámara", | ||||
|     "Please complete pop-up or close it.": "Complete o cierre el pop-up", | ||||
|     "Getting unique faces": "Buscando caras únicas", | ||||
|     "Please select a source image first": "Primero, seleccione una imagen fuente", | ||||
|     "No faces found in target": "No se encontró una cara en el destino", | ||||
|     "Add": "Agregar", | ||||
|     "Clear": "Limpiar", | ||||
|     "Submit": "Enviar", | ||||
|     "Select source image": "Seleccionar imagen fuente", | ||||
|     "Select target image": "Seleccionar imagen destino", | ||||
|     "Please provide mapping!": "Por favor, proporcione un mapeo", | ||||
|     "At least 1 source with target is required!": "Se requiere al menos una fuente con un destino.", | ||||
|     "At least 1 source with target is required!": "Se requiere al menos una fuente con un destino.", | ||||
|     "Face could not be detected in last upload!": "¡No se pudo encontrar una cara en el último video o imagen!", | ||||
|     "Select Camera:": "Elegir cámara:", | ||||
|     "All mappings cleared!": "¡Todos los mapeos fueron borrados!", | ||||
|     "Mappings successfully submitted!": "Mapeos enviados con éxito!", | ||||
|     "Source x Target Mapper is already open.": "El mapeador de fuente x destino ya está abierto." | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Source x Target Kartoitin", | ||||
|     "select an source image": "Valitse lähde kuva", | ||||
|     "Preview": "Esikatsele", | ||||
|     "select an target image or video": "Valitse kohde kuva tai video", | ||||
|     "save image output file": "tallenna kuva", | ||||
|     "save video output file": "tallenna video", | ||||
|     "select an target image": "Valitse kohde kuva", | ||||
|     "source": "lähde", | ||||
|     "Select a target": "Valitse kohde", | ||||
|     "Select a face": "Valitse kasvot", | ||||
|     "Keep audio": "Säilytä ääni", | ||||
|     "Face Enhancer": "Kasvojen Parantaja", | ||||
|     "Many faces": "Useampia kasvoja", | ||||
|     "Show FPS": "Näytä FPS", | ||||
|     "Keep fps": "Säilytä FPS", | ||||
|     "Keep frames": "Säilytä ruudut", | ||||
|     "Fix Blueish Cam": "Korjaa Sinertävä Kamera", | ||||
|     "Mouth Mask": "Suu Maski", | ||||
|     "Show Mouth Mask Box": "Näytä Suu Maski Laatiko", | ||||
|     "Start": "Aloita", | ||||
|     "Live": "Live", | ||||
|     "Destroy": "Tuhoa", | ||||
|     "Map faces": "Kartoita kasvot", | ||||
|     "Processing...": "Prosessoi...", | ||||
|     "Processing succeed!": "Prosessointi onnistui!", | ||||
|     "Processing ignored!": "Prosessointi lopetettu!", | ||||
|     "Failed to start camera": "Kameran käynnistäminen epäonnistui", | ||||
|     "Please complete pop-up or close it.": "Viimeistele tai sulje ponnahdusikkuna", | ||||
|     "Getting unique faces": "Hankitaan uniikkeja kasvoja", | ||||
|     "Please select a source image first": "Valitse ensin lähde kuva", | ||||
|     "No faces found in target": "Kasvoja ei löydetty kohteessa", | ||||
|     "Add": "Lisää", | ||||
|     "Clear": "Tyhjennä", | ||||
|     "Submit": "Lähetä", | ||||
|     "Select source image": "Valitse lähde kuva", | ||||
|     "Select target image": "Valitse kohde kuva", | ||||
|     "Please provide mapping!": "Tarjoa kartoitus!", | ||||
|     "Atleast 1 source with target is required!": "Vähintään 1 lähde kohteen kanssa on vaadittu!", | ||||
|     "At least 1 source with target is required!": "Vähintään 1 lähde kohteen kanssa on vaadittu!", | ||||
|     "Face could not be detected in last upload!": "Kasvoja ei voitu tunnistaa edellisessä latauksessa!", | ||||
|     "Select Camera:": "Valitse Kamera:", | ||||
|     "All mappings cleared!": "Kaikki kartoitukset tyhjennetty!", | ||||
|     "Mappings successfully submitted!": "Kartoitukset lähetety onnistuneesti!", | ||||
|     "Source x Target Mapper is already open.": "Lähde x Kohde Kartoittaja on jo auki." | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| { | ||||
|     "Source x Target Mapper": "ប្រភប x បន្ថែម Mapper", | ||||
|     "select a source image": "ជ្រើសរើសប្រភពរូបភាព", | ||||
|     "Preview": "បង្ហាញ", | ||||
|     "select a target image or video": "ជ្រើសរើសគោលដៅរូបភាពឬវីដេអូ", | ||||
|     "save image output file": "រក្សាទុកលទ្ធផលឯកសាររូបភាព", | ||||
|     "save video output file": "រក្សាទុកលទ្ធផលឯកសារវីដេអូ", | ||||
|     "select a target image": "ជ្រើសរើសគោលដៅរូបភាព", | ||||
|     "source": "ប្រភព", | ||||
|     "Select a target": "ជ្រើសរើសគោលដៅ", | ||||
|     "Select a face": "ជ្រើសរើសមុខ", | ||||
|     "Keep audio": "រម្លងសម្លេង", | ||||
|     "Face Enhancer": "ឧបករណ៍ពង្រឹងមុខ", | ||||
|     "Many faces": "ទម្រង់មុខច្រើន", | ||||
|     "Show FPS": "បង្ហាញ FPS", | ||||
|     "Keep fps": "រម្លង fps", | ||||
|     "Keep frames": "រម្លងទម្រង់", | ||||
|     "Fix Blueish Cam": "ជួសជុល Cam Blueish", | ||||
|     "Mouth Mask": "របាំងមាត់", | ||||
|     "Show Mouth Mask Box": "បង្ហាញប្រអប់របាំងមាត់", | ||||
|     "Start": "ចាប់ផ្ដើម", | ||||
|     "Live": "ផ្សាយផ្ទាល់", | ||||
|     "Destroy": "លុប", | ||||
|     "Map faces": "ផែនទីមុខ", | ||||
|     "Processing...": "កំពុងដំណើរការ...", | ||||
|     "Processing succeed!": "ការដំណើរការទទួលបានជោគជ័យ!", | ||||
|     "Processing ignored!": "ការដំណើរការមិនទទួលបានជោគជ័យ!", | ||||
|     "Failed to start camera": "បរាជ័យដើម្បីចាប់ផ្ដើមបើកកាមេរ៉ា", | ||||
|     "Please complete pop-up or close it.": "សូមបញ្ចប់ផ្ទាំងផុស ឬបិទវា.", | ||||
|     "Getting unique faces": "ការចាប់ផ្ដើមទម្រង់មុខប្លែក", | ||||
|     "Please select a source image first": "សូមជ្រើសរើសប្រភពរូបភាពដំបូង", | ||||
|     "No faces found in target": "រកអត់ឃើញមុខនៅក្នុងគោលដៅ", | ||||
|     "Add": "បន្ថែម", | ||||
|     "Clear": "សម្អាត", | ||||
|     "Submit": "បញ្ចូន", | ||||
|     "Select source image": "ជ្រើសរើសប្រភពរូបភាព", | ||||
|     "Select target image": "ជ្រើសរើសគោលដៅរូបភាព", | ||||
|     "Please provide mapping!": "សូមផ្ដល់នៅផែនទី", | ||||
|     "At least 1 source with target is required!": "ត្រូវការប្រភពយ៉ាងហោចណាស់ ១ ដែលមានគោលដៅ!", | ||||
|     "Face could not be detected in last upload!": "មុខមិនអាចភ្ជាប់នៅក្នុងការបង្ហេាះចុងក្រោយ!", | ||||
|     "Select Camera:": "ជ្រើសរើសកាមេរ៉ា", | ||||
|     "All mappings cleared!": "ផែនទីទាំងអស់ត្រូវបានសម្អាត!", | ||||
|     "Mappings successfully submitted!": "ផែនទីត្រូវបានបញ្ជូនជោគជ័យ!", | ||||
|     "Source x Target Mapper is already open.": "ប្រភព x Target Mapper បានបើករួចហើយ។" | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| { | ||||
|     "Source x Target Mapper": "소스 x 타겟 매퍼", | ||||
|     "select a source image": "소스 이미지 선택", | ||||
|     "Preview": "미리보기", | ||||
|     "select a target image or video": "타겟 이미지 또는 영상 선택", | ||||
|     "save image output file": "이미지 출력 파일 저장", | ||||
|     "save video output file": "영상 출력 파일 저장", | ||||
|     "select a target image": "타겟 이미지 선택", | ||||
|     "source": "소스", | ||||
|     "Select a target": "타겟 선택", | ||||
|     "Select a face": "얼굴 선택", | ||||
|     "Keep audio": "오디오 유지", | ||||
|     "Face Enhancer": "얼굴 향상", | ||||
|     "Many faces": "여러 얼굴", | ||||
|     "Show FPS": "FPS 표시", | ||||
|     "Keep fps": "FPS 유지", | ||||
|     "Keep frames": "프레임 유지", | ||||
|     "Fix Blueish Cam": "푸른빛 카메라 보정", | ||||
|     "Mouth Mask": "입 마스크", | ||||
|     "Show Mouth Mask Box": "입 마스크 박스 표시", | ||||
|     "Start": "시작", | ||||
|     "Live": "라이브", | ||||
|     "Destroy": "종료", | ||||
|     "Map faces": "얼굴 매핑", | ||||
|     "Processing...": "처리 중...", | ||||
|     "Processing succeed!": "처리 성공!", | ||||
|     "Processing ignored!": "처리 무시됨!", | ||||
|     "Failed to start camera": "카메라 시작 실패", | ||||
|     "Please complete pop-up or close it.": "팝업을 완료하거나 닫아주세요.", | ||||
|     "Getting unique faces": "고유 얼굴 가져오는 중", | ||||
|     "Please select a source image first": "먼저 소스 이미지를 선택해주세요", | ||||
|     "No faces found in target": "타겟에서 얼굴을 찾을 수 없음", | ||||
|     "Add": "추가", | ||||
|     "Clear": "지우기", | ||||
|     "Submit": "제출", | ||||
|     "Select source image": "소스 이미지 선택", | ||||
|     "Select target image": "타겟 이미지 선택", | ||||
|     "Please provide mapping!": "매핑을 입력해주세요!", | ||||
|     "At least 1 source with target is required!": "최소 하나의 소스와 타겟이 필요합니다!", | ||||
|     "Face could not be detected in last upload!": "최근 업로드에서 얼굴을 감지할 수 없습니다!", | ||||
|     "Select Camera:": "카메라 선택:", | ||||
|     "All mappings cleared!": "모든 매핑이 삭제되었습니다!", | ||||
|     "Mappings successfully submitted!": "매핑이 성공적으로 제출되었습니다!", | ||||
|     "Source x Target Mapper is already open.": "소스 x 타겟 매퍼가 이미 열려 있습니다." | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Mapeador de Origem x Destino", | ||||
|     "select an source image": "Escolha uma imagem de origem", | ||||
|     "Preview": "Prévia", | ||||
|     "select an target image or video": "Escolha uma imagem ou vídeo de destino", | ||||
|     "save image output file": "Salvar imagem final", | ||||
|     "save video output file": "Salvar vídeo final", | ||||
|     "select an target image": "Escolha uma imagem de destino", | ||||
|     "source": "Origem", | ||||
|     "Select a target": "Escolha o destino", | ||||
|     "Select a face": "Escolha um rosto", | ||||
|     "Keep audio": "Manter o áudio original", | ||||
|     "Face Enhancer": "Melhorar rosto", | ||||
|     "Many faces": "Vários rostos", | ||||
|     "Show FPS": "Mostrar FPS", | ||||
|     "Keep fps": "Manter FPS", | ||||
|     "Keep frames": "Manter frames", | ||||
|     "Fix Blueish Cam": "Corrigir tom azulado da câmera", | ||||
|     "Mouth Mask": "Máscara da boca", | ||||
|     "Show Mouth Mask Box": "Mostrar área da máscara da boca", | ||||
|     "Start": "Começar", | ||||
|     "Live": "Ao vivo", | ||||
|     "Destroy": "Destruir", | ||||
|     "Map faces": "Mapear rostos", | ||||
|     "Processing...": "Processando...", | ||||
|     "Processing succeed!": "Tudo certo!", | ||||
|     "Processing ignored!": "Processamento ignorado!", | ||||
|     "Failed to start camera": "Não foi possível iniciar a câmera", | ||||
|     "Please complete pop-up or close it.": "Finalize ou feche o pop-up", | ||||
|     "Getting unique faces": "Buscando rostos diferentes", | ||||
|     "Please select a source image first": "Selecione primeiro uma imagem de origem", | ||||
|     "No faces found in target": "Nenhum rosto encontrado na imagem de destino", | ||||
|     "Add": "Adicionar", | ||||
|     "Clear": "Limpar", | ||||
|     "Submit": "Enviar", | ||||
|     "Select source image": "Escolha a imagem de origem", | ||||
|     "Select target image": "Escolha a imagem de destino", | ||||
|     "Please provide mapping!": "Você precisa realizar o mapeamento!", | ||||
|     "Atleast 1 source with target is required!": "É necessária pelo menos uma origem com um destino!", | ||||
|     "At least 1 source with target is required!": "É necessária pelo menos uma origem com um destino!", | ||||
|     "Face could not be detected in last upload!": "Não conseguimos detectar o rosto na última imagem!", | ||||
|     "Select Camera:": "Escolher câmera:", | ||||
|     "All mappings cleared!": "Todos os mapeamentos foram removidos!", | ||||
|     "Mappings successfully submitted!": "Mapeamentos enviados com sucesso!", | ||||
|     "Source x Target Mapper is already open.": "O Mapeador de Origem x Destino já está aberto." | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Сопоставитель Источник x Цель", | ||||
|     "select a source image": "выберите исходное изображение", | ||||
|     "Preview": "Предпросмотр", | ||||
|     "select a target image or video": "выберите целевое изображение или видео", | ||||
|     "save image output file": "сохранить выходной файл изображения", | ||||
|     "save video output file": "сохранить выходной файл видео", | ||||
|     "select a target image": "выберите целевое изображение", | ||||
|     "source": "источник", | ||||
|     "Select a target": "Выберите целевое изображение", | ||||
|     "Select a face": "Выберите лицо", | ||||
|     "Keep audio": "Сохранить аудио", | ||||
|     "Face Enhancer": "Улучшение лица", | ||||
|     "Many faces": "Несколько лиц", | ||||
|     "Show FPS": "Показать FPS", | ||||
|     "Keep fps": "Сохранить FPS", | ||||
|     "Keep frames": "Сохранить кадры", | ||||
|     "Fix Blueish Cam": "Исправить синеву камеры", | ||||
|     "Mouth Mask": "Маска рта", | ||||
|     "Show Mouth Mask Box": "Показать рамку маски рта", | ||||
|     "Start": "Старт", | ||||
|     "Live": "В реальном времени", | ||||
|     "Destroy": "Остановить", | ||||
|     "Map faces": "Сопоставить лица", | ||||
|     "Processing...": "Обработка...", | ||||
|     "Processing succeed!": "Обработка успешна!", | ||||
|     "Processing ignored!": "Обработка проигнорирована!", | ||||
|     "Failed to start camera": "Не удалось запустить камеру", | ||||
|     "Please complete pop-up or close it.": "Пожалуйста, заполните всплывающее окно или закройте его.", | ||||
|     "Getting unique faces": "Получение уникальных лиц", | ||||
|     "Please select a source image first": "Сначала выберите исходное изображение, пожалуйста", | ||||
|     "No faces found in target": "В целевом изображении не найдено лиц", | ||||
|     "Add": "Добавить", | ||||
|     "Clear": "Очистить", | ||||
|     "Submit": "Отправить", | ||||
|     "Select source image": "Выбрать исходное изображение", | ||||
|     "Select target image": "Выбрать целевое изображение", | ||||
|     "Please provide mapping!": "Пожалуйста, укажите сопоставление!", | ||||
|     "At least 1 source with target is required!": "Требуется хотя бы 1 источник с целью!", | ||||
|     "Face could not be detected in last upload!": "Лицо не обнаружено в последнем загруженном изображении!", | ||||
|     "Select Camera:": "Выберите камеру:", | ||||
|     "All mappings cleared!": "Все сопоставления очищены!", | ||||
|     "Mappings successfully submitted!": "Сопоставления успешно отправлены!", | ||||
|     "Source x Target Mapper is already open.": "Сопоставитель Источник-Цель уже открыт." | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| { | ||||
|     "Source x Target Mapper": "ตัวจับคู่ต้นทาง x ปลายทาง", | ||||
|     "select a source image": "เลือกรูปภาพต้นฉบับ", | ||||
|     "Preview": "ตัวอย่าง", | ||||
|     "select a target image or video": "เลือกรูปภาพหรือวิดีโอเป้าหมาย", | ||||
|     "save image output file": "บันทึกไฟล์รูปภาพ", | ||||
|     "save video output file": "บันทึกไฟล์วิดีโอ", | ||||
|     "select a target image": "เลือกรูปภาพเป้าหมาย", | ||||
|     "source": "ต้นฉบับ", | ||||
|     "Select a target": "เลือกเป้าหมาย", | ||||
|     "Select a face": "เลือกใบหน้า", | ||||
|     "Keep audio": "เก็บเสียง", | ||||
|     "Face Enhancer": "ปรับปรุงใบหน้า", | ||||
|     "Many faces": "หลายใบหน้า", | ||||
|     "Show FPS": "แสดง FPS", | ||||
|     "Keep fps": "คงค่า FPS", | ||||
|     "Keep frames": "คงค่าเฟรม", | ||||
|     "Fix Blueish Cam": "แก้ไขภาพอมฟ้าจากกล้อง", | ||||
|     "Mouth Mask": "มาสก์ปาก", | ||||
|     "Show Mouth Mask Box": "แสดงกรอบมาสก์ปาก", | ||||
|     "Start": "เริ่ม", | ||||
|     "Live": "สด", | ||||
|     "Destroy": "หยุด", | ||||
|     "Map faces": "จับคู่ใบหน้า", | ||||
|     "Processing...": "กำลังประมวลผล...", | ||||
|     "Processing succeed!": "ประมวลผลสำเร็จแล้ว!", | ||||
|     "Processing ignored!": "การประมวลผลถูกละเว้น", | ||||
|     "Failed to start camera": "ไม่สามารถเริ่มกล้องได้", | ||||
|     "Please complete pop-up or close it.": "โปรดดำเนินการในป๊อปอัปให้เสร็จสิ้น หรือปิด", | ||||
|     "Getting unique faces": "กำลังค้นหาใบหน้าที่ไม่ซ้ำกัน", | ||||
|     "Please select a source image first": "โปรดเลือกภาพต้นฉบับก่อน", | ||||
|     "No faces found in target": "ไม่พบใบหน้าในภาพเป้าหมาย", | ||||
|     "Add": "เพิ่ม", | ||||
|     "Clear": "ล้าง", | ||||
|     "Submit": "ส่ง", | ||||
|     "Select source image": "เลือกภาพต้นฉบับ", | ||||
|     "Select target image": "เลือกภาพเป้าหมาย", | ||||
|     "Please provide mapping!": "โปรดระบุการจับคู่!", | ||||
|     "At least 1 source with target is required!": "ต้องมีการจับคู่ต้นฉบับกับเป้าหมายอย่างน้อย 1 คู่!", | ||||
|     "Face could not be detected in last upload!": "ไม่สามารถตรวจพบใบหน้าในไฟล์อัปโหลดล่าสุด!", | ||||
|     "Select Camera:": "เลือกกล้อง:", | ||||
|     "All mappings cleared!": "ล้างการจับคู่ทั้งหมดแล้ว!", | ||||
|     "Mappings successfully submitted!": "ส่งการจับคู่สำเร็จแล้ว!", | ||||
|     "Source x Target Mapper is already open.": "ตัวจับคู่ต้นทาง x ปลายทาง เปิดอยู่แล้ว" | ||||
| } | ||||
|  | @ -1,11 +1,11 @@ | |||
| { | ||||
|     "Source x Target Mapper": "Source x Target Mapper", | ||||
|     "select an source image": "选择一个源图像", | ||||
|     "select a source image": "选择一个源图像", | ||||
|     "Preview": "预览", | ||||
|     "select an target image or video": "选择一个目标图像或视频", | ||||
|     "select a target image or video": "选择一个目标图像或视频", | ||||
|     "save image output file": "保存图像输出文件", | ||||
|     "save video output file": "保存视频输出文件", | ||||
|     "select an target image": "选择一个目标图像", | ||||
|     "select a target image": "选择一个目标图像", | ||||
|     "source": "源", | ||||
|     "Select a target": "选择一个目标", | ||||
|     "Select a face": "选择一张脸", | ||||
|  | @ -36,11 +36,11 @@ | |||
|     "Select source image": "请选取源图像", | ||||
|     "Select target image": "请选取目标图像", | ||||
|     "Please provide mapping!": "请提供映射", | ||||
|     "Atleast 1 source with target is required!": "至少需要一个来源图像与目标图像相关!", | ||||
|     "At least 1 source with target is required!": "至少需要一个来源图像与目标图像相关!", | ||||
|     "At least 1 source with target is required!": "至少需要一个来源图像与目标图像相关!", | ||||
|     "Face could not be detected in last upload!": "最近上传的图像中没有检测到人脸!", | ||||
|     "Select Camera:": "选择摄像头", | ||||
|     "All mappings cleared!": "所有映射均已清除!", | ||||
|     "Mappings successfully submitted!": "成功提交映射!", | ||||
|     "Source x Target Mapper is already open.": "源 x 目标映射器已打开。" | ||||
| } | ||||
| } | ||||
|  |  | |||
											
												Binary file not shown.
											
										
									
								| After Width: | Height: | Size: 8.7 KiB | 
											
												Binary file not shown.
											
										
									
								| Before Width: | Height: | Size: 9.0 KiB | 
|  | @ -0,0 +1,18 @@ | |||
| import os  | ||||
| import cv2 | ||||
| import numpy as np | ||||
| 
 | ||||
| # Utility function to support unicode characters in file paths for reading | ||||
| def imread_unicode(path, flags=cv2.IMREAD_COLOR): | ||||
|     return cv2.imdecode(np.fromfile(path, dtype=np.uint8), flags) | ||||
| 
 | ||||
| # Utility function to support unicode characters in file paths for writing | ||||
| def imwrite_unicode(path, img, params=None): | ||||
|     root, ext = os.path.splitext(path) | ||||
|     if not ext: | ||||
|         ext = ".png" | ||||
|         result, encoded_img = cv2.imencode(ext, img, params if params else []) | ||||
|         result, encoded_img = cv2.imencode(f".{ext}", img, params if params is not None else []) | ||||
|         encoded_img.tofile(path) | ||||
|         return True | ||||
|     return False | ||||
|  | @ -1,3 +1,3 @@ | |||
| name = 'Deep-Live-Cam' | ||||
| version = '1.9' | ||||
| version = '1.8' | ||||
| edition = 'GitHub Edition' | ||||
|  |  | |||
|  | @ -43,18 +43,29 @@ def get_frame_processors_modules(frame_processors: List[str]) -> List[ModuleType | |||
| 
 | ||||
| def set_frame_processors_modules_from_ui(frame_processors: List[str]) -> None: | ||||
|     global FRAME_PROCESSORS_MODULES | ||||
|     current_processor_names = [proc.__name__.split('.')[-1] for proc in FRAME_PROCESSORS_MODULES] | ||||
| 
 | ||||
|     for frame_processor, state in modules.globals.fp_ui.items(): | ||||
|         if state == True and frame_processor not in frame_processors: | ||||
|             frame_processor_module = load_frame_processor_module(frame_processor) | ||||
|             FRAME_PROCESSORS_MODULES.append(frame_processor_module) | ||||
|             modules.globals.frame_processors.append(frame_processor) | ||||
|         if state == False: | ||||
|         if state == True and frame_processor not in current_processor_names: | ||||
|             try: | ||||
|                 frame_processor_module = load_frame_processor_module(frame_processor) | ||||
|                 FRAME_PROCESSORS_MODULES.remove(frame_processor_module) | ||||
|                 modules.globals.frame_processors.remove(frame_processor) | ||||
|             except: | ||||
|                 pass | ||||
|                 FRAME_PROCESSORS_MODULES.append(frame_processor_module) | ||||
|                 if frame_processor not in modules.globals.frame_processors: | ||||
|                      modules.globals.frame_processors.append(frame_processor) | ||||
|             except SystemExit: | ||||
|                  print(f"Warning: Failed to load frame processor {frame_processor} requested by UI state.") | ||||
|             except Exception as e: | ||||
|                  print(f"Warning: Error loading frame processor {frame_processor} requested by UI state: {e}") | ||||
| 
 | ||||
|         elif state == False and frame_processor in current_processor_names: | ||||
|             try: | ||||
|                 module_to_remove = next((mod for mod in FRAME_PROCESSORS_MODULES if mod.__name__.endswith(f'.{frame_processor}')), None) | ||||
|                 if module_to_remove: | ||||
|                     FRAME_PROCESSORS_MODULES.remove(module_to_remove) | ||||
|                 if frame_processor in modules.globals.frame_processors: | ||||
|                     modules.globals.frame_processors.remove(frame_processor) | ||||
|             except Exception as e: | ||||
|                  print(f"Warning: Error removing frame processor {frame_processor}: {e}") | ||||
| 
 | ||||
| def multi_process_frame(source_path: str, temp_frame_paths: List[str], process_frames: Callable[[str, List[str], Any], None], progress: Any = None) -> None: | ||||
|     with ThreadPoolExecutor(max_workers=modules.globals.execution_threads) as executor: | ||||
|  |  | |||
|  | @ -48,6 +48,17 @@ def pre_start() -> bool: | |||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| TENSORRT_AVAILABLE = False | ||||
| try: | ||||
|     import torch_tensorrt | ||||
|     TENSORRT_AVAILABLE = True | ||||
| except ImportError as im: | ||||
|     print(f"TensorRT is not available: {im}") | ||||
|     pass | ||||
| except Exception as e: | ||||
|     print(f"TensorRT is not available: {e}") | ||||
|     pass | ||||
| 
 | ||||
| def get_face_enhancer() -> Any: | ||||
|     global FACE_ENHANCER | ||||
| 
 | ||||
|  | @ -55,16 +66,26 @@ def get_face_enhancer() -> Any: | |||
|         if FACE_ENHANCER is None: | ||||
|             model_path = os.path.join(models_dir, "GFPGANv1.4.pth") | ||||
|              | ||||
|             match platform.system(): | ||||
|                 case "Darwin":  # Mac OS | ||||
|                     if torch.backends.mps.is_available(): | ||||
|                         mps_device = torch.device("mps") | ||||
|                         FACE_ENHANCER = gfpgan.GFPGANer(model_path=model_path, upscale=1, device=mps_device)  # type: ignore[attr-defined] | ||||
|                     else: | ||||
|                         FACE_ENHANCER = gfpgan.GFPGANer(model_path=model_path, upscale=1)  # type: ignore[attr-defined] | ||||
|                 case _:  # Other OS | ||||
|                     FACE_ENHANCER = gfpgan.GFPGANer(model_path=model_path, upscale=1)  # type: ignore[attr-defined] | ||||
|             selected_device = None | ||||
|             device_priority = [] | ||||
| 
 | ||||
|             if TENSORRT_AVAILABLE and torch.cuda.is_available(): | ||||
|                 selected_device = torch.device("cuda") | ||||
|                 device_priority.append("TensorRT+CUDA") | ||||
|             elif torch.cuda.is_available(): | ||||
|                 selected_device = torch.device("cuda") | ||||
|                 device_priority.append("CUDA") | ||||
|             elif torch.backends.mps.is_available() and platform.system() == "Darwin": | ||||
|                 selected_device = torch.device("mps") | ||||
|                 device_priority.append("MPS") | ||||
|             elif not torch.cuda.is_available(): | ||||
|                 selected_device = torch.device("cpu") | ||||
|                 device_priority.append("CPU") | ||||
|              | ||||
|             FACE_ENHANCER = gfpgan.GFPGANer(model_path=model_path, upscale=1, device=selected_device) | ||||
| 
 | ||||
|             # for debug: | ||||
|             print(f"Selected device: {selected_device} and device priority: {device_priority}") | ||||
|     return FACE_ENHANCER | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,44 +1,56 @@ | |||
| import os # <-- Added for os.path.exists | ||||
| from typing import Any, List | ||||
| import cv2 | ||||
| import insightface | ||||
| import threading | ||||
| 
 | ||||
| import numpy as np | ||||
| import modules.globals | ||||
| import logging | ||||
| import modules.processors.frame.core | ||||
| # Ensure update_status is imported if not already globally accessible | ||||
| # If it's part of modules.core, it might already be accessible via modules.core.update_status | ||||
| from modules.core import update_status | ||||
| from modules.face_analyser import get_one_face, get_many_faces, default_source_face | ||||
| from modules.typing import Face, Frame | ||||
| from modules.utilities import conditional_download, resolve_relative_path, is_image, is_video | ||||
| from modules.utilities import ( | ||||
|     conditional_download, | ||||
|     is_image, | ||||
|     is_video, | ||||
| ) | ||||
| from modules.cluster_analysis import find_closest_centroid | ||||
| import os | ||||
| 
 | ||||
| FACE_SWAPPER = None | ||||
| THREAD_LOCK = threading.Lock() | ||||
| NAME = 'DLC.FACE-SWAPPER' | ||||
| NAME = "DLC.FACE-SWAPPER" | ||||
| 
 | ||||
| abs_dir = os.path.dirname(os.path.abspath(__file__)) | ||||
| models_dir = os.path.join( | ||||
|     os.path.dirname(os.path.dirname(os.path.dirname(abs_dir))), "models" | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| def pre_check() -> bool: | ||||
|     download_directory_path = resolve_relative_path('../models') | ||||
|     # Ensure both models are mentioned or downloaded if necessary | ||||
|     # Conditional download might need adjustment if you want it to fetch FP32 too | ||||
|     conditional_download(download_directory_path, ['https://huggingface.co/hacksider/deep-live-cam/blob/main/inswapper_128_fp16.onnx']) | ||||
|     # Add a check or download for the FP32 model if you have a URL | ||||
|     # conditional_download(download_directory_path, ['URL_TO_FP32_MODEL_HERE']) | ||||
|     download_directory_path = abs_dir | ||||
|     conditional_download( | ||||
|         download_directory_path, | ||||
|         [ | ||||
|             "https://huggingface.co/hacksider/deep-live-cam/blob/main/inswapper_128_fp16.onnx" | ||||
|         ], | ||||
|     ) | ||||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def pre_start() -> bool: | ||||
|     # --- No changes needed in pre_start --- | ||||
|     if not modules.globals.map_faces and not is_image(modules.globals.source_path): | ||||
|         update_status('Select an image for source path.', NAME) | ||||
|         update_status("Select an image for source path.", NAME) | ||||
|         return False | ||||
|     elif not modules.globals.map_faces and not get_one_face(cv2.imread(modules.globals.source_path)): | ||||
|         update_status('No face in source path detected.', NAME) | ||||
|     elif not modules.globals.map_faces and not get_one_face( | ||||
|         cv2.imread(modules.globals.source_path) | ||||
|     ): | ||||
|         update_status("No face in source path detected.", NAME) | ||||
|         return False | ||||
|     if not is_image(modules.globals.target_path) and not is_video(modules.globals.target_path): | ||||
|         update_status('Select an image or video for target path.', NAME) | ||||
|     if not is_image(modules.globals.target_path) and not is_video( | ||||
|         modules.globals.target_path | ||||
|     ): | ||||
|         update_status("Select an image or video for target path.", NAME) | ||||
|         return False | ||||
|     return True | ||||
| 
 | ||||
|  | @ -48,78 +60,67 @@ def get_face_swapper() -> Any: | |||
| 
 | ||||
|     with THREAD_LOCK: | ||||
|         if FACE_SWAPPER is None: | ||||
|             # --- MODIFICATION START --- | ||||
|             # Define paths for both FP32 and FP16 models | ||||
|             model_dir = resolve_relative_path('../models') | ||||
|             model_path_fp32 = os.path.join(model_dir, 'inswapper_128.onnx') | ||||
|             model_path_fp16 = os.path.join(model_dir, 'inswapper_128_fp16.onnx') | ||||
|             chosen_model_path = None | ||||
| 
 | ||||
|             # Prioritize FP32 model | ||||
|             if os.path.exists(model_path_fp32): | ||||
|                 chosen_model_path = model_path_fp32 | ||||
|                 update_status(f"Loading FP32 model: {os.path.basename(chosen_model_path)}", NAME) | ||||
|             # Fallback to FP16 model | ||||
|             elif os.path.exists(model_path_fp16): | ||||
|                 chosen_model_path = model_path_fp16 | ||||
|                 update_status(f"FP32 model not found. Loading FP16 model: {os.path.basename(chosen_model_path)}", NAME) | ||||
|             # Error if neither model is found | ||||
|             else: | ||||
|                 error_message = f"Face Swapper model not found. Please ensure 'inswapper_128.onnx' (recommended) or 'inswapper_128_fp16.onnx' exists in the '{model_dir}' directory." | ||||
|                 update_status(error_message, NAME) | ||||
|                 raise FileNotFoundError(error_message) | ||||
| 
 | ||||
|             # Load the chosen model | ||||
|             try: | ||||
|                 FACE_SWAPPER = insightface.model_zoo.get_model(chosen_model_path, providers=modules.globals.execution_providers) | ||||
|             except Exception as e: | ||||
|                 update_status(f"Error loading Face Swapper model {os.path.basename(chosen_model_path)}: {e}", NAME) | ||||
|                 # Optionally, re-raise the exception or handle it more gracefully | ||||
|                 raise e | ||||
|             # --- MODIFICATION END --- | ||||
|             model_path = os.path.join(models_dir, "inswapper_128_fp16.onnx") | ||||
|             FACE_SWAPPER = insightface.model_zoo.get_model( | ||||
|                 model_path, providers=modules.globals.execution_providers | ||||
|             ) | ||||
|     return FACE_SWAPPER | ||||
| 
 | ||||
| 
 | ||||
| def swap_face(source_face: Face, target_face: Face, temp_frame: Frame) -> Frame: | ||||
|     # --- No changes needed in swap_face --- | ||||
|     swapper = get_face_swapper() | ||||
|     if swapper is None: | ||||
|          # Handle case where model failed to load | ||||
|          update_status("Face swapper model not loaded, skipping swap.", NAME) | ||||
|          return temp_frame | ||||
|     return swapper.get(temp_frame, target_face, source_face, paste_back=True) | ||||
|     face_swapper = get_face_swapper() | ||||
| 
 | ||||
|     # Apply the face swap | ||||
|     swapped_frame = face_swapper.get( | ||||
|         temp_frame, target_face, source_face, paste_back=True | ||||
|     ) | ||||
| 
 | ||||
|     if modules.globals.mouth_mask: | ||||
|         # Create a mask for the target face | ||||
|         face_mask = create_face_mask(target_face, temp_frame) | ||||
| 
 | ||||
|         # Create the mouth mask | ||||
|         mouth_mask, mouth_cutout, mouth_box, lower_lip_polygon = ( | ||||
|             create_lower_mouth_mask(target_face, temp_frame) | ||||
|         ) | ||||
| 
 | ||||
|         # Apply the mouth area | ||||
|         swapped_frame = apply_mouth_area( | ||||
|             swapped_frame, mouth_cutout, mouth_box, face_mask, lower_lip_polygon | ||||
|         ) | ||||
| 
 | ||||
|         if modules.globals.show_mouth_mask_box: | ||||
|             mouth_mask_data = (mouth_mask, mouth_cutout, mouth_box, lower_lip_polygon) | ||||
|             swapped_frame = draw_mouth_mask_visualization( | ||||
|                 swapped_frame, target_face, mouth_mask_data | ||||
|             ) | ||||
| 
 | ||||
|     return swapped_frame | ||||
| 
 | ||||
| 
 | ||||
| def process_frame(source_face: Face, temp_frame: Frame) -> Frame: | ||||
|     # --- No changes needed in process_frame --- | ||||
|     # Ensure the frame is in RGB format if color correction is enabled | ||||
|     # Note: InsightFace swapper often expects BGR by default. Double-check if color issues appear. | ||||
|     # If color correction is needed *before* swapping and insightface needs BGR: | ||||
|     # original_was_bgr = True # Assume input is BGR | ||||
|     # if modules.globals.color_correction: | ||||
|     #     temp_frame = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB) | ||||
|     #     original_was_bgr = False # Now it's RGB | ||||
|     if modules.globals.color_correction: | ||||
|         temp_frame = cv2.cvtColor(temp_frame, cv2.COLOR_BGR2RGB) | ||||
| 
 | ||||
|     if modules.globals.many_faces: | ||||
|         many_faces = get_many_faces(temp_frame) | ||||
|         if many_faces: | ||||
|             for target_face in many_faces: | ||||
|                 temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
|                 if source_face and target_face: | ||||
|                     temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
|                 else: | ||||
|                     print("Face detection failed for target/source.") | ||||
|     else: | ||||
|         target_face = get_one_face(temp_frame) | ||||
|         if target_face: | ||||
|         if target_face and source_face: | ||||
|             temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
| 
 | ||||
|     # Convert back if necessary (example, might not be needed depending on workflow) | ||||
|     # if modules.globals.color_correction and not original_was_bgr: | ||||
|     #      temp_frame = cv2.cvtColor(temp_frame, cv2.COLOR_RGB2BGR) | ||||
| 
 | ||||
|         else: | ||||
|             logging.error("Face detection failed for target or source.") | ||||
|     return temp_frame | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def process_frame_v2(temp_frame: Frame, temp_frame_path: str = "") -> Frame: | ||||
|     # --- No changes needed in process_frame_v2 --- | ||||
|     # (Assuming swap_face handles the potential None return from get_face_swapper) | ||||
|     if is_image(modules.globals.target_path): | ||||
|         if modules.globals.many_faces: | ||||
|             source_face = default_source_face() | ||||
|  | @ -141,7 +142,7 @@ def process_frame_v2(temp_frame: Frame, temp_frame_path: str = "") -> Frame: | |||
|                 target_frame = [f for f in map['target_faces_in_frame'] if f['location'] == temp_frame_path] | ||||
| 
 | ||||
|                 for frame in target_frame: | ||||
|                     for target_face in frame['faces']: | ||||
|                     for target_face in frame["faces"]: | ||||
|                         temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
| 
 | ||||
|         elif not modules.globals.many_faces: | ||||
|  | @ -151,9 +152,10 @@ def process_frame_v2(temp_frame: Frame, temp_frame_path: str = "") -> Frame: | |||
|                     source_face = map['source']['face'] | ||||
| 
 | ||||
|                     for frame in target_frame: | ||||
|                         for target_face in frame['faces']: | ||||
|                         for target_face in frame["faces"]: | ||||
|                             temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
|     else: # Fallback for neither image nor video (e.g., live feed?) | ||||
| 
 | ||||
|     else: | ||||
|         detected_faces = get_many_faces(temp_frame) | ||||
|         if modules.globals.many_faces: | ||||
|             if detected_faces: | ||||
|  | @ -162,96 +164,89 @@ def process_frame_v2(temp_frame: Frame, temp_frame_path: str = "") -> Frame: | |||
|                     temp_frame = swap_face(source_face, target_face, temp_frame) | ||||
| 
 | ||||
|         elif not modules.globals.many_faces: | ||||
|             if detected_faces and hasattr(modules.globals, 'simple_map') and modules.globals.simple_map: # Check simple_map exists | ||||
|                 if len(detected_faces) <= len(modules.globals.simple_map['target_embeddings']): | ||||
|             if detected_faces: | ||||
|                 if len(detected_faces) <= len( | ||||
|                     modules.globals.simple_map["target_embeddings"] | ||||
|                 ): | ||||
|                     for detected_face in detected_faces: | ||||
|                         closest_centroid_index, _ = find_closest_centroid(modules.globals.simple_map['target_embeddings'], detected_face.normed_embedding) | ||||
|                         temp_frame = swap_face(modules.globals.simple_map['source_faces'][closest_centroid_index], detected_face, temp_frame) | ||||
|                         closest_centroid_index, _ = find_closest_centroid( | ||||
|                             modules.globals.simple_map["target_embeddings"], | ||||
|                             detected_face.normed_embedding, | ||||
|                         ) | ||||
| 
 | ||||
|                         temp_frame = swap_face( | ||||
|                             modules.globals.simple_map["source_faces"][ | ||||
|                                 closest_centroid_index | ||||
|                             ], | ||||
|                             detected_face, | ||||
|                             temp_frame, | ||||
|                         ) | ||||
|                 else: | ||||
|                     detected_faces_centroids = [face.normed_embedding for face in detected_faces] | ||||
|                     detected_faces_centroids = [] | ||||
|                     for face in detected_faces: | ||||
|                         detected_faces_centroids.append(face.normed_embedding) | ||||
|                     i = 0 | ||||
|                     for target_embedding in modules.globals.simple_map['target_embeddings']: | ||||
|                         closest_centroid_index, _ = find_closest_centroid(detected_faces_centroids, target_embedding) | ||||
|                         # Ensure index is valid before accessing detected_faces | ||||
|                         if closest_centroid_index < len(detected_faces): | ||||
|                             temp_frame = swap_face(modules.globals.simple_map['source_faces'][i], detected_faces[closest_centroid_index], temp_frame) | ||||
|                     for target_embedding in modules.globals.simple_map[ | ||||
|                         "target_embeddings" | ||||
|                     ]: | ||||
|                         closest_centroid_index, _ = find_closest_centroid( | ||||
|                             detected_faces_centroids, target_embedding | ||||
|                         ) | ||||
| 
 | ||||
|                         temp_frame = swap_face( | ||||
|                             modules.globals.simple_map["source_faces"][i], | ||||
|                             detected_faces[closest_centroid_index], | ||||
|                             temp_frame, | ||||
|                         ) | ||||
|                         i += 1 | ||||
|     return temp_frame | ||||
| 
 | ||||
| 
 | ||||
| def process_frames(source_path: str, temp_frame_paths: List[str], progress: Any = None) -> None: | ||||
|     # --- No changes needed in process_frames --- | ||||
|     # Note: Ensure get_one_face is called only once if possible for efficiency if !map_faces | ||||
|     source_face = None | ||||
| def process_frames( | ||||
|     source_path: str, temp_frame_paths: List[str], progress: Any = None | ||||
| ) -> None: | ||||
|     if not modules.globals.map_faces: | ||||
|         source_img = cv2.imread(source_path) | ||||
|         if source_img is not None: | ||||
|             source_face = get_one_face(source_img) | ||||
|         if source_face is None: | ||||
|              update_status(f"Could not find face in source image: {source_path}, skipping swap.", NAME) | ||||
|              # If no source face, maybe skip processing? Or handle differently. | ||||
|              # For now, it will proceed but swap_face might fail later. | ||||
| 
 | ||||
|     for temp_frame_path in temp_frame_paths: | ||||
|         temp_frame = cv2.imread(temp_frame_path) | ||||
|         if temp_frame is None: | ||||
|             update_status(f"Warning: Could not read frame {temp_frame_path}", NAME) | ||||
|             if progress: progress.update(1) # Still update progress even if frame fails | ||||
|             continue # Skip to next frame | ||||
| 
 | ||||
|         try: | ||||
|             if not modules.globals.map_faces: | ||||
|                 if source_face: # Only process if source face was found | ||||
|                     result = process_frame(source_face, temp_frame) | ||||
|                 else: | ||||
|                     result = temp_frame # No source face, return original frame | ||||
|             else: | ||||
|                  result = process_frame_v2(temp_frame, temp_frame_path) | ||||
| 
 | ||||
|             cv2.imwrite(temp_frame_path, result) | ||||
|         except Exception as exception: | ||||
|             update_status(f"Error processing frame {os.path.basename(temp_frame_path)}: {exception}", NAME) | ||||
|             # Decide whether to 'pass' (continue processing other frames) or raise | ||||
|             pass # Continue processing other frames | ||||
|         finally: | ||||
|         source_face = get_one_face(cv2.imread(source_path)) | ||||
|         for temp_frame_path in temp_frame_paths: | ||||
|             temp_frame = cv2.imread(temp_frame_path) | ||||
|             try: | ||||
|                 result = process_frame(source_face, temp_frame) | ||||
|                 cv2.imwrite(temp_frame_path, result) | ||||
|             except Exception as exception: | ||||
|                 print(exception) | ||||
|                 pass | ||||
|             if progress: | ||||
|                 progress.update(1) | ||||
|     else: | ||||
|         for temp_frame_path in temp_frame_paths: | ||||
|             temp_frame = cv2.imread(temp_frame_path) | ||||
|             try: | ||||
|                 result = process_frame_v2(temp_frame, temp_frame_path) | ||||
|                 cv2.imwrite(temp_frame_path, result) | ||||
|             except Exception as exception: | ||||
|                 print(exception) | ||||
|                 pass | ||||
|             if progress: | ||||
|                 progress.update(1) | ||||
| 
 | ||||
| 
 | ||||
| def process_image(source_path: str, target_path: str, output_path: str) -> None: | ||||
|     # --- No changes needed in process_image --- | ||||
|     # Note: Added checks for successful image reads and face detection | ||||
|     target_frame = cv2.imread(target_path) # Read original target for processing | ||||
|     if target_frame is None: | ||||
|         update_status(f"Error: Could not read target image: {target_path}", NAME) | ||||
|         return | ||||
| 
 | ||||
|     if not modules.globals.map_faces: | ||||
|         source_img = cv2.imread(source_path) | ||||
|         if source_img is None: | ||||
|              update_status(f"Error: Could not read source image: {source_path}", NAME) | ||||
|              return | ||||
|         source_face = get_one_face(source_img) | ||||
|         if source_face is None: | ||||
|             update_status(f"Error: No face found in source image: {source_path}", NAME) | ||||
|             return | ||||
| 
 | ||||
|         source_face = get_one_face(cv2.imread(source_path)) | ||||
|         target_frame = cv2.imread(target_path) | ||||
|         result = process_frame(source_face, target_frame) | ||||
|         cv2.imwrite(output_path, result) | ||||
|     else: | ||||
|         if modules.globals.many_faces: | ||||
|             update_status('Many faces enabled. Using first source image (if applicable in v2). Processing...', NAME) | ||||
|         # For process_frame_v2 on single image, it reads the 'output_path' which should be a copy | ||||
|         # Let's process the 'target_frame' we read instead. | ||||
|         result = process_frame_v2(target_frame) # Process the frame directly | ||||
| 
 | ||||
|     # Write the final result to the output path | ||||
|     success = cv2.imwrite(output_path, result) | ||||
|     if not success: | ||||
|         update_status(f"Error: Failed to write output image to: {output_path}", NAME) | ||||
|             update_status( | ||||
|                 "Many faces enabled. Using first source image. Progressing...", NAME | ||||
|             ) | ||||
|         target_frame = cv2.imread(output_path) | ||||
|         result = process_frame_v2(target_frame) | ||||
|         cv2.imwrite(output_path, result) | ||||
| 
 | ||||
| 
 | ||||
| def process_video(source_path: str, temp_frame_paths: List[str]) -> None: | ||||
|     # --- No changes needed in process_video --- | ||||
|     if modules.globals.map_faces and modules.globals.many_faces: | ||||
|         update_status('Many faces enabled. Using first source image (if applicable in v2). Processing...', NAME) | ||||
|     # The core processing logic is delegated, which is good. | ||||
|  |  | |||
|  | @ -429,7 +429,7 @@ def create_source_target_popup( | |||
|             POPUP.destroy() | ||||
|             select_output_path(start) | ||||
|         else: | ||||
|             update_pop_status("Atleast 1 source with target is required!") | ||||
|             update_pop_status("At least 1 source with target is required!") | ||||
| 
 | ||||
|     scrollable_frame = ctk.CTkScrollableFrame( | ||||
|         POPUP, width=POPUP_SCROLL_WIDTH, height=POPUP_SCROLL_HEIGHT | ||||
|  | @ -489,7 +489,7 @@ def update_popup_source( | |||
|     global source_label_dict | ||||
| 
 | ||||
|     source_path = ctk.filedialog.askopenfilename( | ||||
|         title=_("select an source image"), | ||||
|         title=_("select a source image"), | ||||
|         initialdir=RECENT_DIRECTORY_SOURCE, | ||||
|         filetypes=[img_ft], | ||||
|     ) | ||||
|  | @ -584,7 +584,7 @@ def select_source_path() -> None: | |||
| 
 | ||||
|     PREVIEW.withdraw() | ||||
|     source_path = ctk.filedialog.askopenfilename( | ||||
|         title=_("select an source image"), | ||||
|         title=_("select a source image"), | ||||
|         initialdir=RECENT_DIRECTORY_SOURCE, | ||||
|         filetypes=[img_ft], | ||||
|     ) | ||||
|  | @ -627,7 +627,7 @@ def select_target_path() -> None: | |||
| 
 | ||||
|     PREVIEW.withdraw() | ||||
|     target_path = ctk.filedialog.askopenfilename( | ||||
|         title=_("select an target image or video"), | ||||
|         title=_("select a target image or video"), | ||||
|         initialdir=RECENT_DIRECTORY_TARGET, | ||||
|         filetypes=[img_ft, vid_ft], | ||||
|     ) | ||||
|  | @ -1108,7 +1108,7 @@ def update_webcam_source( | |||
|     global source_label_dict_live | ||||
| 
 | ||||
|     source_path = ctk.filedialog.askopenfilename( | ||||
|         title=_("select an source image"), | ||||
|         title=_("select a source image"), | ||||
|         initialdir=RECENT_DIRECTORY_SOURCE, | ||||
|         filetypes=[img_ft], | ||||
|     ) | ||||
|  | @ -1160,7 +1160,7 @@ def update_webcam_target( | |||
|     global target_label_dict_live | ||||
| 
 | ||||
|     target_path = ctk.filedialog.askopenfilename( | ||||
|         title=_("select an target image"), | ||||
|         title=_("select a target image"), | ||||
|         initialdir=RECENT_DIRECTORY_SOURCE, | ||||
|         filetypes=[img_ft], | ||||
|     ) | ||||
|  |  | |||
|  | @ -1,23 +1,21 @@ | |||
| --extra-index-url https://download.pytorch.org/whl/cu118 | ||||
| 
 | ||||
| numpy>=1.23.5,<2 | ||||
| typing-extensions>=4.8.0 | ||||
| opencv-python==4.11.0.86 | ||||
| onnx==1.17.0 | ||||
| cv2_enumerate_cameras==1.1.18.3 | ||||
| opencv-python==4.10.0.84 | ||||
| cv2_enumerate_cameras==1.1.15 | ||||
| onnx==1.16.0 | ||||
| insightface==0.7.3 | ||||
| psutil==5.9.8 | ||||
| tk==0.1.0 | ||||
| customtkinter==5.2.2 | ||||
| pillow==11.1.0 | ||||
| torch; sys_platform != 'darwin' --index-url https://download.pytorch.org/whl/cu126 | ||||
| torch; sys_platform == 'darwin' --index-url https://download.pytorch.org/whl/cu126 | ||||
| torchvision; sys_platform != 'darwin' --index-url https://download.pytorch.org/whl/cu126 | ||||
| torchvision; sys_platform == 'darwin' --index-url https://download.pytorch.org/whl/cu126 | ||||
| torch==2.5.1+cu118; sys_platform != 'darwin' | ||||
| torch==2.5.1; sys_platform == 'darwin' | ||||
| torchvision==0.20.1; sys_platform != 'darwin' | ||||
| torchvision==0.20.1; sys_platform == 'darwin' | ||||
| onnxruntime-silicon==1.16.3; sys_platform == 'darwin' and platform_machine == 'arm64' | ||||
| onnxruntime-gpu==1.21; sys_platform != 'darwin' | ||||
| onnxruntime-gpu==1.17; sys_platform != 'darwin' | ||||
| tensorflow; sys_platform != 'darwin' | ||||
| opennsfw2==0.10.2 | ||||
| protobuf==4.23.2 | ||||
| tqdm==4.66.4 | ||||
| gfpgan==1.3.8 | ||||
| tkinterdnd2==0.4.2 | ||||
| pygrabber==0.2 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue