#!/bin/bash # # Developed by Fred Weinhaus 8/30/2012 .......... revised 11/3/2015 # # ------------------------------------------------------------------------------ # # Licensing: # # Copyright © Fred Weinhaus # # My scripts are available free of charge for non-commercial use, ONLY. # # For use of my scripts in commercial (for-profit) environments or # non-free applications, please contact me (Fred Weinhaus) for # licensing arrangements. My email address is fmw at alink dot net. # # If you: 1) redistribute, 2) incorporate any of these scripts into other # free applications or 3) reprogram them in another scripting language, # then you must contact me for permission, especially if the result might # be used in a commercial or for-profit environment. # # My scripts are also subject, in a subordinate manner, to the ImageMagick # license, which can be found at: http://www.imagemagick.org/script/license.php # # ------------------------------------------------------------------------------ # #### # # USAGE: ptilethresh [-p percentile] infile outfile # USAGE: ptilethresh [-h or -help] # # OPTIONS: # # -p percentile percentile on cumulative histogram for desired threshold; # 0<=float<=100; default=50 # ### # # NAME: PTILETHRESH # # PURPOSE: To automatically thresholds an image to binary (b/w) format # at a specified percentile on the cumulative histogram. # # DESCRIPTION: PTILETHRESH automatically thresholds an image to binary # (b/w) format at a specified percentile on the cumulative histogram. When # the percentile is 50%, this technique is also known as balanced thresholding. # # OPTIONS: # # -p percentile ... PERCENTILE is the desired threshold point on the cumulative # histogram. Values are floats between 0 and 100. The default=50. # # NOTE: It is highly recommended that the output not be specified # as a JPG image as that will cause compression and potentially a # non-binary (i.e. a graylevel) result. GIF is the recommended # output format. # # REFERENCES: # http://en.wikipedia.org/wiki/Balanced_histogram_thresholding # http://www.pvv.org/~perchrh/papers/datasyn/paper2/report.pdf # # CAVEAT: No guarantee that this script will work on all platforms, # nor that trapping of inconsistent parameters is complete and # foolproof. Use At Your Own Risk. # ###### # # set default values percentile=50 # set directory for temporary files dir="." # suggestions are dir="." or dir="/tmp" # set up functions to report Usage and Usage with Description PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path PROGDIR=`dirname $PROGNAME` # extract directory of program PROGNAME=`basename $PROGNAME` # base name of program usage1() { echo >&2 "" echo >&2 "$PROGNAME:" "$@" sed >&2 -e '1,/^####/d; /^###/g; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME" } usage2() { echo >&2 "" echo >&2 "$PROGNAME:" "$@" sed >&2 -e '1,/^####/d; /^######/g; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME" } # function to report error messages errMsg() { echo "" echo $1 echo "" usage1 exit 1 } # function to test for minus at start of value of second part of option 1 or 2 checkMinus() { test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise [ $test -eq 1 ] && errMsg "$errorMsg" } # test for correct number of arguments and get values if [ $# -eq 0 ] then # help information echo "" usage2 exit 0 elif [ $# -gt 4 ] then errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---" else while [ $# -gt 0 ] do # get parameter values case "$1" in -h|-help) # help information echo "" usage2 exit 0 ;; -p) # get percentile shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID PERCENTILE SPECIFICATION ---" checkMinus "$1" percentile=`expr "$1" : '\([.0-9]*\)'` [ "$percentile" = "" ] && errMsg "--- PERCENTILE=$percentile MUST BE A NON-NEGATIVE FLOAT ---" testA=`echo "$percentile < 0" | bc` testB=`echo "$percentile > 100" | bc` [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- PERCENTILE=$percentile MUST BE A FLOAT BETWEEN 0 AND 100 ---" ;; -) # STDIN and end of arguments break ;; -*) # any other - argument errMsg "--- UNKNOWN OPTION ---" ;; *) # end of arguments break ;; esac shift # next option done # # get infile and outfile infile="$1" outfile="$2" fi # test that infile provided [ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED" # test that outfile provided [ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED" tmpA1="$dir/ptilethresh_1_$$.mpc" tmpA2="$dir/ptilethresh_1_$$.cache" trap "rm -f $tmpA1 $tmpA2 exit 0;" 0 trap "rm -f $tmpA1 $tmpA2; exit 1" 1 2 3 15 # get im_version im_version=`convert -list configure | \ sed '/^LIB_VERSION_NUMBER /!d; s//,/; s/,/,0/g; s/,0*\([0-9][0-9]\)/\1/g' | head -n 1` # colorspace RGB and sRGB swapped between 6.7.5.5 and 6.7.6.7 # though probably not resolved until the latter # then -colorspace gray changed to linear between 6.7.6.7 and 6.7.8.2 # then -separate converted to linear gray channels between 6.7.6.7 and 6.7.8.2, # though probably not resolved until the latter # so -colorspace HSL/HSB -separate and -colorspace gray became linear # but we need to use -set colorspace RGB before using them at appropriate times # so that results stay as in original script # The following was determined from various version tests using ptilethresh. # with IM 6.7.4.10, 6.7.6.10, 6.7.9.10 if [ "$im_version" -lt "06070607" -o "$im_version" -gt "06070707" ]; then setcspace="-set colorspace RGB" else setcspace="" fi # no need for setcspace for grayscale or channels after 6.8.5.4 if [ "$im_version" -gt "06080504" ]; then setcspace="" fi if convert -quiet "$infile" +repage "$tmpA1" then : ' do nothing ' else errMsg "--- FILE $infile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAG ZERO SIZE ---" fi bpt=$percentile wpt=`convert xc: -format "%[fx:100-$bpt]" info:` # process image convert $tmpA1 $setcspace -colorspace gray -linear-stretch $bpt%,$wpt% "$outfile" exit 0