avatarDan Carlson

Summary

This article provides guidance on conducting successful coastal drone surveys, emphasizing the challenges of photographing both land and submerged features, and explains how to enhance images using Python while preserving EXIF data for accurate mapping with Structure from Motion (SFM) software.

Abstract

The use of drones equipped with cameras and GPS has become a valuable tool for coastal monitoring and marine science, allowing for high-resolution mapping and repeatable surveys. However, capturing high-quality imagery in coastal environments is challenging due to varying light conditions, wind, waves, and sun glint, which can obscure or blur features in the images. The article discusses these challenges and offers practical solutions, such as adjusting camera settings, planning surveys based on weather and tidal conditions, and altering the camera's viewing angle to minimize sun glint. It also introduces a Python-based method for enhancing images using contrast limited adaptive histogram equalization (CLAHE) while ensuring that the essential EXIF data, crucial for SFM processing, is retained. The article concludes with advice on iterative testing and adherence to legal regulations for drone operations in coastal areas.

Opinions

  • The author acknowledges the complexity of capturing clear images in coastal areas due to the contrasting lighting conditions between land and water.
  • It is suggested that manual adjustments to drone

How To Execute Successful Coastal Drone Surveys

And how to enhance images using Python

Left: Original drone aerial image of a coastal area. Right: The same image enhanced using contrast limited adaptive histogram equalization (CLAHE) [Images produced by the author]

Camera and GPS-equipped consumer drones have revolutionized coastal monitoring and marine science. The availability of Structure from Motion (SFM) software like Agisoft Metashape and Pix4D, as well as services like Geonadir, enables high-resolution mapping of coastal areas. Pre-programmed flight routes allow the same drone surveys to be repeated, giving scientists and resource managers the ability to detect even the smallest changes.

However, the same features must be clearly visible in multiple overlapping images for SFM matching algorithms to work correctly. Despite increasingly advanced drones and camera systems, acquiring high quality imagery of coastal areas remains a challenge.

The image above illustrates this challenge. In the original image (on the left), submerged features are underexposed while some of the exposed rocks are overexposed. The enhanced image (on the right) reveals more submerged features as well as more details in the rocks.

This image was enhanced using contrast enhanced adaptive histogram equalization (CLAHE). Enhancing images using CLAHE is relatively easy to do in Python, but simply saving enhanced images as JPEGs might cause headaches when you attempt to process them with SFM software. SFM software uses the data stored in the EXIF header to set the interior and exterior camera parameters. Simply applying CLAHE and saving the result will strip out the EXIF data.

In this post you will learn about the challenges encountered when photographing coastal areas and methods to enhance your images while preserving the EXIF data from the original image.

Bright Land, Dark Water

Photographing coastal areas is tricky, especially if you want to capture land and features submerged in shallow water. Submerged features could include shallow navigational hazards, like rocks, and/or habitats, like seagrass and macroalgae. The dry part of your image is probably going to be brighter than the wet part. Keep a sharp eye on your drone’s shutter speed and aperture settings during the survey. If necessary, manually set/change the area of the image that’s analyzed to determine exposure settings.

Wind, Waves, and Sun

While this sounds like the perfect day at the beach, wind, waves, and sun can cause problems for drone surveys. Weak to moderate winds generate ripples (capillary waves) that can cause images to appear blurred (as shown below). Larger waves can resuspend sediment on the bottom, leading to murky water.

Sun glint, or sun glitter, can also cause problems for coastal drone surveyors. In the image below, most of the lower left quadrant is obscured by sun glint. Sun glint is most visible when the angle of the reflected sunlight is the same as the viewing angle of the camera on the drone. Waves “roughen” the water’s surface, enhancing sun glint. In theory, sun glint can be avoided by flying during calm conditions in the early morning and in the late evening, when the sun is lower. However, the weak light and lower sun angle create problems of their own. The early morning light might be ideal for yoga and meditation, but it might not penetrate deep enough into the water. The low sun angle may also result in unwanted shadows from trees and other terrestrial features.

Sun glint obscures the bottom left corner of this drone image. Waves distort the sea surface, making the shallow seabed and seagrass appear blurry. [Image by the author]

Plan Ahead

Successfully executing a coastal drone survey requires more planning than, say, an agricultural survey. Don’t expect perfect results on your first try. Check the weather and marine forecasts to find a window with weak winds and no waves. If you’re interested in mapping shallow, submerged areas find a tide chart for your area and

If you’re using a survey app like Pix4D Capture, pay attention to camera settings (exposure, shutter speed, ISO, and white balance) as well as survey speed. While you might be able to fly quickly over land, speed might blur submerged areas, which are darker. A bit of trial and error might be necessary to find the right balance between flight speed and shutter speed. You might have to resort to manual flights is you can find this balance in the app.

Sun glint can be minimized by changing the viewing angle of the camera. Instead of shooting at nadir, shoot 5–10 degrees off-nadir. Most drone survey apps allow you to set the camera angle so use something like 80–85 degrees instead of 90 degrees if you fly in the middle of the day.

Sun glint in the brighter hours of the day can be minimized further with a bit of simple math. Find the solar azimuth angle for the location and time of your survey. The solar azimuth angle is horizontal angle formed between the sun’s position and due north (not to be confused with the solar elevation angle, which is the vertical angle between the horizon and the position of the sun in the sky). Sun glint will be minimal when flying along (towards and away from) the solar azimuth angle. If your drone survey planning software allows you to set the heading or yaw of the drone during flight, set it to equal the solar azimuth angle (there’s a great paper by Joyce et al. 2019 that explains this, and other issues, in detail).

Image Enhancement in Python

Before proceeding, check to make sure you have the necessary packages. This code requires OpenCV and piexif. If not already installed, use pip or Anaconda.

This code does the following:

  1. Reads the original image
  2. Applies CLAHE using OpenCV
  3. Reads the EXIF data from the original image using piexif
  4. Writes the CLAHE image with the EXIF data

To run this code, copy it to your python/text editor and save it as ‘clahe_exif.py’

Make sure to change ‘orig_jpg’ and ‘img_out’ !

Open a terminal window in the directory containing the python script and run it by entering the command ‘python clahe_exif.py’

Right click on the enhanced image and verify that the EXIF data has been copied to the output image. If you use SFM software, add the enhanced image and verify that your software can read the GPS and camera/lens information from the EXIF header.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
import numpy as np
import matplotlib.pyplot as plt
import piexif

def clahe_exif(image_path, output_path, clip_limit=2.0, grid_size=(8, 8)):
    # Step 1: Load the image
    rgb_image = cv2.imread(image_path)
    
    # Step 2: Apply CLAHE to the original RGB image
    # Convert the image to LAB color space
    lab_image = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2LAB)
    
    # Split the LAB image into channels
    l_channel, a_channel, b_channel = cv2.split(lab_image)
    
    # Apply CLAHE to the L channel
    clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=grid_size)
    clahe_l_channel = clahe.apply(l_channel)
    
    # Merge the processed L channel back with the other channels
    processed_lab_image = cv2.merge((clahe_l_channel, a_channel, b_channel))
    
    # Convert the processed LAB image back to BGR color space
    processed_rgb_image = cv2.cvtColor(processed_lab_image, cv2.COLOR_LAB2BGR)
    
    # Step 3: Write the result to JPG while preserving the original EXIF data
    # Load EXIF data using piexif
    exif_dict = piexif.load(image_path)
    
    # Remove thumbnail data (optional)
    if 'thumbnail' in exif_dict:
        del exif_dict['thumbnail']
    
    # Convert the EXIF data dictionary to bytes
    exif_bytes = piexif.dump(exif_dict)
    
    # Save the processed image as a JPEG file with preserved EXIF data
    cv2.imwrite(output_path, processed_rgb_image, [cv2.IMWRITE_JPEG_QUALITY, 95])
    piexif.insert(exif_bytes, output_path)
    
    print(f"Processed image saved to '{output_path}'")
    
orig_jpg = '/Users/dfc/Documents/other/clahe/DJI_0116.JPG'
img_out = '/Users/dfc/Documents/other/clahe/DJI_0116_clahe.JPG'
clahe_exif(orig_jpg,img_out)

This example uses a single image and can be extended to an entire directory with a few extra lines of code using glob and os.

import os
from glob import glob
# specify image directory
img_path = '/path/to/images/'
# get a list of all JPGs in an image directory
orig_jpgs = sorted(glob(img_path+'*.JPG'))
# specify output directory
out_dir = 'out/put/direc/tory/'
# loop through the list of original jpgs
for oj in orig_jpgs:
  # make output image name
  file_name = os.path.basename(oj)
  base_name, extension = os.path.splitext(file_name)
  img_out = out_dir + base_name + "_clahe.jpg"
  clahe_exif(oj,img_out)

Wrapping Up

Hopefully this post helps you avoid common pitfalls experienced when conducting drone surveys of coastal areas. These tips only apply to relatively clear water. There’s no getting around turbidity, at least with passive optics.

Don’t be discouraged if you still end up with bad images. Instead, look carefully at the images, keep track of conditions, and find out why your drone survey failed.

This post focused on the practicalities and steered clear of legal issues. Make sure to follow all drone laws in your area and note that many coastal areas are protected.

If you found this post helpful please:

  • Give me all 50 of your claps!
  • Leave a comment
  • Highlight important text
  • Subscribe to get more helpful Metashape, Python, and Drone tips!

In Plain English

Thank you for being a part of our community! Before you go:

Python
Opencv
Drones
Remote Sensing
Image Processing
Recommended from ReadMedium