Testcomic / backend /quality_color_enhancer.py
3v324v23's picture
Update Comic123 with local comic folder files
83e35a7
"""
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:
# Read image
img = cv2.imread(frame_path)
if img is None:
return frame_path
print(f"🎨 Enhancing {frame_path}...")
# 1. Denoise
img = cv2.fastNlMeansDenoisingColored(img, None, 3, 3, 7, 21)
# 2. Improve sharpness
kernel = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
sharpened = cv2.filter2D(img, -1, kernel)
# Blend with original (to avoid over-sharpening)
img = cv2.addWeighted(img, 0.5, sharpened, 0.5, 0)
# 3. Enhance colors using PIL
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# Increase color vibrancy
color_enhancer = ImageEnhance.Color(img_pil)
img_pil = color_enhancer.enhance(1.3) # 30% more colorful
# Skip brightness adjustment - images already bright enough
# brightness_enhancer = ImageEnhance.Brightness(img_pil)
# img_pil = brightness_enhancer.enhance(1.0) # No change
# Adjust contrast - reduced
contrast_enhancer = ImageEnhance.Contrast(img_pil)
img_pil = contrast_enhancer.enhance(1.1) # Only 10% more contrast
# Convert back to OpenCV
img = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
# 4. Auto white balance
img = self._auto_white_balance(img)
# 5. Enhance details in dark areas
img = self._enhance_dark_areas(img)
# Save with high quality
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])
# More conservative white balance
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:
# If white balance fails, return original
return img
def _enhance_dark_areas(self, img):
"""Enhance details in dark areas without affecting bright areas"""
# Create a mask for dark areas
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
mask = cv2.inRange(gray, 0, 100) # Dark areas
# Apply CLAHE only to dark areas
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l_channel = lab[:, :, 0]
# Create CLAHE object
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
enhanced_l = clahe.apply(l_channel)
# Apply enhancement only to masked areas
l_channel = np.where(mask > 0, enhanced_l, l_channel)
lab[:, :, 0] = l_channel
# Convert back
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):
# Skip last frame if it's problematic
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!")