Case study · 06
Status: FinishedAI Upscaler
A desktop app for upscaling photos 4× with Real-ESRGAN, with optional background removal. The window is built with CustomTkinter; the heavy work runs on a background thread, on the GPU when CUDA is available.
Image processing · process diagram
- load image
- resize (OpenCV)
- remove background (optional)
- Real-ESRGAN x4 · CUDA/CPU
- unsharp mask
- save result
01 · Problem
What needed solving
Running Real-ESRGAN usually means command-line scripts and manual setup. The goal was a one-window tool: pick a photo, decide whether to drop the background, get a sharp 4× result.
02 · Solution
How it works
A CustomTkinter GUI with a worker thread that reports progress through a queue: an optional pre-resize with OpenCV, background removal with rembg (U²-Net), Real-ESRGAN x4, then an unsharp mask. A PyInstaller spec bundles the models into a standalone Windows .exe.
03 · Key features
What it does
- 4× upscaling with the RealESRGAN_x4plus model (RRDBNet, 23 blocks)
- Optional background removal with rembg before upscaling
- CUDA with half precision when a GPU is available, otherwise the CPU
- Responsive window: processing in a worker thread, status updates through a queue
- Live GPU memory readout; standalone .exe build with PyInstaller
04 · Tech stack
Built with
- Python
- PyTorch
- Real-ESRGAN
- rembg
- OpenCV
- CustomTkinter
- Status
- Finished
- Code
- github.com/KacperBlok1/Upscale-bgremove-ai
- Demo
- Not hosted yet · run locally
05 · Challenges
What was tricky
Responsive window
Upscaling a large photo can take a while. Doing it on the Tk main loop would freeze the window, so a daemon thread does the work and posts status messages to a queue that the UI polls every 150 ms.
One code path for GPU and CPU
The model is created for whichever device is available and uses half precision only on CUDA, where it saves memory; on the CPU it stays in full precision.
Models inside a single .exe
The model weights and the U²-Net folder are bundled by PyInstaller, and a resource_path helper finds them both when running from source and from the unpacked executable.
Try it
Run it locally
No hosted demo yet. The source and README are on GitHub, and these commands start it locally from the repo root.
$ pip install -r requirements.txt
# put RealESRGAN_x4plus.pth next to upscale.py
$ python upscale.py