Skip to content

Instantly share code, notes, and snippets.

@samuel
Last active September 27, 2017 20:36
Show Gist options
  • Save samuel/00f09385ed409381aa6930eb6150d3d7 to your computer and use it in GitHub Desktop.
Save samuel/00f09385ed409381aa6930eb6150d3d7 to your computer and use it in GitHub Desktop.
// Otsu is "A Threshold Selection Method from Gray-Level Histograms"
// <http://ieeexplore.ieee.org/ielx5/21/4310064/04310076.pdf?tp=&arnumber=4310076&isnumber=4310064>
func Otsu(hist []int, start, end int) int {
if end == 0 {
end = len(hist)
} else if end >= len(hist) {
end = len(hist) - 1
}
if start < 0 {
start = 0
} else if start >= len(hist) {
start = len(hist) - 1
}
if start >= end {
return (start + end) / 2
}
total := 0
sum := 0
for t := start; t < end; t++ {
n := hist[t]
total += n
sum += t * n
}
sumB := 0
wB := 0
varMax := 0.0
threshold := 0
for t := start; t < end; t++ {
wB += hist[t]
if wB == 0 {
continue
}
wF := total - wB
if wF == 0 {
break
}
sumB += t * hist[t]
sumF := sum - sumB
varBetween := float64(sumB*sumB)/float64(wB) + float64(sumF*sumF)/float64(wF)
if varBetween > varMax {
varMax = varBetween
threshold = t
}
}
return threshold
}
func HistogramLuminance(img image.Image) Histogram {
bounds := img.Bounds()
hist := make([]int, 256)
if m, ok := img.(*image.RGBA); ok {
w := bounds.Dx()
h := bounds.Dy()
for y, o := 0, 0; y < h; y, o = y+1, o+m.Stride {
for x, o2 := 0, o; x < w; x, o2 = x+1, o2+4 {
r := m.Pix[o2+0]
g := m.Pix[o2+1]
b := m.Pix[o2+2]
max := r
min := r
if g > max {
max = g
}
if g < min {
min = g
}
if b > max {
max = b
}
if b < min {
min = b
}
hist[(int(max)+int(min))/2]++
}
}
} else {
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
color := img.At(x, y)
r, g, b, _ := color.RGBA()
max := r
min := r
if g > max {
max = g
}
if g < min {
min = g
}
if b > max {
max = b
}
if b < min {
min = b
}
hist[((int(max)+int(min))/2)>>8]++
}
}
}
return hist
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment