Created
December 29, 2025 10:43
-
-
Save me-suzy/163139eedc4fe76410312b51ec9ca0fc to your computer and use it in GitHub Desktop.
7565oo.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
| import cv2 | |
| import numpy as np | |
| from pathlib import Path | |
| def remove_underlines_statistical(image_path, output_path=None): | |
| """ | |
| Elimină sublinierile folosind abordare statistică: | |
| - Frecvența pixelilor în zona de subliniere per rând | |
| - Mediana + k*std ca threshold pentru detectare | |
| - Înlocuire cu mediana fundalului local | |
| """ | |
| img = cv2.imread(str(image_path)) | |
| if img is None: | |
| raise ValueError(f"Nu s-a putut încărca: {image_path}") | |
| # Pasul 1: Desaturare completă | |
| hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | |
| h, s, v = cv2.split(hsv) | |
| s_zero = np.zeros_like(s) | |
| hsv_desat = cv2.merge([h, s_zero, v]) | |
| img_gray = cv2.cvtColor(hsv_desat, cv2.COLOR_HSV2BGR) | |
| gray = cv2.cvtColor(img_gray, cv2.COLOR_BGR2GRAY) | |
| # Pasul 2: Gamma correction | |
| gamma = 3.0 | |
| inv_gamma = 1.0 / gamma | |
| table = np.array([((i / 255.0) ** inv_gamma) * 255 for i in range(256)]).astype("uint8") | |
| gamma_corrected = cv2.LUT(gray, table) | |
| # Pasul 3: Analiză statistică per rând | |
| # Zona de subliniere potențială: 120-220 (după gamma) | |
| # Text: 0-120, Fundal: 220-255 | |
| UNDERLINE_LOW = 120 | |
| UNDERLINE_HIGH = 220 | |
| height, width = gamma_corrected.shape | |
| # Calculăm frecvența pixelilor în zona de subliniere pentru fiecare rând | |
| f_under_arr = np.zeros(height) | |
| for y in range(height): | |
| row = gamma_corrected[y, :] | |
| f_under = np.sum((row >= UNDERLINE_LOW) & (row < UNDERLINE_HIGH)) / width | |
| f_under_arr[y] = f_under | |
| # Threshold bazat pe distribuția frecvențelor | |
| # Folosim mediana + k*std (distribuție aproximativ normală) | |
| median_f = np.median(f_under_arr) | |
| std_f = np.std(f_under_arr) | |
| k = 1.0 # Factor de sensibilitate | |
| threshold_f = median_f + k * std_f | |
| # Rândurile suspecte | |
| suspect_rows = f_under_arr > threshold_f | |
| print(f"Statistici frecvență zonă subliniere:") | |
| print(f" Mediana: {median_f:.4f}") | |
| print(f" Std: {std_f:.4f}") | |
| print(f" Threshold: {threshold_f:.4f}") | |
| print(f" Rânduri suspecte: {suspect_rows.sum()} din {height}") | |
| # Pasul 4: Înlocuire pixeli subliniere cu mediana fundalului | |
| result = gamma_corrected.copy() | |
| for y in np.where(suspect_rows)[0]: | |
| row = result[y, :] | |
| underline_mask = (row >= UNDERLINE_LOW) & (row < UNDERLINE_HIGH) | |
| if underline_mask.any(): | |
| # Mediana fundalului din rând | |
| bg_pixels = row[row >= UNDERLINE_HIGH] | |
| if len(bg_pixels) > 0: | |
| replacement = int(np.median(bg_pixels)) | |
| else: | |
| replacement = 240 | |
| row[underline_mask] = replacement | |
| # Pasul 5: Binarizare adaptivă | |
| gray_blur = cv2.GaussianBlur(result, (3, 3), 0) | |
| binary = cv2.adaptiveThreshold(gray_blur, 255, | |
| cv2.ADAPTIVE_THRESH_GAUSSIAN_C, | |
| cv2.THRESH_BINARY, 25, 12) | |
| # Salvare | |
| if output_path is None: | |
| p = Path(image_path) | |
| output_path = p.parent / f"{p.stem}_clean{p.suffix}" | |
| cv2.imwrite(str(output_path), binary) | |
| print(f"Salvat: {output_path}") | |
| return binary | |
| # ========== CONFIGURARE ========== | |
| IMAGE_PATH = r"d:\imagine_noua.jpg" | |
| OUTPUT_PATH = r"d:\imagine_noua_clean.jpg" | |
| # ================================= | |
| if __name__ == "__main__": | |
| print("Eliminare sublinieri - Abordare Statistică") | |
| print(f"Input: {IMAGE_PATH}") | |
| print(f"Output: {OUTPUT_PATH}") | |
| print("-" * 50) | |
| remove_underlines_statistical(IMAGE_PATH, OUTPUT_PATH) | |
| print("-" * 50) | |
| print("Gata!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment