Created
July 30, 2025 00:17
-
-
Save nicjansma/e67f4d134c3c4420e51246fe7a50837c to your computer and use it in GitHub Desktop.
compare-images-in-directories.sh - finds matching images in two sets of directories under a DSSIM similarity threshold
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Enhanced version that can use dssim, ssim, or ImageMagick | |
| # Usage: ./enhanced_compare.sh <directory1> <directory2> [threshold] [method] | |
| DEFAULT_THRESHOLD=0.01 | |
| DEFAULT_METHOD="auto" | |
| usage() { | |
| echo "Usage: $0 <directory1> <directory2> [threshold] [method]" | |
| echo "Methods: auto, dssim, imagemagick, perceptual" | |
| echo " auto: automatically choose best available method" | |
| echo " dssim: use dssim tool (most accurate)" | |
| echo " imagemagick: use ImageMagick compare" | |
| echo " perceptual: use perceptual hashing" | |
| exit 1 | |
| } | |
| # Function to check available similarity tools | |
| detect_similarity_tools() { | |
| local available_tools=() | |
| if command -v dssim &> /dev/null; then | |
| available_tools+=("dssim") | |
| fi | |
| if command -v compare &> /dev/null; then | |
| available_tools+=("imagemagick") | |
| fi | |
| # Perceptual hashing is always available if ImageMagick is present | |
| if command -v convert &> /dev/null; then | |
| available_tools+=("perceptual") | |
| fi | |
| echo "${available_tools[@]}" | |
| } | |
| # Function to use dssim for comparison | |
| compare_with_dssim() { | |
| local img1="$1" | |
| local img2="$2" | |
| # dssim returns 0 for identical images, higher values for more different images | |
| local result=$(dssim "$img1" "$img2" 2>/dev/null | awk '{print $1}') | |
| echo "$result" | |
| } | |
| # Parse arguments | |
| DIR1="$1" | |
| DIR2="$2" | |
| THRESHOLD="${3:-$DEFAULT_THRESHOLD}" | |
| METHOD="${4:-$DEFAULT_METHOD}" | |
| if [ $# -lt 2 ]; then | |
| usage | |
| fi | |
| # Detect available tools | |
| available_tools=($(detect_similarity_tools)) | |
| if [ ${#available_tools[@]} -eq 0 ]; then | |
| echo "Error: No image comparison tools available." | |
| echo "Please install one of: dssim, imagemagick" | |
| exit 1 | |
| fi | |
| # Choose method | |
| if [ "$METHOD" = "auto" ]; then | |
| if [[ " ${available_tools[@]} " =~ " dssim " ]]; then | |
| METHOD="dssim" | |
| elif [[ " ${available_tools[@]} " =~ " imagemagick " ]]; then | |
| METHOD="imagemagick" | |
| else | |
| METHOD="perceptual" | |
| fi | |
| fi | |
| echo "Using method: $METHOD" | |
| echo "Available tools: ${available_tools[*]}" | |
| echo "Comparing PNG images using perceptual similarity:" | |
| echo " Directory 1: $DIR1" | |
| echo " Directory 2: $DIR2" | |
| echo " Similarity threshold: $THRESHOLD (lower = more strict)" | |
| echo | |
| # Create temporary directory | |
| TEMP_DIR=$(mktemp -d) | |
| cleanup() { | |
| rm -rf "$TEMP_DIR" | |
| } | |
| trap cleanup EXIT | |
| # Find all PNG files | |
| PNG_FILES1=($(find "$DIR1" -type f -iname "*.png" | sort)) | |
| PNG_FILES2=($(find "$DIR2" -type f -iname "*.png" | sort)) | |
| if [ ${#PNG_FILES1[@]} -eq 0 ]; then | |
| echo "No PNG files found in directory 1" | |
| exit 0 | |
| fi | |
| if [ ${#PNG_FILES2[@]} -eq 0 ]; then | |
| echo "No PNG files found in directory 2" | |
| exit 0 | |
| fi | |
| echo "Found ${#PNG_FILES1[@]} PNG files in directory 1" | |
| echo "Found ${#PNG_FILES2[@]} PNG files in directory 2" | |
| echo "Starting comparison..." | |
| echo | |
| MATCHES=0 | |
| COMPARISONS=0 | |
| LOWESTTHRESHOLD=1.0 | |
| LOWESTTHRESHOLDMATCH1="" | |
| LOWESTTHRESHOLDMATCH2="" | |
| # Compare each image from dir1 with each image from dir2 | |
| for img1 in "${PNG_FILES1[@]}"; do | |
| img1_name=$(basename "$img1") | |
| echo "Processing: $img1_name" | |
| for img2 in "${PNG_FILES2[@]}"; do | |
| img2_name=$(basename "$img2") | |
| ((COMPARISONS++)) | |
| # Show progress for large comparisons | |
| if [ $((COMPARISONS % 100)) -eq 0 ]; then | |
| echo " ...completed $COMPARISONS comparisons" | |
| fi | |
| # Compare images | |
| similarity=$(compare_with_dssim "$img1" "$img2") | |
| # Check if similarity is below threshold (more similar) | |
| if [ -n "$similarity" ]; then | |
| # Use bc for floating point comparison if available, otherwise use awk | |
| if command -v bc &> /dev/null; then | |
| is_similar=$(echo "$similarity <= $THRESHOLD" | bc) | |
| else | |
| is_similar=$(awk -v sim="$similarity" -v thr="$THRESHOLD" 'BEGIN {print (sim <= thr) ? 1 : 0}') | |
| fi | |
| is_less_lowest=$(echo "$similarity <= $LOWESTTHRESHOLD" | bc) | |
| if [ "$is_less_lowest" -eq 1 ]; then | |
| LOWESTTHRESHOLD=$similarity | |
| LOWESTTHRESHOLDMATCH1="$img1" | |
| LOWESTTHRESHOLDMATCH2="$img2" | |
| echo "New lowest threshold match found: $similarity" | |
| echo " File 1: $img1" | |
| echo " File 2: $img2" | |
| fi | |
| if [ "$is_similar" -eq 1 ]; then | |
| echo "" | |
| echo "*** SIMILAR IMAGES FOUND ***" | |
| echo " File 1: $img1" | |
| echo " File 2: $img2" | |
| echo " Similarity score: $similarity (threshold: $THRESHOLD)" | |
| # Additional info | |
| info1=$(identify -format "%wx%h %b" "$img1" 2>/dev/null) | |
| info2=$(identify -format "%wx%h %b" "$img2" 2>/dev/null) | |
| echo " File 1 info: $info1" | |
| echo " File 2 info: $info2" | |
| echo "" | |
| ((MATCHES++)) | |
| fi | |
| fi | |
| done | |
| done | |
| echo "" | |
| echo "=== SUMMARY ===" | |
| echo "Total comparisons performed: $COMPARISONS" | |
| echo "Similar image pairs found: $MATCHES" | |
| echo "Similarity threshold used: $THRESHOLD" | |
| echo "PNG files in directory 1: ${#PNG_FILES1[@]}" | |
| echo "PNG files in directory 2: ${#PNG_FILES2[@]}" | |
| echo "Lowest threshold match found: $LOWESTTHRESHOLD" | |
| echo " File 1: $LOWESTTHRESHOLDMATCH1" | |
| echo " File 2: $LOWESTTHRESHOLDMATCH2" | |
| if [ $MATCHES -gt 0 ]; then | |
| echo "" | |
| echo "Similar images were found!" | |
| exit 0 | |
| else | |
| echo "" | |
| echo "No similar images found with the current threshold." | |
| echo "Try increasing the threshold (e.g., 0.1) for more lenient matching." | |
| exit 1 | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment