function graythresh(in_img) g=convert(Array,in_img); step=65536; #get histogram values e,counts=hist(g[:],linrange(minfinite(g[:]),maxfinite(g[:]),step)) im_len=length(in_img); tot_sum=0; for t=1:step-1 tot_sum=tot_sum+t*counts[t]; end sumB = 0; wB = 0; wF = 0; varMax = 0; threshold = 0; for t = 1:step-1 wB=wB + counts[t]; #weight background wF=im_len - wB; #weight foreground sumB=sumB+t*counts[t]; mB = sumB / wB; #Mean Background mF = (tot_sum - sumB) / wF; # Mean Foreground varBetween = wB * wF * (mB - mF)^2; # Check if new maximum found if (varBetween > varMax) varMax = varBetween; threshold = t; end end return e[threshold]end
1. Initialize thresh to the mean value of the image pixels
2. Compute the mean of the pixels that are larger than thresh, mplus, and smaller than thresh, mminus.
3. Set thresh to the mean of mminus and mplus, and then loop back to 1. Iterate to a fixed point.
You can implement this version without allocating any extra data structures, so it may well be much faster.
Sorry I don't have any references here. Writing from a phone.
Also, yes, defined edges would be much more sensible. Will give it a try.