diff --git a/CHANGELOG.md b/CHANGELOG.md index f786340..09063fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## Version 4.0.1 + +**Release date:** 27 July 2025 + +### Model Cleanup and Optimization + +#### 1.1 **SuperResolution-10 Model Removal** + +- **Model Deprecation**: Removed the SuperResolution-10 model from the application due to performance and compatibility issues. +- **Code Cleanup**: Eliminated the dedicated `AI_super_resolution` class and all related processing pipelines. +- **UI Updates**: Removed SuperResolution-10 from model selection dropdown and information dialogs. +- **Memory Optimization**: Cleaned up VRAM usage configurations by removing SuperResolution-10 entries (0.8 GB allocation). +- **Streamlined Processing**: Simplified the upscaling orchestrator by removing SuperResolution-specific routing logic. +- **Model List Cleanup**: Removed `SuperResolution_models_list` from the main AI models collection. + +#### 1.2 **Performance Improvements** + +- **Reduced Memory Footprint**: Application now uses less memory without the SuperResolution-10 model overhead. +- **Simplified Code Paths**: Cleaner processing logic with fewer conditional branches for model selection. +- **Enhanced Stability**: Removed potential failure points associated with the deprecated model. + +--- + ## Version 4.0 **Release date:** 18 July 2025 @@ -140,8 +163,6 @@ - The application now explicitly handles images with an alpha channel (4-channel BGRA) when using face restoration models. A new import for `COLOR_BGRA2BGR` was added, and it is used within `preprocess_face_image` to convert images to the 3-channel BGR format expected by the GFPGAN model. This prevents runtime errors and ensures correct processing of PNGs or other images with transparency. ---- - ## Version 2.2 **Release date:** 7 July 2025 @@ -219,8 +240,6 @@ - Core methods in AI classes now include checks for `None` inputs and feature default fallbacks (`case _:`) in `match` statements to prevent unexpected errors with unsupported data. ---- - ## Version 2.1 **Release date:** 23 June 2025 diff --git a/README.md b/README.md index 0d0de60..b67634a 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@
-# Warlock-Studio +# 🎭 Warlock-Studio ### _AI Media Enhancement Suite_ [![Build Status](https://img.shields.io/badge/build-Stable_Release-blue?style=for-the-badge)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases) -[![Version](https://img.shields.io/badge/Version-4.0--07.25-darkred?style=for-the-badge)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases/tag/4.0) -[![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge)](LICENSE) +[![Version](https://img.shields.io/badge/Version-4.0.1--07.25-darkred?style=for-the-badge)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases/tag/4.0.1) +[![License](https://img.shields.io/badge/License-MIT-purple?style=for-the-badge)](LICENSE) [![Downloads](https://img.shields.io/github/downloads/Ivan-Ayub97/Warlock-Studio/total?style=for-the-badge&color=gold)](https://github.com/Ivan-Ayub97/Warlock-Studio/releases) _Transform your media with cutting-edge AI technology_ @@ -19,11 +19,13 @@ _Transform your media with cutting-edge AI technology_ **Warlock-Studio** is a powerful, open-source desktop application for Windows that integrates state-of-the-art AI models for video and image enhancement. Inspired by the work of [Djdefrag](https://github.com/Djdefrag) on tools like **QualityScaler** and **FluidFrames**, this suite provides a unified, high-performance interface for upscaling, restoration, and frame interpolation. -Version 4.0 continues this evolution with the addition of **SuperResolution-10** model integration, enhanced AI architecture, and improved code stability for even better performance and reliability. +Version 4.0.1 continues this evolution with enhanced AI architecture and improved code stability for even better performance and reliability. Note: The SuperResolution-10 model has been removed in this version for better performance optimization. --- -### ► Download Installer (v4.0) +### ► Download Installer (v4.0.1) - Now Lightweight + +🚀 **NEW**: Installer size reduced from **1.4GB to ~450MB**! AI models (400MB) are automatically downloaded when first launched. Get the latest stable release from any of the following platforms: @@ -35,7 +37,7 @@ Get the latest stable release from any of the following platforms: - + Download from GitHub @@ -47,13 +49,13 @@ Get the latest stable release from any of the following platforms: ## Key Features - **State-of-the-Art AI Models** - A comprehensive suite including Real-ESRGAN, BSRGAN, IRCNN, **GFPGAN**, **RIFE**, and **SuperResolution-10** for denoising, resolution enhancement, detail restoration, extreme upscaling, and smooth frame interpolation. + A comprehensive suite including Real-ESRGAN, BSRGAN, IRCNN, **GFPGAN**, and **RIFE** for denoising, resolution enhancement, detail restoration, upscaling, and smooth frame interpolation. - **AI Face Restoration** Restore and enhance faces in old, blurry, or low-quality photos and videos with the integrated GFPGAN model, bringing cherished memories back to life. -- **SuperResolution-10 Model (New in v4.0)** - Extreme 10x upscaling capabilities specifically designed for very low-resolution images, perfect for bringing old photos back to life with exceptional detail. +- **High-Quality Upscaling Models** + Real-ESRGAN and BSRGAN models provide excellent upscaling capabilities for various image types, from anime to photorealistic content. - **AI Frame Interpolation & Slow Motion** Generate new in-between frames using RIFE to create ultra-smooth **2x, 4x, or 8x** motion or dramatic slow-motion effects. @@ -72,14 +74,14 @@ Get the latest stable release from any of the following platforms: --- -## What's New in Version 4.0 +## What's New in Version 4.0.1 -- ✅ **SuperResolution-10 Model:** Added support for the SuperResolution-10 model, providing extreme 10x upscaling capabilities specifically designed for very low-resolution images. -- ✅ **Enhanced AI Architecture:** Implemented the missing `AI_model_base` class with robust ONNX model loading, GPU acceleration support, and comprehensive error handling. +- 🔧 **Model Optimization:** Removed SuperResolution-10 model to improve overall performance and reduce complexity. For extreme upscaling needs, we recommend using Real-ESRGAN or BSRGAN models which provide excellent results. +- ✅ **Enhanced AI Architecture:** Implemented robust ONNX model loading, GPU acceleration support, and comprehensive error handling. - ✅ **Code Quality Improvements:** Fixed critical import errors, consolidated duplicate code sections, and improved type annotations for better maintainability. - ✅ **Improved Error Handling:** Added graceful degradation mechanisms that prevent crashes and provide meaningful error messages during processing. -- ✅ **Complete Model Integration:** SuperResolution-10 is fully integrated into the UI, processing pipeline, and information dialogs with proper VRAM management. -- 🚀 **Smart Model Distribution:** New lightweight installer (300MB vs 1.4GB) with automatic AI model download system that fetches models on first launch. +- ✅ **Streamlined Model Integration:** Optimized model integration in the UI and processing pipeline for better performance. +- 🚀 **Smart Model Distribution:** Lightweight installer (~450MB) with automatic AI model download system that fetches models on first launch. - 📦 **Optimized Packaging:** Enhanced PyInstaller configuration excludes AI models from executable, significantly reducing download and installation time. --- @@ -90,8 +92,8 @@ Version 4.0 introduces a revolutionary approach to AI model distribution: ### 🎯 **Lightweight Installation** -- **Installer Size:** Reduced from 1.4GB to ~300MB (78% size reduction) -- **First Launch:** AI models (327MB) download automatically with progress tracking +- **Installer Size:** Reduced from 1.4GB to ~450MB (68% size reduction) +- **First Launch:** AI models (~400MB) download automatically with progress tracking - **Bandwidth Friendly:** Users with limited internet can get started faster ### 🛡️ **Reliability Features** @@ -104,7 +106,7 @@ Version 4.0 introduces a revolutionary approach to AI model distribution: ## Interface Previews -### 🔹 Main View (v4.0) +### 🔹 Main View (v4.0.1) ![Screenshot of Warlock-Studio's main interface](rsc/Capture.png) @@ -168,12 +170,12 @@ Warlock-Studio uses [PyInstaller](https://www.pyinstaller.org/) and [Inno Setup] --- -## Development Status — v4.0-07.25 +## Development Status — v4.0.1-07.25 | Component | Status | Notes | | :---------------------------------- | :-------------- | :----------------------------------------------------------------------------------- | | **Upscaling Models (ESRGAN, etc.)** | 🟢 **Stable** | Fully integrated with dynamic VRAM recovery for enhanced stability. | -| **SuperResolution-10 Model** | 🟢 **New** | Extreme 10x upscaling for very low-resolution images with robust error handling. | +| **Optimized Model Suite** | 🟢 **Enhanced** | Streamlined AI models for optimal performance and reliability. | | **Face Restoration (GFPGAN)** | 🟢 **Stable** | High-quality face enhancement and restoration capabilities. | | **Frame Interpolation (RIFE)** | 🟢 **Stable** | Includes slow-motion and intermediate frame generation capabilities. | | **Batch Processing** | 🟢 **Stable** | Reliable processing with improved error handling and resource management. | @@ -202,7 +204,6 @@ Warlock-Studio/ ├──RealSRx4_Anime_fp16.onnx ├──RIFE_fp32.onnx ├──RIFE_Lite_fp32.onnx - └──super-resolution-10.onnx ├──Assets/ │ └──├──banner.png @@ -248,37 +249,31 @@ Warlock-Studio/ ├──Warlock-Studio.py # Main └──Warlock-Studio.spec ``` -## AI models Workflow -![Workflow](rsc/WorkflowBSRGAN.png) -![Workflow](rsc/WorkflowIRCNN.png) -![Workflow](rsc/WorkflowRealESRGAN.png) -![Workflow](rsc/WorkflowRIFE.png) --- ## Integrated Technologies & Licenses -| Technology | License | Author / Maintainer | Source Code / Homepage | -| :------------------ | :------------------------ | :------------------------------------------------------------ | :-------------------------------------------------------------------------------------------- | -| QualityScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler) | -| RealScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/RealScaler) | -| FluidFrames | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames) | -| Real-ESRGAN | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) | -| GFPGAN | Apache 2.0 | [TencentARC / Xintao Wang](https://github.com/TencentARC) | [GitHub](https://github.com/TencentARC/GFPGAN) | -| RIFE | Apache 2.0 | [hzwer](https://github.com/hzwer) | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) | -| SRGAN | CC BY-NC-SA 4.0 | [TensorLayer Community](https://github.com/tensorlayer) | [GitHub](https://github.com/tensorlayer/srgan) | -| BSRGAN | Apache 2.0 | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/BSRGAN) | -| IRCNN | BSD / Mixed | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/IRCNN) | -| Anime4K | MIT | [Tianyang Zhang (bloc97)](https://github.com/bloc97) | [GitHub](https://github.com/bloc97/Anime4K) | -| Super Resolution 10 | MIT | [ONNX Model Zoo Contributors](https://github.com/onnx/models) | [GitHub](https://github.com/onnx/models/tree/main/vision/super_resolution/sub_pixel_cnn_2016) | -| ONNX Runtime | MIT | [Microsoft](https://github.com/microsoft) | [GitHub](https://github.com/microsoft/onnxruntime) | -| PyTorch | BSD 3-Clause | [Meta AI](https://pytorch.org/) | [GitHub](https://github.com/pytorch/pytorch) | -| FFmpeg | LGPL / GPL (varies) | [FFmpeg Team](https://ffmpeg.org/) | [Official Site](https://ffmpeg.org) | -| ExifTool | Perl Artistic License | [Phil Harvey](https://exiftool.org/) | [Official Site](https://exiftool.org/) | -| DirectML | MIT | [Microsoft](https://github.com/microsoft/) | [GitHub](https://github.com/microsoft/DirectML) | -| Python | PSF License | [Python Software Foundation](https://www.python.org/) | [Official Site](https://www.python.org) | -| PyInstaller | GPLv2+ | [PyInstaller Team](https://github.com/pyinstaller) | [GitHub](https://github.com/pyinstaller/pyinstaller) | -| Inno Setup | Custom License | [Jordan Russell](http://www.jrsoftware.org/) | [Official Site](http://www.jrsoftware.org/isinfo.php) | +| Technology | License | Author / Maintainer | Source Code / Homepage | +| :------------ | :------------------------ | :-------------------------------------------------------- | :--------------------------------------------------------- | +| QualityScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/QualityScaler) | +| RealScaler | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/RealScaler) | +| FluidFrames | MIT | [Djdefrag](https://github.com/Djdefrag) | [GitHub](https://github.com/Djdefrag/FluidFrames) | +| Real-ESRGAN | BSD 3-Clause / Apache 2.0 | [Xintao Wang](https://github.com/xinntao) | [GitHub](https://github.com/xinntao/Real-ESRGAN) | +| GFPGAN | Apache 2.0 | [TencentARC / Xintao Wang](https://github.com/TencentARC) | [GitHub](https://github.com/TencentARC/GFPGAN) | +| RIFE | Apache 2.0 | [hzwer](https://github.com/hzwer) | [GitHub](https://github.com/megvii-research/ECCV2022-RIFE) | +| SRGAN | CC BY-NC-SA 4.0 | [TensorLayer Community](https://github.com/tensorlayer) | [GitHub](https://github.com/tensorlayer/srgan) | +| BSRGAN | Apache 2.0 | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/BSRGAN) | +| IRCNN | BSD / Mixed | [Kai Zhang](https://github.com/cszn) | [GitHub](https://github.com/cszn/IRCNN) | +| Anime4K | MIT | [Tianyang Zhang (bloc97)](https://github.com/bloc97) | [GitHub](https://github.com/bloc97/Anime4K) | +| ONNX Runtime | MIT | [Microsoft](https://github.com/microsoft) | [GitHub](https://github.com/microsoft/onnxruntime) | +| PyTorch | BSD 3-Clause | [Meta AI](https://pytorch.org/) | [GitHub](https://github.com/pytorch/pytorch) | +| FFmpeg | LGPL / GPL (varies) | [FFmpeg Team](https://ffmpeg.org/) | [Official Site](https://ffmpeg.org) | +| ExifTool | Perl Artistic License | [Phil Harvey](https://exiftool.org/) | [Official Site](https://exiftool.org/) | +| DirectML | MIT | [Microsoft](https://github.com/microsoft/) | [GitHub](https://github.com/microsoft/DirectML) | +| Python | PSF License | [Python Software Foundation](https://www.python.org/) | [Official Site](https://www.python.org) | +| PyInstaller | GPLv2+ | [PyInstaller Team](https://github.com/pyinstaller) | [GitHub](https://github.com/pyinstaller/pyinstaller) | +| Inno Setup | Custom License | [Jordan Russell](http://www.jrsoftware.org/) | [Official Site](http://www.jrsoftware.org/isinfo.php) | --- diff --git a/Setup.iss b/Setup.iss index e3a8bd8..9fc854d 100644 --- a/Setup.iss +++ b/Setup.iss @@ -1,9 +1,9 @@ ; =================================================================== -; Warlock-Studio 4.0 - Inno Setup Script with Online Download +; Warlock-Studio 4.0.1 - Inno Setup Script with Online Download ; =================================================================== #define AppName "Warlock-Studio" -#define AppVersion "4.0" +#define AppVersion "4.0.1" #define AppPublisher "Iván Eduardo Chavez Ayub" #define AppURL "https://github.com/Ivan-Ayub97/Warlock-Studio" #define AppExeName "Warlock-Studio.exe" diff --git a/Warlock-Studio.py b/Warlock-Studio.py index bcfee91..308dff3 100644 --- a/Warlock-Studio.py +++ b/Warlock-Studio.py @@ -107,8 +107,24 @@ def find_by_relative_path(relative_path: str) -> str: return os_path_join(base_path, relative_path) +def image_read(path: str) -> numpy_ndarray: + """Read an image file and return it as a numpy array.""" + try: + if not os_path_exists(path): + raise FileNotFoundError(f"Image file not found: {path}") + + image = opencv_imdecode(numpy_frombuffer(open(path, 'rb').read(), dtype=uint8), IMREAD_UNCHANGED) + if image is None: + raise ValueError(f"Failed to read image: {path}") + return image + except Exception as e: + error_msg = f"Error reading image {path}: {str(e)}" + log_and_report_error(error_msg) + raise RuntimeError(error_msg) + + app_name = "Warlock-Studio" -version = "4.0-07.25" +version = "4.0.1-07.25" # AI Model Base Class @@ -128,75 +144,23 @@ class AI_model_base: f"Model file not found: {self.model_path}") # Set up providers for GPU acceleration - providers = ['DmlExecutionProvider', 'CPUExecutionProvider'] + # Use available GPU or CPU if no compatible GPU found + providers = ['CUDAExecutionProvider', 'DmlExecutionProvider', 'CPUExecutionProvider'] self.inferenceSession = InferenceSession( self.model_path, providers=providers ) print( f"[AI] Successfully loaded model: {os_path_basename(self.model_path)}") + except FileNotFoundError as fnf_error: + print(f"[AI ERROR] Model file not found: {fnf_error}") + # Handle specific file not found error except Exception as e: - print( - f"[AI ERROR] Failed to load model {self.model_path}: {str(e)}") + print(f"[AI ERROR] Failed to load model due to unexpected error: {str(e)}") + # Log the error and avoid crashing the application + self.inferenceSession = None # Reset inference session on error raise -# AI Super Resolution Implementation - - -class AI_super_resolution(AI_model_base): - def __init__(self, model_path: str, device: str = "CPU"): - super().__init__(model_path, device) - self.model_name = "SuperResolution-10" - self.upscale_factor = 10 # Based on the model name - - def preprocess_super_resolution_image(self, image: numpy_ndarray) -> numpy_ndarray: - """ - Preprocess image for super resolution model input. - """ - # Convert image to float32 and normalize - image = (image.astype(float32) / 255.0) - - # Convert image to CHW format (channels, height, width) - image = numpy_transpose(image, (2, 0, 1)) - - # Add batch dimension - image = numpy_expand_dims(image, axis=0) - return image - - def postprocess_super_resolution_image(self, output: numpy_ndarray) -> numpy_ndarray: - """ - Postprocess model output to an image. - """ - # Remove batch dimension and convert back to HWC format - output = numpy_squeeze(output, axis=0) - output = numpy_transpose(output, (1, 2, 0)) - - # Clip values and convert to uint8 - output = numpy_clip(output * 255.0, 0, 255).astype(uint8) - return output - - def enhance_image(self, image: numpy_ndarray) -> numpy_ndarray: - """ - Enhance image using the super resolution model. - """ - input_image = self.preprocess_super_resolution_image(image) - input_name = self.inferenceSession.get_inputs()[0].name - output_name = self.inferenceSession.get_outputs()[0].name - result = self.inferenceSession.run( - [output_name], {input_name: input_image})[0] - enhanced_image = self.postprocess_super_resolution_image(result) - return enhanced_image - - def AI_orchestration(self, image: numpy_ndarray) -> numpy_ndarray: - """ - Main orchestration function for super resolution processing. - """ - try: - return self.enhance_image(image) - except Exception as e: - print(f"[SUPER RESOLUTION ERROR] {str(e)}") - # Return original image if enhancement fails - return image # Esquema de colores mejorado - Rojo, Gris, Amarillo, Negro, Blanco @@ -223,7 +187,6 @@ VRAM_model_usage = { 'IRCNN_Mx1': 4, 'IRCNN_Lx1': 4, 'GFPGAN': 1.8, - 'SuperResolution-10': 0.8, } MENU_LIST_SEPARATOR = ["----"] @@ -232,11 +195,10 @@ BSRGAN_models_list = ["BSRGANx4", "BSRGANx2", "RealESRGANx4", "RealESRNetx4"] IRCNN_models_list = ["IRCNN_Mx1", "IRCNN_Lx1"] Face_restoration_models_list = ["GFPGAN"] RIFE_models_list = ["RIFE", "RIFE_Lite"] -SuperResolution_models_list = ["SuperResolution-10"] AI_models_list = (SRVGGNetCompact_models_list + MENU_LIST_SEPARATOR + BSRGAN_models_list + MENU_LIST_SEPARATOR + IRCNN_models_list + MENU_LIST_SEPARATOR + Face_restoration_models_list + - MENU_LIST_SEPARATOR + SuperResolution_models_list + MENU_LIST_SEPARATOR + RIFE_models_list) + MENU_LIST_SEPARATOR + RIFE_models_list) frame_interpolation_models_list = RIFE_models_list frame_generation_options_list = [ "x2", "x4", "x8", "Slowmotion x2", "Slowmotion x4", "Slowmotion x8" @@ -277,32 +239,49 @@ else: if os_path_exists(USER_PREFERENCE_PATH): print(f"[{app_name}] Preference file exist") - with open(USER_PREFERENCE_PATH, "r") as json_file: - json_data = json_load(json_file) - default_AI_model = json_data.get( - "default_AI_model", AI_models_list[0]) - default_AI_multithreading = json_data.get( - "default_AI_multithreading", AI_multithreading_list[0]) - default_gpu = json_data.get( - "default_gpu", gpus_list[0]) - default_keep_frames = json_data.get( - "default_keep_frames", keep_frames_list[1]) - default_image_extension = json_data.get( - "default_image_extension", image_extension_list[0]) - default_video_extension = json_data.get( - "default_video_extension", video_extension_list[0]) - default_video_codec = json_data.get( - "default_video_codec", video_codec_list[0]) - default_blending = json_data.get( - "default_blending", blending_list[1]) - default_output_path = json_data.get( - "default_output_path", OUTPUT_PATH_CODED) - default_input_resize_factor = json_data.get( - "default_input_resize_factor", str(50)) - default_output_resize_factor = json_data.get( - "default_output_resize_factor", str(100)) - default_VRAM_limiter = json_data.get( - "default_VRAM_limiter", str(4)) + try: + with open(USER_PREFERENCE_PATH, "r") as json_file: + json_data = json_load(json_file) + default_AI_model = json_data.get( + "default_AI_model", AI_models_list[0]) + default_AI_multithreading = json_data.get( + "default_AI_multithreading", AI_multithreading_list[0]) + default_gpu = json_data.get( + "default_gpu", gpus_list[0]) + default_keep_frames = json_data.get( + "default_keep_frames", keep_frames_list[1]) + default_image_extension = json_data.get( + "default_image_extension", image_extension_list[0]) + default_video_extension = json_data.get( + "default_video_extension", video_extension_list[0]) + default_video_codec = json_data.get( + "default_video_codec", video_codec_list[0]) + default_blending = json_data.get( + "default_blending", blending_list[1]) + default_output_path = json_data.get( + "default_output_path", OUTPUT_PATH_CODED) + default_input_resize_factor = json_data.get( + "default_input_resize_factor", str(50)) + default_output_resize_factor = json_data.get( + "default_output_resize_factor", str(100)) + default_VRAM_limiter = json_data.get( + "default_VRAM_limiter", str(4)) + except (json.JSONDecodeError, FileNotFoundError, PermissionError) as e: + print(f"[{app_name} ERROR] Failed to load preferences file: {str(e)}") + print(f"[{app_name}] Using default coded values instead") + # Fall back to default values + default_AI_model = AI_models_list[0] + default_AI_multithreading = AI_multithreading_list[0] + default_gpu = gpus_list[0] + default_keep_frames = keep_frames_list[1] + default_image_extension = image_extension_list[0] + default_video_extension = video_extension_list[0] + default_video_codec = video_codec_list[0] + default_blending = blending_list[1] + default_output_path = OUTPUT_PATH_CODED + default_input_resize_factor = str(50) + default_output_resize_factor = str(100) + default_VRAM_limiter = str(4) else: print(f"[{app_name}] Preference file does not exist, using default coded value") @@ -386,6 +365,9 @@ class AI_upscale: return 4 def _load_inferenceSession(self) -> None: + if self.inferenceSession is not None: + print(f"[AI] Model {self.AI_model_name} is already loaded.") + return try: # Check if model file exists if not os_path_exists(self.AI_model_path): @@ -400,6 +382,7 @@ class AI_upscale: case 'GPU 2': provider_options = [{"device_id": "1"}] case 'GPU 3': provider_options = [{"device_id": "2"}] case 'GPU 4': provider_options = [{"device_id": "3"}] + case _: provider_options = [{"device_id": "0"}] # Default case inference_session = InferenceSession( path_or_bytes=self.AI_model_path, @@ -411,10 +394,13 @@ class AI_upscale: print( f"[AI] Successfully loaded model: {os_path_basename(self.AI_model_path)}") + except FileNotFoundError as fnf_error: + print(f"[AI ERROR] AI model file not found: {fnf_error}") + # Graceful handling of file not found except Exception as e: - error_msg = f"Failed to load AI model {os_path_basename(self.AI_model_path)}: {str(e)}" - print(f"[AI ERROR] {error_msg}") - raise RuntimeError(error_msg) + print(f"[AI ERROR] Unexpected error loading AI model: {str(e)}") + # Reset inference session to None upon error + self.inferenceSession = None # INTERNAL CLASS FUNCTIONS @@ -450,8 +436,9 @@ class AI_upscale: old_height, old_width = self.get_image_resolution(image) - new_width = int(old_width * self.input_resize_factor) - new_height = int(old_height * self.input_resize_factor) + scale = self.input_resize_factor / 100.0 + new_width = int(old_width * scale) + new_height = int(old_height * scale) new_width = new_width if new_width % 2 == 0 else new_width + 1 new_height = new_height if new_height % 2 == 0 else new_height + 1 @@ -467,15 +454,16 @@ class AI_upscale: old_height, old_width = self.get_image_resolution(image) - new_width = int(old_width * self.output_resize_factor) - new_height = int(old_height * self.output_resize_factor) + scale = self.output_resize_factor / 100.0 + new_width = int(old_width * scale) + new_height = int(old_height * scale) new_width = new_width if new_width % 2 == 0 else new_width + 1 new_height = new_height if new_height % 2 == 0 else new_height + 1 - if self.output_resize_factor > 1: + if scale > 1.0: return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC) - elif self.output_resize_factor < 1: + elif scale < 1.0: return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA) else: return image @@ -621,7 +609,7 @@ class AI_upscale: # Default fallback to 255 case _: return (onnx_output * 255).astype(uint8) - def AI_upscale(self, image: numpy_ndarray) -> numpy_ndarray: + def run_upscaling(self, image: numpy_ndarray) -> numpy_ndarray: # Optimización: Usar memoria contigua antes de procesar image = numpy_ascontiguousarray(image, dtype=float32) image_mode = self.get_image_mode(image) @@ -682,7 +670,7 @@ class AI_upscale: t_height, t_width = self.calculate_target_resolution(image) tiles_x, tiles_y = self.calculate_tiles_number(image) tiles_list = self.split_image_into_tiles(image, tiles_x, tiles_y) - tiles_list = [self.AI_upscale(tile) for tile in tiles_list] + tiles_list = [self.run_upscaling(tile) for tile in tiles_list] return self.combine_tiles_into_image(image, tiles_list, t_height, t_width, tiles_x) @@ -698,7 +686,7 @@ class AI_upscale: if self.image_need_tilling(resized_image): upscaled_image = self.AI_upscale_with_tilling(resized_image) else: - upscaled_image = self.AI_upscale(resized_image) + upscaled_image = self.run_upscaling(resized_image) return self.resize_with_output_factor(upscaled_image) @@ -788,15 +776,16 @@ class AI_interpolation: old_height, old_width = self.get_image_resolution(image) - new_width = int(old_width * self.input_resize_factor) - new_height = int(old_height * self.input_resize_factor) + scale = self.input_resize_factor / 100.0 + new_width = int(old_width * scale) + new_height = int(old_height * scale) new_width = new_width if new_width % 2 == 0 else new_width + 1 new_height = new_height if new_height % 2 == 0 else new_height + 1 - if self.input_resize_factor > 1: + if scale > 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC) - elif self.input_resize_factor < 1: + elif scale < 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA) else: return image @@ -805,15 +794,16 @@ class AI_interpolation: old_height, old_width = self.get_image_resolution(image) - new_width = int(old_width * self.output_resize_factor) - new_height = int(old_height * self.output_resize_factor) + scale = self.output_resize_factor / 100.0 + new_width = int(old_width * scale) + new_height = int(old_height * scale) new_width = new_width if new_width % 2 == 0 else new_width + 1 new_height = new_height if new_height % 2 == 0 else new_height + 1 - if self.output_resize_factor > 1: + if scale > 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC) - elif self.output_resize_factor < 1: + elif scale < 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA) else: return image @@ -1006,15 +996,16 @@ class AI_face_restoration: def resize_with_input_factor(self, image: numpy_ndarray) -> numpy_ndarray: old_height, old_width = self.get_image_resolution(image) - new_width = int(old_width * self.input_resize_factor) - new_height = int(old_height * self.input_resize_factor) + scale = self.input_resize_factor / 100.0 + new_width = int(old_width * scale) + new_height = int(old_height * scale) new_width = new_width if new_width % 2 == 0 else new_width + 1 new_height = new_height if new_height % 2 == 0 else new_height + 1 - if self.input_resize_factor > 1: + if scale > 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_CUBIC) - elif self.input_resize_factor < 1: + elif scale < 1: return opencv_resize(image, (new_width, new_height), interpolation=INTER_AREA) else: return image @@ -1868,8 +1859,8 @@ def cleanup_on_exit(): for temp_file in temp_files: try: os_remove(temp_file) - except Exception: - pass + except Exception as e: + print(f"[ERROR] Could not remove temporary file {temp_file}: {str(e)}") # Stop any running processes stop_upscale_process() @@ -3602,13 +3593,6 @@ def upscale_orchestrator( input_resize_factor, output_resize_factor, tiles_resolution) for _ in range(selected_AI_multithreading) ] - # Check if the selected model is a super resolution model - elif selected_AI_model in SuperResolution_models_list: - AI_upscale_instance_list = [ - AI_super_resolution( - f"AI-onnx{os_separator}super-resolution-10.onnx", selected_gpu) - for _ in range(selected_AI_multithreading) - ] else: AI_upscale_instance_list = [ AI_upscale(selected_AI_model, selected_gpu, @@ -3691,11 +3675,7 @@ def upscale_image( write_process_status( process_status_q, f"{file_number}. Enchanting your image. Be patient...") - # Check if using SuperResolution-10 model - if selected_AI_model in SuperResolution_models_list: - upscaled_image = AI_instance.enhance_image(starting_image) - else: - upscaled_image = AI_instance.AI_orchestration(starting_image) + upscaled_image = AI_instance.AI_orchestration(starting_image) if selected_blending_factor > 0: blend_images_and_save( @@ -4435,12 +4415,6 @@ def place_AI_menu(): " • Lite is 10% faster than full model\n" + " • Recommended for GPUs with VRAM < 4GB \n", - "\n SuperResolution-10 \n" - "\n • Advanced super-resolution model with 10x upscaling\n" - " • Year: 2023\n" - " • Function: High-resolution image enhancement\n" - " • Excellent for very low resolution images\n" - " • Specialized for significant resolution increases\n", ] MessageBox( diff --git a/logo.ico b/logo.ico index b12d0fd..d8acdb6 100644 Binary files a/logo.ico and b/logo.ico differ