Created
February 13, 2026 18:54
-
-
Save me-suzy/87e62c1a88270d09a9d56bad26652f9c to your computer and use it in GitHub Desktop.
rtsdfs.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| import cv2 | |
| import numpy as np | |
| from pathlib import Path | |
| import sys | |
| try: | |
| if sys.platform == 'win32' and hasattr(sys.stdout, 'buffer'): | |
| import io | |
| sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') | |
| sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') | |
| except: | |
| pass | |
| def detect_colored_lines(img): | |
| """Detecteaza liniile colorate""" | |
| hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | |
| mask_red1 = cv2.inRange(hsv, np.array([0, 50, 50]), np.array([10, 255, 255])) | |
| mask_red2 = cv2.inRange(hsv, np.array([160, 50, 50]), np.array([180, 255, 255])) | |
| mask_red = cv2.bitwise_or(mask_red1, mask_red2) | |
| mask_blue = cv2.inRange(hsv, np.array([100, 50, 50]), np.array([130, 255, 255])) | |
| mask_green = cv2.inRange(hsv, np.array([35, 50, 50]), np.array([85, 255, 255])) | |
| mask_yellow = cv2.inRange(hsv, np.array([20, 50, 50]), np.array([35, 255, 255])) | |
| combined_mask = cv2.bitwise_or(mask_red, mask_blue) | |
| combined_mask = cv2.bitwise_or(combined_mask, mask_green) | |
| combined_mask = cv2.bitwise_or(combined_mask, mask_yellow) | |
| s = hsv[:, :, 1] | |
| saturation_mask = (s > 40).astype(np.uint8) * 255 | |
| combined_mask = cv2.bitwise_and(combined_mask, saturation_mask) | |
| h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 1)) | |
| lines_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, h_kernel) | |
| for angle in [-10, -7, -5, -3, 3, 5, 7, 10]: | |
| length = 30 | |
| rad = np.deg2rad(angle) | |
| dx = int(length * np.cos(rad)) | |
| dy = int(length * np.sin(rad)) | |
| kernel_size = max(abs(dx), abs(dy)) + 1 | |
| kernel = np.zeros((kernel_size * 2 + 1, kernel_size * 2 + 1), dtype=np.uint8) | |
| cv2.line(kernel, (kernel_size - dx, kernel_size - dy), | |
| (kernel_size + dx, kernel_size + dy), 1, 2) | |
| lines_angle = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, kernel) | |
| lines_mask = cv2.bitwise_or(lines_mask, lines_angle) | |
| dilate_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 7)) | |
| lines_mask = cv2.dilate(lines_mask, dilate_kernel, iterations=2) | |
| return lines_mask | |
| def remove_colored_lines(img, lines_mask): | |
| result = cv2.inpaint(img, lines_mask, 3, cv2.INPAINT_TELEA) | |
| return result | |
| def apply_photoscape_settings(img): | |
| """Aplica setarile PhotoScape X pentru text clar""" | |
| # Convertim la float pentru calcule precise | |
| img_float = img.astype(np.float32) / 255.0 | |
| # 1. Temperature 3000 (foarte cald/galben) - shifteaza spre galben | |
| # Scadem albastru, adaugam rosu/galben | |
| img_float[:, :, 0] = img_float[:, :, 0] * 0.6 # Blue channel redus | |
| img_float[:, :, 2] = np.clip(img_float[:, :, 2] * 1.2, 0, 1) # Red usor crescut | |
| # 2. Whites -100 (alburile devin mai inchise/galbene) | |
| white_threshold = 0.85 | |
| white_mask = np.mean(img_float, axis=2) > white_threshold | |
| for c in range(3): | |
| channel = img_float[:, :, c] | |
| # Inchide zonele albe | |
| channel[white_mask] = channel[white_mask] * 0.9 | |
| img_float[:, :, c] = channel | |
| # 3. Darken Highlights 100 | |
| highlights = np.mean(img_float, axis=2) > 0.7 | |
| for c in range(3): | |
| channel = img_float[:, :, c] | |
| channel[highlights] = channel[highlights] * 0.85 | |
| img_float[:, :, c] = channel | |
| # 4. Contrast 100 - crestem contrastul | |
| mean_val = 0.5 | |
| contrast_factor = 1.5 | |
| img_float = (img_float - mean_val) * contrast_factor + mean_val | |
| img_float = np.clip(img_float, 0, 1) | |
| # 5. Burn 100 - intuneca tonurile medii/inchise | |
| burn_mask = np.mean(img_float, axis=2) < 0.6 | |
| for c in range(3): | |
| channel = img_float[:, :, c] | |
| channel[burn_mask] = channel[burn_mask] * 0.7 | |
| img_float[:, :, c] = channel | |
| # 6. Cyan/Red -100, Magenta/Green -100, Yellow/Blue -100 | |
| # Elimina culorile, face imaginea mai neutra/galbena | |
| # Deja aplicat partial prin temperature | |
| # 7. Saturation 100 - pastram saturatia pentru galben | |
| hsv = cv2.cvtColor((img_float * 255).astype(np.uint8), cv2.COLOR_BGR2HSV).astype(np.float32) | |
| hsv[:, :, 1] = np.clip(hsv[:, :, 1] * 1.3, 0, 255) | |
| img_float = cv2.cvtColor(hsv.astype(np.uint8), cv2.COLOR_HSV2BGR).astype(np.float32) / 255.0 | |
| # Convertim inapoi la uint8 | |
| result = (np.clip(img_float, 0, 1) * 255).astype(np.uint8) | |
| return result | |
| def process_image(image_path, output_path): | |
| img = cv2.imread(str(image_path)) | |
| if img is None: | |
| raise ValueError(f"Nu s-a putut incarca: {image_path}") | |
| print(f" Procesare: {Path(image_path).name}") | |
| # Pasul 1: Aplicam setarile PhotoScape (text clar) | |
| img_enhanced = apply_photoscape_settings(img) | |
| print(" -> Setari PhotoScape aplicate") | |
| # Pasul 2: Eliminam liniile colorate | |
| lines_mask = detect_colored_lines(img) # Detectam pe imaginea originala | |
| if np.any(lines_mask > 0): | |
| result = cv2.inpaint(img_enhanced, lines_mask, 3, cv2.INPAINT_TELEA) | |
| print(" -> Linii colorate eliminate") | |
| else: | |
| result = img_enhanced | |
| cv2.imwrite(str(output_path), result) | |
| print(f" [OK] Salvat: {output_path}") | |
| return result | |
| def process_folder(input_folder, output_folder): | |
| input_path = Path(input_folder) | |
| output_path = Path(output_folder) | |
| output_path.mkdir(parents=True, exist_ok=True) | |
| extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tiff', '*.tif'] | |
| images = [] | |
| for ext in extensions: | |
| images.extend(input_path.glob(ext)) | |
| images.extend(input_path.glob(ext.upper())) | |
| images = sorted(set(images)) | |
| if not images: | |
| print(f"Nu s-au gasit imagini in: {input_folder}") | |
| return | |
| print(f"Gasite {len(images)} imagini de procesat\n") | |
| success = 0 | |
| failed = 0 | |
| for img_path in images: | |
| output_file = output_path / img_path.name | |
| try: | |
| process_image(img_path, output_file) | |
| success += 1 | |
| except Exception as e: | |
| print(f" [EROARE] {img_path.name}: {e}") | |
| failed += 1 | |
| print(f"\n{'='*60}") | |
| print(f"REZULTAT: {success} procesate, {failed} erori") | |
| print(f"{'='*60}") | |
| if __name__ == "__main__": | |
| input_folder = r"e:\Carte\BB\17 - Site Leadership\alte\Ionel Balauta\Aryeht\Task 1 - Traduce tot site-ul\Doar Google Web\Andreea\Meditatii\2023\Edit Text Images (Remove shadows + Remove red LInes)\TTT" | |
| output_folder = r"e:\Carte\BB\17 - Site Leadership\alte\Ionel Balauta\Aryeht\Task 1 - Traduce tot site-ul\Doar Google Web\Andreea\Meditatii\2023\Edit Text Images (Remove shadows + Remove red LInes)\Output" | |
| print("=" * 60) | |
| print("PROCESARE - PhotoScape settings + Eliminare linii") | |
| print("=" * 60) | |
| print(f"Input: {input_folder}") | |
| print(f"Output: {output_folder}") | |
| print("=" * 60 + "\n") | |
| process_folder(input_folder, output_folder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment