Created
October 31, 2017 03:25
-
-
Save athurg/d59d6c8fa379f39ab7c2afc697def048 to your computer and use it in GitHub Desktop.
Golang版本的图像二值化分析范例
This file contains 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" | |
"os" | |
"image" | |
"image/jpeg" | |
"image/draw" | |
) | |
func main(){ | |
for i:=1; i<=5; i++ { | |
fromFile := fmt.Sprintf("%d.jpg", i) | |
toFile := fmt.Sprintf("gray_%d.jpg", i) | |
convertJpegToGray(fromFile, toFile) | |
} | |
} | |
func createGrayImageFromJpegFile(file string) (image.Image, error) { | |
f, err := os.Open(file) | |
if err!=nil { | |
return nil, err | |
} | |
defer f.Close() | |
colorImage, err := jpeg.Decode(f) | |
if err!=nil { | |
return nil, err | |
} | |
grayImage := image.NewGray(colorImage.Bounds()) | |
draw.Draw(grayImage, colorImage.Bounds(), colorImage, colorImage.Bounds().Min, draw.Src) | |
return grayImage,nil | |
} | |
func convertJpegToGray(fromFile,toFile string) error { | |
grayImage, err := createGrayImageFromJpegFile(fromFile) | |
if err !=nil { | |
return err | |
} | |
w, err := os.Create(toFile) | |
if err!=nil { | |
return err | |
} | |
defer w.Close() | |
return jpeg.Encode(w, grayImage, nil) //保存文件 | |
//统计 | |
//width := size.Dx() | |
//height := size.Dy() | |
//zft := make([]int, 256)//用于保存每个像素的数量,注意这里用了int类型,在某些图像上可能会溢出。 | |
//var idx int | |
//for i := 0; i < width; i++ { | |
// for j := 0; j < height; j++ { | |
// idx = i*height + j | |
// zft[pic.Pix[idx]]++ //image对像有一个Pix属性,它是一个slice,里面保存的是所有像素的数据。 | |
// } | |
//} | |
//灰度化结果 | |
//fz := uint8(GetOSTUThreshold(zft)) | |
//for fz := uint8(0); fz<255; fz++ { | |
//do(pic, fz) | |
//} | |
} | |
//二值化 | |
func toValued(oriPic *image.Gray, fz uint8) { | |
pic := new(image.Gray) | |
pic.Stride = oriPic.Stride | |
pic.Rect = oriPic.Rect | |
pic.Pix = make([]uint8, len(oriPic.Pix)) | |
copy(pic.Pix, oriPic.Pix) | |
zeroCount := 0 | |
for i := 0; i < len(pic.Pix); i++ { | |
//以下是内外区间法,像素差5以内算同一像素 | |
if (pic.Pix[i] - fz) > 5 { | |
pic.Pix[i] = 255 | |
} else { | |
zeroCount += 1 | |
pic.Pix[i] = 0 | |
} | |
//以下是区间法,大于fz为白,否则为黑 | |
//if pic.Pix[i] > fz { | |
// pic.Pix[i] = 255 | |
//} else { | |
// pic.Pix[i] = 0 | |
//} | |
} | |
//只保留白色为1%~2%的图像 | |
r := float32(zeroCount)/float32(len(pic.Pix)) | |
if r > 0.02 || r < 0.01 { | |
return | |
} | |
w, _ := os.Create(fmt.Sprintf("result/black_white%03d_%.0f.jpg", fz, 100 * float32(zeroCount)/float32(len(pic.Pix)))) | |
defer w.Close() | |
jpeg.Encode(w, pic, nil) | |
} | |
//直方图获取二值化中间值 | |
func GetOSTUThreshold(HistGram []int) int { | |
var Y, Amount int | |
var PixelBack, PixelFore, PixelIntegralBack, PixelIntegralFore, PixelIntegral int | |
var OmegaBack, OmegaFore, MicroBack, MicroFore, SigmaB, Sigma float64 // 类间方差; | |
var MinValue, MaxValue int | |
var Threshold int = 0 | |
for MinValue = 0; MinValue < 256 && HistGram[MinValue] == 0; MinValue++ { | |
} | |
for MaxValue = 255; MaxValue > MinValue && HistGram[MinValue] == 0; MaxValue-- { | |
} | |
if MaxValue == MinValue { | |
return MaxValue // 图像中只有一个颜色 | |
} | |
if MinValue+1 == MaxValue { | |
return MinValue // 图像中只有二个颜色 | |
} | |
for Y = MinValue; Y <= MaxValue; Y++ { | |
Amount += HistGram[Y] // 像素总数 | |
} | |
PixelIntegral = 0 | |
for Y = MinValue; Y <= MaxValue; Y++ { | |
PixelIntegral += HistGram[Y] * Y | |
} | |
SigmaB = -1 | |
for Y = MinValue; Y < MaxValue; Y++ { | |
PixelBack = PixelBack + HistGram[Y] | |
PixelFore = Amount - PixelBack | |
OmegaBack = float64(PixelBack) / float64(Amount) | |
OmegaFore = float64(PixelFore) / float64(Amount) | |
PixelIntegralBack += HistGram[Y] * Y | |
PixelIntegralFore = PixelIntegral - PixelIntegralBack | |
MicroBack = float64(PixelIntegralBack) / float64(PixelBack) | |
MicroFore = float64(PixelIntegralFore) / float64(PixelFore) | |
Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore) | |
if Sigma > SigmaB { | |
SigmaB = Sigma | |
Threshold = Y | |
} | |
} | |
return Threshold | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment