| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- // Copyright 2012 Harry de Boer. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package ocr
- import (
- "image"
- )
- // Threshold performs thresholding on a grayscale image.
- //
- // All color values greater than threshold are set to fgColor, the other to bgColor.
- func Threshold(m *image.Gray, threshold, bgColor, fgColor uint8) {
- count := len(m.Pix)
- for i := 0; i < count; i++ {
- if m.Pix[i] > threshold {
- m.Pix[i] = fgColor
- } else {
- m.Pix[i] = bgColor
- }
- }
- }
- // Otsu determines a threshold value using Otsu's method on grayscale images.
- //
- // "A threshold selection method from gray-level histograms" (Otsu, 1979).
- func Otsu(m *image.Gray) uint8 {
- hist := Histogram(m)
- sum := 0
- for i, v := range hist {
- sum += i * v
- }
- wB, wF := 0, len(m.Pix)
- sumB, sumF := 0, sum
- maxVariance := 0.0
- threshold := uint8(0)
- for t := 0; t < 256; t++ {
- wB += hist[t]
- wF -= hist[t]
- if wB == 0 {
- continue
- }
- if wF == 0 {
- return threshold
- }
- sumB += t * hist[t]
- sumF = sum - sumB
- mB := float64(sumB) / float64(wB)
- mF := float64(sumF) / float64(wF)
- betweenVariance := float64(wB*wF) * (mB - mF) * (mB - mF)
- if betweenVariance > maxVariance {
- maxVariance = betweenVariance
- threshold = uint8(t)
- }
- }
- return threshold
- }
- // Histogram creates a histogram of a grayscale image.
- func Histogram(m *image.Gray) []int {
- hist := make([]int, 256)
- count := len(m.Pix)
- for i := 0; i < count; i++ {
- hist[m.Pix[i]]++
- }
- return hist
- }
|