F) Maybe Is Full Script Complet
F) Maybe Is Full Script Complet
import os
import sys
import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFilter, ImageEnhance
import torch
import torchvision.transforms as transforms
from pathlib import Path
import requests
import zipfile
import gdown
from typing import List, Tuple, Optional, Dict
import warnings
import json
import time
from tqdm import tqdm
import gc
warnings.filterwarnings('ignore')
def install_all_dependencies():
"""Complete dependency installation for Google Colab"""
print("Installing all required packages... This may take a few minutes.")
# Core packages
packages = [
"torch torchvision torchaudio --index-url
https://download.pytorch.org/whl/cu118",
"opencv-python-headless",
"pillow>=9.0.0",
"numpy>=1.21.0",
"matplotlib>=3.5.0",
"tqdm",
"scipy",
"scikit-image",
"scikit-learn"
]
# OCR packages
ocr_packages = [
"easyocr",
"paddlepaddle-gpu" if torch.cuda.is_available() else "paddlepaddle",
"paddleocr>=2.6.0"
]
# AI/ML packages
ai_packages = [
"transformers>=4.20.0",
"diffusers>=0.21.0",
"accelerate>=0.20.0",
"controlnet-aux",
"xformers" if torch.cuda.is_available() else "",
"segment-anything",
"ultralytics>=8.0.0"
]
# Additional utilities
util_packages = [
"imageio",
"imageio-ffmpeg",
"gradio",
"ipywidgets"
]
class AdvancedTextDetector:
"""Multi-method text detection with manga/comic specialization"""
def __init__(self):
self.setup_all_detectors()
self.detection_cache = {}
def setup_all_detectors(self):
"""Initialize all available text detection methods"""
print("🔧 Setting up text detection models...")
# OCR Readers
self.detectors = {}
# EasyOCR setup
try:
import easyocr
self.detectors['easyocr'] = easyocr.Reader(
['en', 'ja', 'ko', 'zh', 'th', 'vi'],
gpu=torch.cuda.is_available()
)
print("✅ EasyOCR initialized")
except Exception as e:
print(f"⚠️ EasyOCR failed: {e}")
# PaddleOCR setup
try:
from paddleocr import PaddleOCR
self.detectors['paddle_en'] = PaddleOCR(
use_angle_cls=True,
lang='en',
show_log=False,
use_gpu=torch.cuda.is_available()
)
self.detectors['paddle_ch'] = PaddleOCR(
use_angle_cls=True,
lang='ch',
show_log=False,
use_gpu=torch.cuda.is_available()
)
print("✅ PaddleOCR initialized")
except Exception as e:
print(f"⚠️ PaddleOCR failed: {e}")
# OpenCV-based detectors
self.setup_opencv_detectors()
def setup_craft_detector(self):
"""Setup CRAFT text detector for better comic text detection"""
try:
# Download CRAFT model if not exists
craft_path = "/content/craft_mlt_25k.pth"
if not os.path.exists(craft_path):
print("Downloading CRAFT model...")
url =
"https://github.com/clovaai/CRAFT-pytorch/releases/download/v1.0/craft_mlt_25k.pth"
os.system(f"wget -q {url} -O {craft_path}")
except Exception as e:
print(f"CRAFT setup failed: {e}")
def setup_opencv_detectors(self):
"""Setup OpenCV-based text detection methods"""
# EAST Text Detector
try:
east_path = "/content/frozen_east_text_detection.pb"
if not os.path.exists(east_path):
print("Downloading EAST model...")
url =
"https://github.com/opencv/opencv_extra/raw/master/testdata/dnn/frozen_east_text_de
tection.pb"
os.system(f"wget -q {url} -O {east_path}")
self.detectors['east'] = cv2.dnn.readNet(east_path)
print("✅ EAST detector initialized")
except Exception as e:
print(f"⚠️ EAST detector failed: {e}")
Returns:
List of detection dictionaries with bbox, confidence, method, text
"""
results = []
# Method 1: EasyOCR
if 'easyocr' in self.detectors:
results.extend(self._detect_with_easyocr(image, min_confidence))
# Method 2: PaddleOCR
if 'paddle_en' in self.detectors:
results.extend(self._detect_with_paddle(image, min_confidence))
# Method 3: EAST
if 'east' in self.detectors:
results.extend(self._detect_with_east(image, min_confidence))
return merged_results
results.append({
'bbox': (x_min, y_min, x_max, y_max),
'confidence': confidence,
'method': 'easyocr',
'text': text,
'polygon': bbox
})
except Exception as e:
print(f"EasyOCR detection error: {e}")
return results
try:
ocr_results = self.detectors[lang].ocr(image, cls=True)
if ocr_results and ocr_results[0]:
for item in ocr_results[0]:
bbox, (text, confidence) = item
if confidence >= min_confidence:
bbox_array = np.array(bbox, dtype=np.int32)
x_min, y_min = np.min(bbox_array, axis=0)
x_max, y_max = np.max(bbox_array, axis=0)
results.append({
'bbox': (x_min, y_min, x_max, y_max),
'confidence': confidence,
'method': lang,
'text': text,
'polygon': bbox
})
except Exception as e:
print(f"{lang} detection error: {e}")
return results
net = self.detectors['east']
height, width = image.shape[:2]
net.setInput(blob)
scores, geometry = net.forward(['feature_fusion/Conv_7/Sigmoid',
'feature_fusion/concat_3'])
# Decode predictions
boxes, confidences = self._decode_east_predictions(scores, geometry,
min_confidence)
# Apply NMS
indices = cv2.dnn.NMSBoxes(boxes, confidences, min_confidence, 0.4)
if len(indices) > 0:
for i in indices.flatten():
x, y, w, h = boxes[i]
# Scale back to original image
x = int(x * ratio_w)
y = int(y * ratio_h)
w = int(w * ratio_w)
h = int(h * ratio_h)
results.append({
'bbox': (x, y, x + w, y + h),
'confidence': confidences[i],
'method': 'east',
'text': '',
'polygon': [(x, y), (x + w, y), (x + w, y + h), (x, y + h)]
})
except Exception as e:
print(f"EAST detection error: {e}")
return results
for y in range(height):
scores_data = scores[0, 0, y]
x_data0 = geometry[0, 0, y]
x_data1 = geometry[0, 1, y]
x_data2 = geometry[0, 2, y]
x_data3 = geometry[0, 3, y]
angles_data = geometry[0, 4, y]
for x in range(width):
if scores_data[x] < min_confidence:
continue
h = x_data0[x] + x_data2[x]
w = x_data1[x] + x_data3[x]
try:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3
else image
regions, _ = mser.detectRegions(gray)
for region in regions:
if len(region) > 10:
x, y, w, h = cv2.boundingRect(region)
aspect_ratio = w / h if h > 0 else 0
area = w * h
if (0.1 < aspect_ratio < 20 and 100 < area < 10000 and
w > 15 and h > 8):
results.append({
'bbox': (x, y, x + w, y + h),
'confidence': 0.6,
'method': 'mser',
'text': '',
'polygon': [(x, y), (x + w, y), (x + w, y + h), (x, y +
h)]
})
except Exception as e:
print(f"OpenCV detection error: {e}")
return results
try:
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) if len(image.shape) == 3
else image
except Exception as e:
print(f"Manga-specific detection error: {e}")
return results
try:
# Use HoughCircles to detect circular/oval speech bubbles
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 50,
param1=50, param2=30, minRadius=20,
maxRadius=200)
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
for (x, y, r) in circles:
# Create bounding box around circle
bbox = (max(0, x - r), max(0, y - r),
min(gray.shape[1], x + r), min(gray.shape[0], y + r))
results.append({
'bbox': bbox,
'confidence': 0.4,
'method': 'speech_bubble',
'text': '',
'polygon': [(bbox[0], bbox[1]), (bbox[2], bbox[1]),
(bbox[2], bbox[3]), (bbox[0], bbox[3])]
})
except Exception as e:
print(f"Speech bubble detection error: {e}")
return results
try:
# Sound effects often have bold, stylized text
# Use different morphological operations
kernel_large = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
kernel_small = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
# Combine both
combined = cv2.add(tophat, blackhat)
# Threshold
_, thresh = cv2.threshold(combined, 10, 255, cv2.THRESH_BINARY)
# Find contours
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
except Exception as e:
print(f"Sound effect detection error: {e}")
return results
try:
# Handwritten text often has more irregular patterns
# Use gradient-based detection
grad_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
grad_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
# Apply threshold
_, thresh = cv2.threshold(magnitude, 30, 255, cv2.THRESH_BINARY)
# Morphological operations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
except Exception as e:
print(f"Handwritten text detection error: {e}")
return results
# Sort by confidence
detections.sort(key=lambda x: x['confidence'], reverse=True)
merged = []
used = set()
current = detection.copy()
current_bbox = detection['bbox']
# Combine methods
methods = [current['method']] + [detections[j]['method'] for j in
overlaps]
current['method'] = '+'.join(set(methods))
# Mark as used
used.update(overlaps)
merged.append(current)
used.add(i)
return merged
# Calculate intersection
x1_int = max(x1_1, x1_2)
y1_int = max(y1_1, y1_2)
x2_int = min(x2_1, x2_2)
y2_int = min(y2_1, y2_2)
# Calculate union
area1 = (x2_1 - x1_1) * (y2_1 - y1_1)
area2 = (x2_2 - x1_2) * (y2_2 - y1_2)
union = area1 + area2 - intersection
class AdvancedInpainter:
"""Multi-method inpainting with quality optimization"""
def __init__(self):
self.setup_inpainting_models()
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
def setup_inpainting_models(self):
"""Setup all available inpainting methods"""
print("🔧 Setting up inpainting models...")
self.inpainters = {}
model_id = "runwayml/stable-diffusion-inpainting"
self.inpainters['sd'] = StableDiffusionInpaintPipeline.from_pretrained(
model_id,
torch_dtype=torch.float16 if torch.cuda.is_available() else
torch.float32,
variant="fp16" if torch.cuda.is_available() else None,
use_safetensors=True
).to(self.device)
# Enable optimizations
if torch.cuda.is_available():
self.inpainters['sd'].enable_attention_slicing()
self.inpainters['sd'].enable_model_cpu_offload()
try:
self.inpainters['sd'].enable_xformers_memory_efficient_attention()
except:
pass
except Exception as e:
print(f"⚠️ Stable Diffusion loading failed: {e}")
def setup_mat_inpainter(self):
"""Setup MAT (Mask-Aware Transformer) inpainter"""
# Placeholder for MAT implementation
# Would require downloading MAT model weights
pass
def setup_lama_inpainter(self):
"""Setup LaMa (Large Mask Inpainting) inpainter"""
# Placeholder for LaMa implementation
# Would require downloading LaMa model weights
pass
Args:
image: Input image (H, W, 3)
mask: Binary mask (H, W) where 255 = inpaint area
method: 'auto', 'sd', 'opencv', 'telea', 'ns', 'edge_connect'
Returns:
Inpainted image
"""
if method == 'auto':
# Choose best method based on mask characteristics
method = self._choose_best_method(image, mask)
# Inpaint
result = self.inpainters['sd'](
prompt=prompt,
negative_prompt=negative_prompt,
image=pil_image,
mask_image=pil_mask,
num_inference_steps=25,
guidance_scale=7.5,
strength=0.8
).images[0]
except Exception as e:
print(f"SD inpainting failed: {e}")
return self._inpaint_with_opencv(image, mask, 'telea')
return result
except Exception as e:
print(f"OpenCV inpainting failed: {e}")
return image
# Detect edges
edges = cv2.Canny(gray, 50, 150)
# Blend results
alpha = 0.6
result = cv2.addWeighted(inpaint1, alpha, inpaint2, 1-alpha, 0)
return result
except Exception as e:
print(f"Edge connect inpainting failed: {e}")
return self._inpaint_with_opencv(image, mask, 'telea')
# Extract region
region = image[y:y+h, x:x+w]
region_mask = mask[y:y+h, x:x+w]
# Blend back
result[y:y+h, x:x+w] = filled_region
return result
except Exception as e:
print(f"Patch match inpainting failed: {e}")
return self._inpaint_with_opencv(image, mask, 'telea')
return result
if not np.any(valid_pixels):
return None
best_match = None
best_score = float('inf')
return best_match
class MangaTextRemover:
"""Main class for comprehensive manga/comic text removal"""
def __init__(self):
self.detector = AdvancedTextDetector()
self.inpainter = AdvancedInpainter()
self.processing_stats = {}
Args:
image_path: Path to input image
output_path: Path for output image (optional)
detection_confidence: Minimum confidence for text detection
inpaint_method: Inpainting method to use
expand_mask: Pixels to expand mask around detected text
show_process: Whether to show processing steps
Returns:
Dictionary with processing results and statistics
"""
print(f"🎯 Processing image: {image_path}")
start_time = time.time()
# Load image
image = cv2.imread(image_path)
if image is None:
raise ValueError(f"Could not load image: {image_path}")
original_image = image.copy()
# Step 3: Inpainting
print("🔄 Step 3: Removing text and inpainting...")
result = self.inpainter.inpaint_comprehensive(image, mask, inpaint_method)
# Step 4: Post-processing
print("✨ Step 4: Post-processing...")
result = self._post_process_result(original_image, result, mask)
# Calculate statistics
processing_time = time.time() - start_time
stats = {
'detections_count': len(detections),
'processing_time': processing_time,
'mask_area_ratio': np.sum(mask > 0) / (mask.shape[0] * mask.shape[1]),
'detection_methods': list(set([d['method'] for d in detections])),
'inpaint_method': inpaint_method,
'image_size': image.shape[:2]
}
if show_process:
self._show_processing_results(original_image, detections, mask, result,
stats)
return {
'result': result,
'original': original_image,
'mask': mask,
'detections': detections,
'stats': stats
}
# Add to mask
mask[y1:y2, x1:x2] = 255
return mask
# Smooth transition
final_result = (result * blurred_mask + original * (1 -
blurred_mask)).astype(np.uint8)
# Color correction
final_result = self._match_color_distribution(original, final_result, mask)
# Sharpening
final_result = self._apply_sharpening(final_result)
return final_result
# Calculate statistics
orig_mean = np.mean(orig_channel)
orig_std = np.std(orig_channel)
result_mean = np.mean(result_channel)
result_std = np.std(result_channel)
except Exception as e:
print(f"Color matching failed: {e}")
return result
except Exception as e:
print(f"Sharpening failed: {e}")
return image
# Mask
axes[0, 1].imshow(mask, cmap='gray')
axes[0, 1].set_title('Inpainting Mask')
axes[0, 1].axis('off')
# Result
axes[1, 0].imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
axes[1, 0].set_title('Text Removed Result')
axes[1, 0].axis('off')
# Comparison
comparison = np.hstack([
cv2.cvtColor(original, cv2.COLOR_BGR2RGB),
cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
])
axes[1, 1].imshow(comparison)
axes[1, 1].set_title('Before vs After')
axes[1, 1].axis('off')
plt.tight_layout()
plt.show()
# Print statistics
print(f"\n📊 Processing Statistics:")
print(f" • Text regions detected: {stats['detections_count']}")
print(f" • Processing time: {stats['processing_time']:.2f} seconds")
print(f" • Mask area ratio: {stats['mask_area_ratio']:.1%}")
print(f" • Detection methods: {', '.join(stats['detection_methods'])}")
print(f" • Inpainting method: {stats['inpaint_method']}")
print(f" • Image size: {stats['image_size'][1]}x{stats['image_size']
[0]}")
class BatchProcessor:
"""Batch processing for multiple images"""
def __init__(self):
self.remover = MangaTextRemover()
results = {}
failed = []
# Process image
result = self.remover.process_image(
str(image_file),
output_path,
show_process=False,
**kwargs
)
results[str(image_file)] = result['stats']
except Exception as e:
print(f"❌ Failed to process {image_file}: {e}")
failed.append(str(image_file))
return {
'processed': len(results),
'failed': len(failed),
'failed_files': failed,
'results': results
}
def setup_environment():
"""One-click setup for Google Colab"""
print("🚀 Setting up Manga Text Removal environment...")
install_all_dependencies()
print("✅ Environment setup complete!")
Args:
image_path: Path to input image
output_path: Path for output (optional)
confidence: Detection confidence threshold
Returns:
Path to output image
"""
if output_path is None:
name, ext = os.path.splitext(image_path)
output_path = f"{name}_no_text{ext}"
remover = MangaTextRemover()
result = remover.process_image(image_path, output_path, confidence)
return output_path
Args:
input_folder: Path to input folder
output_folder: Path to output folder (optional)
confidence: Detection confidence threshold
Returns:
Processing statistics
"""
if output_folder is None:
output_folder = f"{input_folder}_cleaned"
processor = BatchProcessor()
return processor.process_folder(input_folder, output_folder,
detection_confidence=confidence)
# ======================= USAGE EXAMPLES =======================
def demo_usage():
"""Demonstrate how to use the system"""
print("""
🎯 Manga/Comic Text Removal System - Usage Examples
3. Process folder:
stats = remove_text_from_folder('manga_folder/', 'clean_manga_folder/')
4. Advanced usage:
remover = MangaTextRemover()
result = remover.process_image('image.jpg', confidence=0.4)
5. Batch processing:
processor = BatchProcessor()
stats = processor.process_folder('input/', 'output/')
📝 Tips:
- Lower confidence (0.1-0.3) detects more text but may have false positives
- Higher confidence (0.4-0.8) is more selective but may miss some text
- Use 'sd' inpainting method for best quality (requires GPU)
- Use 'telea' or 'ns' for faster processing
""")
def upload_and_process():
"""Helper function for Google Colab file upload"""
try:
from google.colab import files
# Upload files
print("📤 Please select image files to upload:")
uploaded = files.upload()
results = []
results.append({
'input': filename,
'output': output_path,
'stats': result['stats']
})
# Download results
print("\n📥 Download processed images:")
for result in results:
files.download(result['output'])
return results
except ImportError:
print("This function is only available in Google Colab")
return None
def create_gradio_interface():
"""Create Gradio web interface for easy use"""
try:
import gradio as gr
try:
# Process
remover = MangaTextRemover()
result = remover.process_image(
temp_input,
temp_output,
detection_confidence=confidence,
inpaint_method=inpaint_method,
show_process=False
)
# Load result
result_image = Image.open(temp_output)
except Exception as e:
return None, f"Error: {str(e)}"
# Create interface
interface = gr.Interface(
fn=process_image_gradio,
inputs=[
gr.Image(type="pil", label="Upload Manga/Comic Image"),
gr.Slider(0.1, 0.9, value=0.3, label="Detection Confidence"),
gr.Dropdown(
["auto", "sd", "telea", "ns", "edge_connect"],
value="auto",
label="Inpainting Method"
)
],
outputs=[
gr.Image(type="pil", label="Text Removed"),
gr.Textbox(label="Processing Stats")
],
title="Manga/Comic Text Removal",
description="Upload a manga or comic image to automatically detect and
remove text while preserving the artwork."
)
return interface
except ImportError:
print("Gradio not available. Install with: pip install gradio")
return None
if __name__ == "__main__":
# Show usage information
demo_usage()
print("\n" + "="*50)
print("🎯 MANGA/COMIC TEXT REMOVAL SYSTEM READY!")
print("="*50)
# Auto-setup if requested
setup_choice = input("\nSetup environment now? (y/n): ").lower()
if setup_choice == 'y':
setup_environment()
except ImportError:
print("💻 Running in local environment")
print("Make sure all dependencies are installed:")
print("pip install opencv-python pillow numpy matplotlib tqdm easyocr
pytesseract transformers torch diffusers")
# Offer local setup
local_choice = input("\nInstall dependencies now? (y/n): ").lower()
if local_choice == 'y':
install_all_dependencies()
def quick_test():
"""Quick test function to verify everything works"""
print("🧪 Running quick system test...")
try:
# Test the system
remover = MangaTextRemover()
result = remover.process_image("test_manga.jpg", "test_result.jpg",
show_process=True)
# Clean up
if os.path.exists("test_manga.jpg"):
os.remove("test_manga.jpg")
return True
except Exception as e:
print(f"❌ System test failed: {e}")
return False
def optimize_for_colab():
"""Optimize settings for Google Colab environment"""
print("⚙️ Optimizing for Google Colab...")
# Memory optimization
import gc
gc.collect()
print("✅ Optimization complete!")
def create_sample_images():
"""Create sample manga-style images for testing"""
print("🎨 Creating sample images for testing...")
samples_dir = "sample_images"
os.makedirs(samples_dir, exist_ok=True)
def benchmark_methods():
"""Benchmark different detection and inpainting methods"""
print(" Benchmarking detection and inpainting methods...")
results = {}
file_results = {}
start_time = time.time()
try:
remover = MangaTextRemover()
result = remover.process_image(
sample_path,
f"benchmark_{sample_file}_{confidence}.jpg",
detection_confidence=confidence,
show_process=False
)
file_results[confidence] = {
'detections': result['stats']['detections_count'],
'time': processing_time,
'methods': result['stats']['detection_methods']
}
except Exception as e:
file_results[confidence] = {'error': str(e)}
results[sample_file] = file_results
return results
def create_advanced_gradio_interface():
"""Create advanced Gradio interface with more options"""
try:
import gradio as gr
try:
# Process
remover = MangaTextRemover()
result = remover.process_image(
temp_input,
temp_output,
detection_confidence=confidence,
inpaint_method=inpaint_method,
expand_mask=expand_mask,
show_process=False
)
# Load result
result_image = Image.open(temp_output)
detection_image = Image.fromarray(cv2.cvtColor(detection_vis,
cv2.COLOR_BGR2RGB))
mask_image = Image.fromarray(mask)
except Exception as e:
return None, None, None, None, f"Error: {str(e)}"
# Create interface
interface = gr.Interface(
fn=process_with_options,
inputs=[
gr.Image(type="pil", label="📸 Upload Manga/Comic Image"),
gr.Slider(0.05, 0.95, value=0.3, step=0.05, label="🎯 Detection
Confidence"),
gr.Dropdown(
["auto", "sd", "telea", "ns", "edge_connect", "patch_match"],
value="auto",
label="🎨 Inpainting Method"
),
gr.Slider(1, 20, value=5, step=1, label="📏 Mask Expansion
(pixels)"),
gr.Checkbox(value=False, label=" Show Processing Steps")
],
outputs=[
gr.Image(type="pil", label="✨ Text Removed Result"),
gr.Image(type="pil", label="🔍 Detected Text Regions"),
gr.Image(type="pil", label="🎭 Inpainting Mask"),
gr.Image(type="pil", label="📊 Before/After Comparison"),
gr.Textbox(label="📈 Processing Statistics", lines=8)
],
title="🎯 Advanced Manga/Comic Text Removal",
description="""
Upload a manga or comic image to automatically detect and remove text
while preserving the artwork.
**Tips:**
- Lower confidence detects more text but may include false positives
- 'auto' inpainting method chooses the best approach automatically
- Increase mask expansion for better coverage around text
- Use 'sd' method for highest quality (requires GPU)
""",
examples=[
["sample_images/sample1_simple.jpg", 0.3, "auto", 5, False],
["sample_images/sample2_bubble.jpg", 0.4, "telea", 7, False],
["sample_images/sample3_complex.jpg", 0.2, "auto", 8, False]
] if os.path.exists("sample_images") else None,
theme=gr.themes.Soft(),
allow_flagging="never"
)
return interface
except ImportError:
print("Gradio not available. Install with: pip install gradio")
return None
def create_batch_interface():
"""Create Gradio interface for batch processing"""
try:
import gradio as gr
import zipfile
try:
# Create temp directories
temp_dir = "temp_batch"
output_dir = "batch_output"
os.makedirs(temp_dir, exist_ok=True)
os.makedirs(output_dir, exist_ok=True)
# Create summary
summary = f"""
📊 Batch Processing Complete!
• Total images processed: {results['processed']}
• Failed images: {results['failed']}
• Success rate: {results['processed']/(results['processed']
+results['failed'])*100:.1f}%
except Exception as e:
return None, f"Error processing batch: {str(e)}"
interface = gr.Interface(
fn=process_batch,
inputs=[
gr.File(label="📦 Upload ZIP file with images",
file_types=[".zip"]),
gr.Slider(0.1, 0.9, value=0.3, label="🎯 Detection Confidence"),
gr.Dropdown(["auto", "telea", "ns"], value="auto", label="🎨
Inpainting Method")
],
outputs=[
gr.File(label="📥 Download Processed Images"),
gr.Textbox(label="📊 Processing Summary", lines=6)
],
title="📦 Batch Manga Text Removal",
description="Upload a ZIP file containing multiple manga/comic images
for batch processing."
)
return interface
except ImportError:
return None
def launch_application():
"""Launch the complete application with all features"""
print("🚀 Launching Manga Text Removal Application...")
# Check environment
gpu_available = check_gpu_availability()
if gpu_available:
print("🎮 GPU acceleration available - using advanced models")
else:
print("💻 Using CPU mode - basic models only")
# Create interfaces
basic_interface = create_gradio_interface()
advanced_interface = create_advanced_gradio_interface()
batch_interface = create_batch_interface()
demo = gr.TabbedInterface(
[basic_interface, advanced_interface, batch_interface] if
batch_interface else [basic_interface, advanced_interface],
["⚙️
Basic Mode", " Advanced Mode", "📦 Batch Mode"] if
batch_interface else ["⚙️
Basic Mode", " Advanced Mode"],
title="🎨 Complete Manga/Comic Text Removal System"
)
except Exception as e:
print(f"Web interface failed: {e}")
print("You can still use the command-line functions")
else:
print("❌ System test failed. Please check dependencies.")
if __name__ == "__main__":
# Show usage information
demo_usage()
print("\n" + "="*50)
print("🎯 MANGA/COMIC TEXT REMOVAL SYSTEM READY!")
print("="*50)
# Auto-setup if requested
setup_choice = input("\nSetup environment now? (y/n): ").lower()
if setup_choice == 'y':
setup_environment()
except ImportError:
print("💻 Running in local environment")
print("Make sure all dependencies are installed:")
print("pip install opencv-python pillow numpy matplotlib tqdm easyocr
pytesseract transformers torch diffusers gradio")
# Offer local setup
local_choice = input("\nInstall dependencies now? (y/n): ").lower()
if local_choice == 'y':
install_all_dependencies()
# Launch application
launch_choice = input("\nLaunch application? (y/n): ").lower()
if launch_choice == 'y':
launch_application()