Revisiting Art and Fusion Technology: The Beach and Windmill Experiment

Yesterday I had a photo in my gallery from a little experiment with Enfuse – Since I received quite a few positive reactions and some questions via email, I decided to dedicate a second article to the topic.

If you have Enfuse installed on your system — whether through Hugin, your package manager, or directly from the Enblend-Enfuse website — you can easily merge two or more images using a single command in your terminal or command prompt. Whether this is to improve HDR images, do focus stacking, or simply merge differently exposed or mirrored photos into one image, as long as you’re feeling inspired, it can produce some fun and interesting results.

Tip:
Some of the messages I received mentioned that using commands and scripts can seem complicated—or even a bit scary. People worry about making mistakes. But here’s the good news: if you’re not familiar with this kind of thing but you’ve used ChatGPT before, just ask it to create a script for you—like one that merges photos from a specific folder. Ask it to walk you through the steps, one by one. Before you know it, you’ll be typing commands on your computer like a pro and fusing photos with ease!

What You Need

  • Two or more images of the same scene, ideally taken with different exposures (bracketing).
  • Enfuse, properly installed.

That’s it.

The Basic Command

enfuse -o result.jpg photo1.jpg photo2.jpg

Explanation:

  • -o result.jpg tells Enfuse what to name the output file.
  • photo1.jpg photo2.jpg are the input images you want to fuse.

Enfuse analyzes the input and blends them by selecting the best-exposed and most detailed parts of each image. It produces a natural-looking result without complicated HDR tone-mapping.

Important Note on Alignment

Your photos must be perfectly aligned. If you shot handheld or notice any misalignment, it’s best to align the images first:

align_image_stack -m -a aligned_ photo1.jpg photo2.jpg
enfuse -o result.jpg aligned_*.tif

The align_image_stack tool, which comes with Hugin, creates aligned TIFF files that you can feed directly into Enfuse.

Platform Notes

Windows: If you installed Hugin, you probably already have Enfuse. Just open CMD or PowerShell and run the command.

macOS: You can install Enfuse using Homebrew:

brew install enblend-enfuse

Linux: Use your system’s package manager:

sudo apt install enblend-enfuse

or

sudo dnf install enblend-enfuse

What Does Enfuse Actually Do?

Enfuse is not a traditional HDR tool. It doesn’t stretch the dynamic range or apply tone-mapping. Instead, it blends multiple exposures by evaluating local contrast, exposure, and saturation. The result is a clean, well-balanced image without halos or artificial effects.

That’s all you need to start experimenting with exposure fusion. Try it with a basic bracketed set (like -1 EV, 0 EV, +1 EV) and see what it can do.s

Top and bottom: two mirrored and fusion-created results.

And below, the two photos that were used – two photos, multiple possibilities.

Like yesterday in my gallery :

In the meantime, the script has also been updated and now includes some extra code to handle issues.

Execute it with bash [name of the script].sh

Copy and paste it into a text editor – save with a name something like this : Auto-Fusion-Utility.sh

Run chmod +x [name of the script].sh

#!/bin/bash#Auto-Fusion-Utility.shLOGFILE="debug_EnfuseUtility.log"echo "==== Nieuwe run op $(date) ====" >> "$LOGFILE"lastsettings=".lastsettings"logfile="./lastfusion.txt"print_header() {  clear  echo -e "\n╔══════════════════════════════════════════════╗"  printf "║ %-44s ║\n" "$1"  echo "╚══════════════════════════════════════════════╝"}validate_numeric() {  if ! [[ "$1" =~ ^[0-9]*\.?[0-9]+$ ]]; thenecho "Invalid number: $1" >&2exit 1  fi}save_last_settings() {  echo "$1" > "$lastsettings"  echo "$2" >> "$lastsettings"  echo "$3" >> "$lastsettings"  echo "$4" >> "$lastsettings"  echo "$5" >> "$lastsettings"  echo "$6" >> "$lastsettings"}load_last_settings() {  if [[ ! -f "$lastsettings" ]]; thenecho "No previous settings found." >&2exit 1  fi  IFS=$'\n' read -r last_dir last_ext last_exposure last_saturation last_contrast hmasklog < "$lastsettings"  if [[ "$hmasklog" == "YES" ]]; thenhardmask="--hard-mask"  elsehardmask=""  fi}ask_hardmask() {  read -rp "Use hard mask? (y/n): " hardmaskchoice  if [[ "$hardmaskchoice" =~ ^[Yy]$ ]]; thenhardmask="--hard-mask"hmasklog="YES"  elsehardmask=""hmasklog="NO"  fi}run_enfuse() {  local output="$1"  shift  local files=("$@")  if [[ ${#files[@]} -eq 0 ]]; thenecho "⚠️ Geen bestanden gevonden om te fusen." | tee -a "$LOGFILE"exit 1  fi  echo "Starting enfuse with output: $output" | tee -a "$LOGFILE"  echo "Input files:" | tee -a "$LOGFILE"  for f in "${files[@]}"; doecho "  $f" | tee -a "$LOGFILE"  done  enfuse --exposure-weight="$exposure_weight" --saturation-weight="$saturation_weight" --contrast-weight="$contrast_weight" $hardmask --output="$output" "${files[@]}" >> "$LOGFILE" 2>&1  local enfuse_status=$?  if (( enfuse_status != 0 )); thenecho "❌ enfuse faalde met status $enfuse_status. Check $LOGFILE" | tee -a "$LOGFILE"exit $enfuse_status  fi  if [[ ! -f "$output" ]]; thenecho "❌ Outputbestand niet gevonden: $output" | tee -a "$LOGFILE"exit 1  fi  echo "✅ Fusion succesvol, output: $output" | tee -a "$LOGFILE"}print_header "ENFUSE FUSION TOOL - MAIN MENU"echo "║  1. Quick Fusion (default weights)   ║"echo "║  2. Custom Fusion (interactive input)║"echo "║  3. Repeat Last Fusion   ║"echo "║  Q. Quit ║"echo "╚══════════════════════════════════════════════╝"read -rp "Choose an option [1, 2, 3, Q]: " runoptioncase "$runoption" in  "1")print_header "QUICK FUSION – DEFAULT SETTINGS"read -rp "Image Path (no trailing slash): " variable1if [[ -z "$variable1" || ! -d "$variable1" ]]; then  echo "Invalid path." >&2  exit 1firead -rp "Image Extension (jpg, tif, etc.): " ext1# Gewichten defaultexposure_weight=1saturation_weight=1contrast_weight=1# Hardmask interactiefask_hardmasktimestamp=$(date +"%Y%m%d_%H%M%S")outputfile="$variable1/output_$timestamp.$ext1"mapfile -t files < <(find "$variable1" -maxdepth 1 -type f -iname "*.$ext1" | sort)run_enfuse "$outputfile" "${files[@]}"echo -e "\n[QUICK FUSION - $timestamp]" >> "$logfile"echo "Source: $variable1/*.$ext1" >> "$logfile"echo "Output: $outputfile" >> "$logfile"echo "Weights: exposure=$exposure_weight, saturation=$saturation_weight, contrast=$contrast_weight" >> "$logfile"echo "Hard Mask: $hmasklog" >> "$logfile"save_last_settings "$variable1" "$ext1" "$exposure_weight" "$saturation_weight" "$contrast_weight" "$hmasklog"read -rp "View output image? (y/n): " viewimg[[ "$viewimg" =~ ^[Yy]$ ]] && xdg-open "$outputfile" >/dev/null 2>&1 &;;  "2")print_header "CUSTOM FUSION – YOUR SETTINGS"read -rp "Image Path (no trailing slash): " variable1if [[ -z "$variable1" || ! -d "$variable1" ]]; then  echo "Invalid path." >&2  exit 1firead -rp "Image Extension (jpg, tif, etc.): " ext1read -rp "Exposure weight (e.g., 1): " exposure_weight; validate_numeric "$exposure_weight"read -rp "Saturation weight (e.g., 0.2): " saturation_weight; validate_numeric "$saturation_weight"read -rp "Contrast weight (e.g., 0.3): " contrast_weight; validate_numeric "$contrast_weight"ask_hardmasktimestamp=$(date +"%Y%m%d_%H%M%S")outputfile="$variable1/output_$timestamp.$ext1"mapfile -t files < <(find "$variable1" -maxdepth 1 -type f -iname "*.$ext1" | sort)run_enfuse "$outputfile" "${files[@]}"echo -e "\n[CUSTOM FUSION - $timestamp]" >> "$logfile"echo "Source: $variable1/*.$ext1" >> "$logfile"echo "Output: $outputfile" >> "$logfile"echo "Weights: exposure=$exposure_weight, saturation=$saturation_weight, contrast=$contrast_weight" >> "$logfile"echo "Hard Mask: $hmasklog" >> "$logfile"save_last_settings "$variable1" "$ext1" "$exposure_weight" "$saturation_weight" "$contrast_weight" "$hmasklog"read -rp "View output image? (y/n): " viewimg[[ "$viewimg" =~ ^[Yy]$ ]] && xdg-open "$outputfile" >/dev/null 2>&1 &;;  "3")print_header "REPEAT LAST FUSION"load_last_settingsecho "Last settings:"echo "Source folder: $last_dir"echo "Extension: $last_ext"echo "Weights: exposure=$last_exposure, saturation=$last_saturation, contrast=$last_contrast"echo "Hard Mask: $hmasklog"# Vraag opnieuw hardmask interactiefask_hardmasktimestamp=$(date +"%Y%m%d_%H%M%S")outputfile="$last_dir/output_$timestamp.$last_ext"mapfile -t files < <(find "$last_dir" -maxdepth 1 -type f -iname "*.$last_ext" | sort)run_enfuse "$outputfile" "${files[@]}"echo -e "\n[REPEATED FUSION - $timestamp]" >> "$logfile"echo "Source: $last_dir/*.$last_ext" >> "$logfile"echo "Output: $outputfile" >> "$logfile"echo "Weights: exposure=$last_exposure, saturation=$last_saturation, contrast=$last_contrast" >> "$logfile"echo "Hard Mask: $hmasklog" >> "$logfile"save_last_settings "$last_dir" "$last_ext" "$last_exposure" "$last_saturation" "$last_contrast" "$hmasklog"read -rp "View output image? (y/n): " viewimg[[ "$viewimg" =~ ^[Yy]$ ]] && xdg-open "$outputfile" >/dev/null 2>&1 &;;  "Q"|"q")echo "Bye!"exit 0;;  *)echo "Invalid option. Exiting."exit 1;;esac

I don’t have any Sponsoring Companies, Patreon support, or Follower Donations.

I don’t drink Coffee, well, I do … but not the financial form you sometimes find on other websites, like ‘buy me a coffee’ 😊

However, what I truly need to keep going is Motivation, and the best part is, it won’t cost you a thing. You can offer it for free – just hit the Like button and Subscribe !



Discover more from Open Source Photography

Subscribe to get the latest posts sent to your email.

Type your email…

Enjoyed this post? Put your thoughts into words! Or just give a thumbs-up in the comment box!

Website Powered by WordPress.com.

Up ↑

Discover more from Open Source Photography

Subscribe now to keep reading and get access to the full archive.

Type your email…

Continue reading