Created
June 6, 2019 15:56
-
-
Save mAlishera/a705b57b91eaf1db9930960962f1381f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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