diff -bruw gimp-2.3.7-orig/app/base/gimphistogram.c gimp-2.3.7/app/base/gimphistogram.c
--- gimp-2.3.7-orig/app/base/gimphistogram.c	2006-01-23 15:45:59.000000000 +0100
+++ gimp-2.3.7/app/base/gimphistogram.c	2006-04-04 09:41:42.781250000 +0200
@@ -344,6 +344,106 @@
   return -1;
 }
 
+/* 
+   adapted from GNU ocrad 0.14 : page_image_io.cc : otsu_th
+
+   N. Otsu, "A threshold selection method from gray-level histograms," 
+   IEEE Trans. Systems, Man, and Cybernetics, vol. 9, no. 1, pp. 62-66, 1979.
+
+*/
+gdouble
+gimp_histogram_get_threshold(GimpHistogram         *histogram,
+			     GimpHistogramChannel  channel,
+			     gint                  start,
+			     gint                  end)
+{
+  gint     i;
+  gint     maxval;
+  gdouble* hist = NULL;
+  gdouble* chist = NULL;
+  gdouble* cmom = NULL;
+  gdouble  hist_max = 0.0;
+  gdouble  chist_max = 0.0;
+  gdouble  cmom_max = 0.0;
+  gdouble  bvar_max = 0.0;
+  gint     threshold = 127;
+
+  g_return_val_if_fail (histogram != NULL, -1);
+
+  /*  the gray alpha channel is in slot 1  */
+  if (histogram->n_channels == 3 && channel == GIMP_HISTOGRAM_ALPHA)
+    channel = 1;
+  
+  if (! histogram->values[0] ||
+      start > end ||
+      (channel == GIMP_HISTOGRAM_RGB && histogram->n_channels < 4) ||
+      (channel != GIMP_HISTOGRAM_RGB && channel >= histogram->n_channels))
+    return 0;
+  
+  start = CLAMP (start, 0, 255);
+  end = CLAMP (end, 0, 255);
+
+  maxval = end-start;
+
+  hist  = g_new(gdouble, maxval+1);
+  chist = g_new(gdouble, maxval+1);
+  cmom  = g_new(gdouble, maxval+1);
+  
+  if (channel == GIMP_HISTOGRAM_RGB) 
+    for (i = start; i <= end; i++)
+      {
+	hist[i - start] = 
+	  (HISTOGRAM_VALUE (GIMP_HISTOGRAM_RED,   i) +
+	   HISTOGRAM_VALUE (GIMP_HISTOGRAM_GREEN, i) +
+	   HISTOGRAM_VALUE (GIMP_HISTOGRAM_BLUE,  i));
+      }
+  else
+    for (i = start; i <= end; i++)
+      {
+	hist[i - start] = HISTOGRAM_VALUE (channel, i);
+      }
+
+  hist_max = hist[0];
+  chist[0] = hist[0];
+  cmom[0] = 0 * chist[0];
+
+  for (i = 1; i <= maxval; i++)
+    {
+      if (hist[i] > hist_max) 
+	hist_max = hist[i];
+
+      chist[i] = chist[i-1] + hist[i];
+      cmom[i] = cmom[i-1] + i * hist[i];
+    }
+  
+  chist_max = chist[maxval];
+  cmom_max = cmom[maxval];
+
+  bvar_max = 0;
+  for( i = 0; i < maxval; ++i )
+    if( chist[i] > 0 && chist[i] < chist_max )
+      {
+	double bvar;
+	bvar = (double)cmom[i] / chist[i];
+	bvar -= ( cmom_max - cmom[i] ) / ( chist_max - chist[i] );
+	bvar *= bvar;
+	bvar *= chist[i];
+	bvar *= ( chist_max - chist[i] );
+	if( bvar > bvar_max ) 
+	  { 
+	    bvar_max = bvar; 
+	    threshold = start + i; 
+	  }
+      }
+
+  g_free(cmom);
+  g_free(chist);
+  g_free(hist);
+
+  return threshold;
+}
+
+
 gdouble
 gimp_histogram_get_std_dev (GimpHistogram        *histogram,
 			    GimpHistogramChannel  channel,
diff -bruw gimp-2.3.7-orig/app/base/gimphistogram.h gimp-2.3.7/app/base/gimphistogram.h
--- gimp-2.3.7-orig/app/base/gimphistogram.h	2006-01-23 15:45:59.000000000 +0100
+++ gimp-2.3.7/app/base/gimphistogram.h	2006-04-04 09:42:29.093750000 +0200
@@ -47,6 +47,10 @@
                                             GimpHistogramChannel  channel,
                                             gint                  start,
                                             gint                  end);
+gdouble         gimp_histogram_get_threshold(GimpHistogram         *histogram,
+					     GimpHistogramChannel  channel,
+					     gint                  start,
+					     gint                  end);
 gdouble         gimp_histogram_get_value   (GimpHistogram        *histogram,
                                             GimpHistogramChannel  channel,
                                             gint                  bin);
diff -bruw gimp-2.3.7-orig/app/pdb/color_cmds.c gimp-2.3.7/app/pdb/color_cmds.c
--- gimp-2.3.7-orig/app/pdb/color_cmds.c	2006-01-23 15:46:04.000000000 +0100
+++ gimp-2.3.7/app/pdb/color_cmds.c	2006-04-04 09:43:11.531250000 +0200
@@ -1255,6 +1255,7 @@
   gdouble pixels = 0;
   gdouble count = 0;
   gdouble percentile = 0;
+  gdouble threshold = 0;
 
   drawable = (GimpDrawable *) gimp_item_get_by_ID (gimp, args[0].value.pdb_int);
   if (! (GIMP_IS_DRAWABLE (drawable) && ! gimp_item_is_removed (GIMP_ITEM (drawable))))
@@ -1297,6 +1298,8 @@
           pixels     = gimp_histogram_get_count (histogram, channel, 0, 255);
           count      = gimp_histogram_get_count (histogram, channel,
                                                  start_range, end_range);
+	  threshold  = gimp_histogram_get_threshold (histogram, channel, 
+						     start_range, end_range);
           percentile = count / pixels;
 
           gimp_histogram_free (histogram);
@@ -1313,6 +1316,7 @@
       return_args[4].value.pdb_float = pixels;
       return_args[5].value.pdb_float = count;
       return_args[6].value.pdb_float = percentile;
+      return_args[7].value.pdb_float = threshold;
     }
 
   return return_args;
@@ -1373,6 +1377,11 @@
     GIMP_PDB_FLOAT,
     "percentile",
     "Percentile that range falls under"
+  },
+  {
+    GIMP_PDB_FLOAT,
+    "threshold",
+    "Optimal binarization threshold"
   }
 };
 
diff -bruw gimp-2.3.7-orig/app/tools/gimpthresholdtool.c gimp-2.3.7/app/tools/gimpthresholdtool.c
--- gimp-2.3.7-orig/app/tools/gimpthresholdtool.c	2005-12-27 21:47:36.000000000 +0100
+++ gimp-2.3.7/app/tools/gimpthresholdtool.c	2006-04-04 09:43:39.515625000 +0200
@@ -169,6 +169,10 @@
 
   gimp_drawable_calculate_histogram (drawable, t_tool->hist);
 
+  t_tool->threshold->low_threshold = gimp_histogram_get_threshold(t_tool->hist,
+				t_tool->threshold->color?GIMP_HISTOGRAM_RGB:GIMP_HISTOGRAM_VALUE,
+				0, 255);
+
   g_signal_handlers_block_by_func (t_tool->histogram_box->view,
                                    gimp_threshold_tool_histogram_range,
                                    t_tool);
