Skip to content

Instantly share code, notes, and snippets.

@me-suzy
Created December 29, 2025 10:43
Show Gist options
  • Select an option

  • Save me-suzy/163139eedc4fe76410312b51ec9ca0fc to your computer and use it in GitHub Desktop.

Select an option

Save me-suzy/163139eedc4fe76410312b51ec9ca0fc to your computer and use it in GitHub Desktop.
7565oo.py
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