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 }