GNOME Bugzilla – Bug 679622
Possible wrong Otsu (auto) threshold value for binarisation
Last modified: 2018-05-24 13:15:45 UTC
Created attachment 218327 [details] Picture-test to compute Otsu Thresholding Hello, Gimp use the Otsu method to compute binarization threshold. If you compute the auto-threshold for the attached picture with Gimp 2.8 (menu "Colors / Threshold - Auto" or "Couleurs / Seuil - Auto in french), Gimp find 185. If you compute the auto-threshold for the attached picture with ImageJ (menu "Image / Adjust / Threshold - Otsu"), ImageJ find 195. I think these two threshold (195 and 185) can be improved. + Gimp return the threshold "s1" for maximum (GREATER) histogram standard variation. + ImageJ return the threshold "s2" for maximum (GREATER OR EQUAL) histogram standard variation. I think you must compute s1 and s2 and return s = ( s1 + s2 ) / 2 Otsu threshold must be ( 185 + 195 ) / 2 = 190 for the attached picture. Look at the histogram, it is the middle... (In most cases, s1 = s2 = s...) Best regards, Vincent
Read "standard deviation" ("écart-type au carré" or "variance" in french) instead "standard variation", sorry...
What is "Otsu"? Are you using 3rd party plugins?
> Michael Natterer > What is "Otsu"? Are you using 3rd party plugins? I have read that Otsu was the algorithm used by Gimp to compute binary threshold. This is not a plugin ! Look here for example : http://en.wikipedia.org/wiki/Otsu%27s_method (I suggest this improvement for this Wikipedia page and for ImageJ too)
I see. Needs to be checked then.
Hello, I'm looking in Gimp 2.8.8 source code and I think I've find the Otsu threshold fonction and a solution : I'v opened "\gimp-2.8.8\app\base\gimphistogram.c" file. At the end of the function "gdouble gimp_histogram_get_threshold ( ...", line 404, you can read : ... for (i = 0; i < maxval; ++i) if (chist[i] > 0 && chist[i] < chist_max) { gdouble bvar; bvar = (gdouble) 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; } } return threshold; } I suggest this following improvement : gint threshold; gint threshold_begin = 127; gint threshold_end = 127; ... bvar = (gdouble) 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) { threshold_end = start + i; if (bvar > bvar_max) { threshold_begin = start + i; { bvar_max = bvar; } } threshold = ( threshold_begin + threshold_end ) / 2; return threshold; }// gimp_histogram_get_threshold
Can you please turn this into a patch?
(In reply to comment #6) > Can you please turn this into a patch? How can I do a "patch" ? Do you have a tutorial or some indications for this, please ?
I've find the official tutorial. I'll try to do it. Thank's. http://www.gimp.org/bugs/howtos/submit-patch.html
If you are using git, you simply edit the file and say git diff >foo.patch if you use a tarball, you keep the .c file's original around, edit the file and say diff -u original.c modified.c >foo.patch
I've do a patch with Git and your advice. "git diff" produce the following text-file between the two "------------" lines. ------------------------------------------------------------------------- diff --git a/app/core/gimphistogram.c b/app/core/gimphistogram.c index 5143e0e..5913805 100644 --- a/app/core/gimphistogram.c +++ b/app/core/gimphistogram.c @@ -781,7 +781,9 @@ gimp_histogram_get_threshold (GimpHistogram *histogram, gdouble chist_max = 0.0; gdouble cmom_max = 0.0; gdouble bvar_max = 0.0; - gint threshold = 127; + gint threshold; + gint threshold_begin = 127; + gint threshold_end = 127; g_return_val_if_fail (GIMP_IS_HISTOGRAM (histogram), -1); @@ -848,14 +850,18 @@ gimp_histogram_get_threshold (GimpHistogram *histogram, bvar *= chist[i]; bvar *= chist_max - chist[i]; - if (bvar > bvar_max) + if (bvar >= bvar_max) { + threshold_end = start + i; + if (bvar > bvar_max) + { + threshold_begin = start + i; + } bvar_max = bvar; - threshold = start + i; } } } - + threshold = (threshold_begin + threshold_end) / 2; return threshold; } -------------------------------------------------------------------------
Can somebody with a clue please check if that patch makes sense?
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/412.