Bajo el agua, las diferentes longitudes de onda de la luz se absorben progresivamente: el rojo desaparece primero, seguido por el naranja y el amarillo. Incluso a poca profundidad, las fotos suelen presentar una dominante azul-cian. Como resultado, las imágenes se ven azuladas o verdosas y los corales pierden sus colores naturales. Afortunadamente, esto se puede corregir con bastante facilidad.
A poca profundidad (<2-3 m), la pérdida de rojo es limitada, pero la imagen suele estar dominada por tonos azul/cian.
Para un procesamiento automático (por ejemplo antes de usar herramientas de CoralReef), el mejor enfoque es:
- balance de blancos automático
- ligero refuerzo del canal rojo
- reducción del canal azul
- aumento del contraste
Esto se puede hacer fácilmente con Python + OpenCV sobre un directorio completo de imágenes.
En el procesamiento científico de imágenes submarinas se utilizan varias técnicas de visión por computadora:
- Gray World / balance de blancos adaptativo
- Red Channel Compensation (RCC) para reconstruir el rojo perdido
- CLAHE (Contrast Limited Adaptive Histogram Equalization)
- en algunos casos Retinex para corregir la iluminación
Esta combinación se utiliza en numerosos estudios sobre arrecifes de coral y robótica submarina.
Este script de Python aplica:
1️⃣ compensación del canal rojo
2️⃣ balance de blancos Gray-World
3️⃣ mejora de contraste (CLAHE)
4️⃣ procesamiento por lotes de un directorio
Este método es mucho más eficaz que los scripts simples.
Script Python
import cv2
import numpy as np
import os
from pathlib import Path
input_dir = "photos_brutes"
output_dir = "photos_corrigees"
Path(output_dir).mkdir(exist_ok=True)
# -----------------------------
# Red Channel Compensation
# -----------------------------
def red_channel_compensation(img):
b,g,r = cv2.split(img)
b_mean = np.mean(b)
g_mean = np.mean(g)
r = r + (g_mean - np.mean(r))*0.6
r = r + (b_mean - np.mean(r))*0.3
r = np.clip(r,0,255)
return cv2.merge([b,g,r.astype(np.uint8)])
# -----------------------------
# Gray World White Balance
# -----------------------------
def gray_world(img):
img = img.astype(np.float32)
avg_b = np.mean(img[:,:,0])
avg_g = np.mean(img[:,:,1])
avg_r = np.mean(img[:,:,2])
avg = (avg_b + avg_g + avg_r) / 3
img[:,:,0] *= avg/avg_b
img[:,:,1] *= avg/avg_g
img[:,:,2] *= avg/avg_r
img = np.clip(img,0,255)
return img.astype(np.uint8)
# -----------------------------
# CLAHE Contrast Enhancement
# -----------------------------
def enhance_contrast(img):
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l,a,b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=2.5, tileGridSize=(8,8))
l = clahe.apply(l)
lab = cv2.merge((l,a,b))
return cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)
# -----------------------------
# Pipeline complet
# -----------------------------
def process(img):
img = red_channel_compensation(img)
img = gray_world(img)
img = enhance_contrast(img)
return img
# -----------------------------
# Batch processing
# -----------------------------
for file in os.listdir(input_dir):
if file.lower().endswith((".jpg",".jpeg",".png",".tif",".tiff")):
path = os.path.join(input_dir,file)
img = cv2.imread(path)
if img is None:
print("image ignorée:", file)
continue
corrected = process(img)
outpath = os.path.join(output_dir,file)
cv2.imwrite(outpath,corrected)
print("processed:",file)
print("Terminé")Instalación
En una consola OSGeo4W:
pip install opencv-python numpy
Estructura de carpetas
proyecto/
script.py
fotos_brutas/
fotos_corregidas/
Antes / Después
Por qué se utiliza este método en investigación
Corrige tres problemas principales de las imágenes submarinas:
| Problema | Corrección |
|---|---|
| absorción del rojo | Red Channel Compensation |
| dominante azul-verde | Gray World |
| bajo contraste | CLAHE |
Resultados:
- colores más naturales
- texturas de coral más visibles
- segmentación automática más estable
Esto es muy útil para el análisis de arrecifes de coral.
