| """ |
| Quality and Color Enhancer - Improves image quality while preserving natural colors |
| """ |
|
|
| import cv2 |
| import numpy as np |
| from PIL import Image, ImageEnhance |
|
|
| class QualityColorEnhancer: |
| def __init__(self): |
| self.enhance_quality = True |
| self.enhance_colors = True |
| |
| def enhance_frame(self, frame_path: str, output_path: str = None) -> str: |
| """Enhance frame quality and colors""" |
| |
| if output_path is None: |
| output_path = frame_path |
| |
| try: |
| |
| img = cv2.imread(frame_path) |
| if img is None: |
| return frame_path |
| |
| print(f"🎨 Enhancing {frame_path}...") |
| |
| |
| img = cv2.fastNlMeansDenoisingColored(img, None, 3, 3, 7, 21) |
| |
| |
| kernel = np.array([[-1,-1,-1], |
| [-1, 9,-1], |
| [-1,-1,-1]]) |
| sharpened = cv2.filter2D(img, -1, kernel) |
| |
| |
| img = cv2.addWeighted(img, 0.5, sharpened, 0.5, 0) |
| |
| |
| img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) |
| |
| |
| color_enhancer = ImageEnhance.Color(img_pil) |
| img_pil = color_enhancer.enhance(1.3) |
| |
| |
| |
| |
| |
| |
| contrast_enhancer = ImageEnhance.Contrast(img_pil) |
| img_pil = contrast_enhancer.enhance(1.1) |
| |
| |
| img = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR) |
| |
| |
| img = self._auto_white_balance(img) |
| |
| |
| img = self._enhance_dark_areas(img) |
| |
| |
| cv2.imwrite(output_path, img, [cv2.IMWRITE_JPEG_QUALITY, 100]) |
| |
| return output_path |
| |
| except Exception as e: |
| print(f"⚠️ Enhancement failed: {e}") |
| return frame_path |
| |
| def _auto_white_balance(self, img): |
| """Simple auto white balance with safety checks""" |
| try: |
| result = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) |
| avg_a = np.average(result[:, :, 1]) |
| avg_b = np.average(result[:, :, 2]) |
| |
| |
| result[:, :, 1] = result[:, :, 1] - ((avg_a - 128) * (result[:, :, 0] / 255.0) * 0.5) |
| result[:, :, 2] = result[:, :, 2] - ((avg_b - 128) * (result[:, :, 0] / 255.0) * 0.5) |
| result = cv2.cvtColor(result, cv2.COLOR_LAB2BGR) |
| return result |
| except: |
| |
| return img |
| |
| def _enhance_dark_areas(self, img): |
| """Enhance details in dark areas without affecting bright areas""" |
| |
| gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
| mask = cv2.inRange(gray, 0, 100) |
| |
| |
| lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) |
| l_channel = lab[:, :, 0] |
| |
| |
| clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8)) |
| enhanced_l = clahe.apply(l_channel) |
| |
| |
| l_channel = np.where(mask > 0, enhanced_l, l_channel) |
| lab[:, :, 0] = l_channel |
| |
| |
| result = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR) |
| return result |
| |
| def batch_enhance(self, frames_dir: str): |
| """Enhance all frames in directory""" |
| import os |
| |
| frames = sorted([f for f in os.listdir(frames_dir) if f.endswith('.png')]) |
| print(f"🎨 Enhancing {len(frames)} frames for better quality and colors...") |
| |
| for i, frame in enumerate(frames): |
| |
| is_last = (i == len(frames) - 1) |
| if is_last: |
| print(f" ⚠️ Skipping last frame {frame} to preserve original colors") |
| continue |
| |
| frame_path = os.path.join(frames_dir, frame) |
| self.enhance_frame(frame_path) |
| print(f" ✓ Enhanced {i+1}/{len(frames)}") |
| |
| print("✅ Quality and color enhancement complete!") |