| import os |
| import time |
| import argparse |
| import sys |
| import torch |
| from pathlib import Path |
| from PIL import Image |
|
|
| |
| |
| import crop |
| import process_images |
| import color_steal |
| import white_bg |
| import restoration |
|
|
| def run_pipeline(raw_dir, crop_dir, trans_dir, colored_dir, white_dir, curves_file, restore=False, fidelity=0.5): |
| start_total = time.time() |
|
|
| |
| current_raw_dir = raw_dir |
| if restore: |
| print("\n" + "="*50) |
| print("STEP 0: Face Restoration (CodeFormer)") |
| print("="*50) |
| restored_dir = os.path.join(os.path.dirname(crop_dir), "restored") |
| restoration.batch_restore(raw_dir, restored_dir, fidelity=fidelity) |
| current_raw_dir = restored_dir |
|
|
| |
| print("\n" + "="*50) |
| print("STEP 1: Cropping and Face Detection") |
| print("="*50) |
| crop.batch_process(current_raw_dir, crop_dir) |
|
|
| |
| print("\n" + "="*50) |
| print("STEP 2: Background Removal (AI)") |
| print("="*50) |
| |
| |
| model, device = process_images.setup_model() |
| transform = process_images.get_transform() |
| |
| input_path = Path(crop_dir) |
| output_path = Path(trans_dir) |
| output_path.mkdir(parents=True, exist_ok=True) |
| |
| files = [f for f in input_path.iterdir() if f.suffix.lower() in process_images.ALLOWED_EXTENSIONS] |
| if not files: |
| print(f"No images found in {crop_dir} for background removal.") |
| else: |
| for idx, file_path in enumerate(files, 1): |
| try: |
| print(f"[{idx}/{len(files)}] Removing background: {file_path.name}...", end='', flush=True) |
| img = Image.open(file_path) |
| from PIL import ImageOps |
| img = ImageOps.exif_transpose(img) |
| img = img.convert('RGB') |
| result = process_images.remove_background(model, img, transform) |
| out_name = file_path.stem + "_rmbg.png" |
| result.save(output_path / out_name, "PNG") |
| print(" Done.") |
| except Exception as e: |
| print(f" Failed! {e}") |
| |
| |
| print("\n" + "="*50) |
| print("STEP 3: Color Grading") |
| print("="*50) |
| luts = color_steal.load_trained_curves(curves_file) |
| if not luts: |
| print(f"Warning: No trained curves found at {curves_file}. Skipping color grading.") |
| |
| |
| current_input_for_white = trans_dir |
| else: |
| color_steal.apply_to_folder(luts, trans_dir, colored_dir) |
| current_input_for_white = colored_dir |
|
|
| |
| print("\n" + "="*50) |
| print("STEP 4: Adding White Background & Finalizing") |
| print("="*50) |
| white_bg.add_white_background(current_input_for_white, white_dir) |
|
|
| end_total = time.time() |
| print("\n" + "="*50) |
| print(f"PIPELINE COMPLETE in {end_total - start_total:.2f} seconds") |
| print(f"Final results are in: {os.path.abspath(white_dir)}") |
| print("="*50) |
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser(description="Full Image Processing Pipeline") |
| parser.add_argument("--raw", default="raw", help="Folder with raw images") |
| parser.add_argument("--crop", default="crop", help="Folder for cropped images") |
| parser.add_argument("--trans", default="trans", help="Folder for transparent images") |
| parser.add_argument("--colored", default="colored", help="Folder for color-graded images") |
| parser.add_argument("--white", default="white", help="Folder for final results") |
| parser.add_argument("--curves", default="trained_curves.npz", help="Pre-trained curves file") |
| parser.add_argument("--restore", action="store_true", help="Enable face restoration using CodeFormer") |
| parser.add_argument("--fidelity", type=float, default=0.5, help="CodeFormer fidelity (0-1, lower is more restoration)") |
| |
| args = parser.parse_args() |
| |
| |
| for d in [args.raw, args.crop, args.trans, args.colored, args.white]: |
| if not os.path.exists(d): |
| os.makedirs(d) |
| print(f"Created directory: {d}") |
|
|
| run_pipeline(args.raw, args.crop, args.trans, args.colored, args.white, args.curves, restore=args.restore, fidelity=args.fidelity) |
|
|