Skip to content

Instantly share code, notes, and snippets.

@mAlishera
Created June 6, 2019 15:56
Show Gist options
  • Save mAlishera/a705b57b91eaf1db9930960962f1381f to your computer and use it in GitHub Desktop.
Save mAlishera/a705b57b91eaf1db9930960962f1381f to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"image"
"image/png"
"log"
"os"
"github.com/Arafatk/glot"
"gocv.io/x/gocv"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Enter .jpeg file path for image")
return
}
filename := os.Args[1]
src1 := gocv.IMRead(filename, gocv.IMReadGrayScale)
if src1.Empty() {
fmt.Println("Error reading image from: %v", filename)
return
}
var (
src = loadImage("123.png")
bounds = src.Bounds()
gray = image.NewGray(bounds)
)
for x := 0; x < bounds.Max.X; x++ {
for y := 0; y < bounds.Max.Y; y++ {
var rgba = src.At(x, y)
gray.Set(x, y, rgba)
}
}
threshold := Otsu(gray)
Threshold(gray, threshold, 0, 255)
saveImage("otsu.png", gray)
// сравнить полученные результаты ручной реализации отсу и gocv ниже
dest1 := gocv.NewMat()
defer dest1.Close()
gocv.Threshold(src1, &dest1, 128, 225, gocv.ThresholdOtsu)
}
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
}
}
}
func Otsu(m *image.Gray) uint8 {
hist := Histogram(m)
histPlot(hist)
// log.Println("histogram ---- %v \n", hist)
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 {
log.Printf("otsu threshold1 ---- %v \n", threshold)
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)
}
}
log.Printf("otsu threshold2 ---- %v \n", threshold)
return threshold
}
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
}
func histPlot(hist []int) {
dimensions := 2
persist := false
debug := false
plot, _ := glot.NewPlot(dimensions, persist, debug)
pointGroupName := "Simple Circles"
style := "points"
plot.AddPointGroup(pointGroupName, style, hist)
plot.SetTitle("Example Plot")
plot.SetXLabel("X-Axis")
plot.SetYLabel("Y-Axis")
plot.SetXrange(0, 255)
plot.SetYrange(0, 25000)
plot.SavePlot("2.png")
}
func loadImage(filename string) image.Image {
f, err := os.Open(filename)
if err != nil {
log.Fatalf("os.Open failed: %v", err)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
log.Fatalf("image.Decode failed: %v", err)
}
return img
}
func saveImage(filename string, img image.Image) {
f, err := os.Create(filename)
if err != nil {
log.Fatalf("os.Create failed: %v", err)
}
defer f.Close()
err = png.Encode(f, img)
if err != nil {
log.Fatalf("png.Encode failed: %v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment