[EN]Python Script to Automatically Correct Underwater Photos

Underwater, different wavelengths of light are progressively absorbed: red disappears first, followed by orange and yellow. Even at shallow depths, photos often have a blue-cyan color cast. As a result, images look bluish or greenish and corals lose their natural colors. Fortunately, this can be corrected quite easily.



At shallow depths (<2–3 m), red loss is limited but images are often dominated by blue/cyan tones.
For automatic processing (for example before using CoralReef tools), the best approach is:

  • automatic white balance
  • slight enhancement of the red channel
  • reduction of the blue channel
  • contrast enhancement

This can easily be done with Python + OpenCV on an entire image folder.

In scientific underwater image processing, several methods from computer vision are commonly used:

  • Gray World / adaptive white balance
  • Red Channel Compensation (RCC) to reconstruct lost red information
  • CLAHE (Contrast Limited Adaptive Histogram Equalization)
  • sometimes Retinex for illumination correction

This combination is used in several research works on coral reefs and underwater robotics.

This preprocessing step is useful for coral reef monitoring workflows using machine learning or computer vision.

Here I propose a robust Python script that applies:

1️⃣ red channel compensation
2️⃣ Gray-World white balance
3️⃣ contrast enhancement (CLAHE)
4️⃣ batch processing of a folder

This approach is significantly more effective than simple scripts.


Python Script

This script:

  • reads all images in a folder
  • corrects white balance
  • rebalances color channels
  • saves corrected images into a new folder

The complete script is available on GitHub.

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é")


How to automatically correct underwater photos with Python

Steps:

  1. Install the required Python libraries (OpenCV, NumPy)
  2. Place your underwater photos in a folder
  3. Run the Python script
  4. Generate corrected images automatically
  5. Use the corrected images for coral reef analysis

Installation

In an OSGeo4W shell:

pip install opencv-python numpy

Folder structure

project/
script.py
raw_photos/
img1.jpg
img2.jpg
corrected_photos/

Before / After correction

underwater coral color correction python opencv
Before correction with the script ————– After correction

Why this method is used in research

It corrects the three major issues of underwater images:

ProblemCorrection
red absorptionRed Channel Compensation
blue-green color castGray World
low contrastCLAHE

Results:

  • more natural colors
  • clearer coral textures
  • more stable automatic segmentation

This is very useful for coral reef analysis tools.


Why this script works well with CoralReef

Coral reef analysis tools often rely on:

  • color segmentation
  • coral classification

The script improves:

  • coral / water separation
  • texture visibility
  • color consistency

which can improve automatic detection.


Note: If images are taken at very shallow depth (~1 m), you can slightly reduce the red compensation:

r = r + (g_mean - np.mean(r))*0.4

FAQ

Why do underwater photos look blue?

Water absorbs red wavelengths first, leaving mostly blue and green light. This is why underwater images often appear bluish.

Can Python automatically correct underwater photos?

Yes. Using libraries such as OpenCV, it is possible to automatically correct color balance, restore the red channel, and improve contrast.

Why is image correction important for coral reef analysis?

Color correction improves segmentation, classification and texture detection in coral reef monitoring tools.


This Python script can be used as an image preprocessing step for automatic coral reef analysis, before classification or segmentation tools.


Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

Leave a Reply

Your email address will not be published. Required fields are marked *