func TestAdjustGamma(t *testing.T) { src := image.NewGray(image.Rect(0, 0, 256, 1)) dst := image.NewGray(image.Rect(0, 0, 256, 1)) for i := 0; i <= 255; i++ { src.Pix[i] = uint8(i) } ag := Gamma(2.0) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] <= src.Pix[i] { t.Errorf("Gamma unexpected color") } } ag = Gamma(0.5) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] >= src.Pix[i] { t.Errorf("Gamma unexpected color") } } ag = Gamma(1.0) ag.Draw(dst, src, nil) for i := 100; i <= 150; i++ { if dst.Pix[i] != src.Pix[i] { t.Errorf("Gamma unexpected color") } } }
// DrawPicture . func DrawPicture(src image.Image, width int, height int) *image.Gray { rect := image.Rect(0, 0, width, height) img := image.NewGray(rect) rander := rander() for x := 0; x < width; x++ { for y := 0; y < height; y++ { var c color.Gray if IsBlack(src, x, y) { if y > 1 && IsNotBlack(src, x, y-1) { c = borderColor(rander) } else { c = insideColor(rander) } } else { c = outsideColor(rander) } x1, y1 := transformCurve(x, y, width, height) //c = color.Gray{c.Y + ScaledLuminanceAt(90, src, x, y)} img.Set(x1, y1, c) } } g := gift.New( //gift.GaussianBlur(2), ) img2 := image.NewGray(rect) g.Draw(img2, img) return img2 }
func MakeComputeMaker(src image.Image) *ComMaker { b := src.Bounds() sz := b.Size() width := sz.X / 8 height := sz.Y / 8 smallB := image.Rect(0, 0, width, height) cm := ComMaker{ width: sz.X / 8, height: sz.Y / 8, bound: smallB, } // Make Grey Img gSrc := image.NewGray(b) draw.Draw(gSrc, b, src, image.ZP, draw.Src) // Make Smaller gDst := image.NewGray(smallB) // Prep Conversion cfg, err := rez.PrepareConversion(gDst, gSrc) if err != nil { log.Println(err) return nil } cm.rConv, err = rez.NewConverter(cfg, rez.NewBilinearFilter()) if err != nil { log.Println(err) return nil } return &cm }
func TestEdgeOps(t *testing.T) { src, err := loadImage("../../testdata/gopher-100x150.png") if err != nil { t.Fatal(err) } for _, ot := range opTests { mag := image.NewGray(src.Bounds()) dir := image.NewGray(src.Bounds()) if err := ot.fn(mag, dir, src); err != nil { t.Fatalf("%s: %v", ot.name, err) } magFile := fmt.Sprintf("../../testdata/%s-mag.png", ot.name) cmp, err := loadImage(magFile) if err != nil { t.Fatalf("%s mag: %v", ot.name, err) } if err = imageWithinTolerance(mag, cmp, 0x101); err != nil { t.Fatalf("%s mag: %v", ot.name, err) } dirFile := fmt.Sprintf("../../testdata/%s-dir.png", ot.name) cmp, err = loadImage(dirFile) if err != nil { t.Fatalf("%s dir: %v", ot.name, err) } if err = imageWithinTolerance(dir, cmp, 0x101); err != nil { t.Fatalf("%s dir: %v", ot.name, err) } } }
func ToComputeImageManual(src image.Image) *image.Gray { fullBound := src.Bounds() m := image.NewGray(fullBound) draw.Draw(m, fullBound, src, image.ZP, draw.Src) // Smaller Image smallBound := image.Rect(0, 0, fullBound.Dx()/4, fullBound.Dy()/4) smallImg := image.NewGray(smallBound) swid := smallBound.Dx() wid := fullBound.Dx() for o, o2, omax := 0, 0, len(smallImg.Pix); o < omax; o, o2 = o+1, o2+4 { if (o % swid) == 0 { o2 = (o / swid) * wid * 4 } smallImg.Pix[o] = uint8((int(m.Pix[o2+0]) + int(m.Pix[o2+3]) + int(m.Pix[o2+2+wid]) + int(m.Pix[o2+1+wid*2]) + int(m.Pix[o2+0+wid*3]) + int(m.Pix[o2+3+wid*3])) / 6) } return smallImg }
func main() { flag.Parse() reader, err := os.Open(*in) if err != nil { log.Fatal(err) } defer reader.Close() i, _, err := image.Decode(reader) if err != nil { log.Fatal(err) } b := i.Bounds() m := image.NewGray(b) // monochrome draw.Draw(m, b, i, b.Min, draw.Src) o := image.NewGray(image.Rect(0, 0, 256, 256)) white := color.RGBA{0xff, 0xff, 0xff, 0xff} black := color.RGBA{0x00, 0x00, 0x00, 0xff} draw.Draw(o, o.Bounds(), &image.Uniform{white}, image.ZP, draw.Src) delta := []int{-16, -1, 1, 16} ud := []int{-6, 0, 0, 6} lr := []int{0, -6, 6, 0} for j := 0; j < 16; j++ { for i := 0; i < 16; i++ { cx := int(19 + 20.5333*float64(i)) cy := int(19 + 20.5333*float64(j)) s := []uint32{0, 0, 0, 0} best := uint32(50000) bestK := 0 for k := 0; k < 4; k++ { for sx := -1; sx < 2; sx++ { for sy := -1; sy < 2; sy++ { r, g, b, _ := m.At(cx+lr[k]+sx, cy+ud[k]+sy).RGBA() s[k] += (r + g + b) / 3 } } if k == 0 || s[k] < best { best = s[k] bestK = k } } src := 16*j + i dst := (src + delta[bestK] + 256) % 256 fmt.Printf("%v\n", dst) o.Set(src, dst, black) } } writer, err := os.Create(*out) if err != nil { log.Fatal(err) } png.Encode(writer, o) writer.Close() }
func TestRotate270(t *testing.T) { img0 := image.NewGray(image.Rect(-1, -1, 3, 1)) img0.Pix = []uint8{ 1, 2, 3, 4, 5, 6, 7, 8, } img1Exp := image.NewGray(image.Rect(0, 0, 2, 4)) img1Exp.Pix = []uint8{ 5, 1, 6, 2, 7, 3, 8, 4, } f := Rotate270() img1 := image.NewGray(f.Bounds(img0.Bounds())) f.Draw(img1, img0, nil) if img1.Bounds().Size() != img1Exp.Bounds().Size() { t.Errorf("expected %v got %v", img1Exp.Bounds().Size(), img1.Bounds().Size()) } if !comparePix(img1Exp.Pix, img1.Pix) { t.Errorf("expected %v got %v", img1Exp.Pix, img1.Pix) } }
// Canny detects and returns edges from the given image. // Each dst pixel is given one of three values: // 0xff: an edge // 0x80: possibly an edge // 0x00: not an edge func Canny(dst *image.Gray, src image.Image) error { if dst == nil { return errors.New("edge: dst is nil") } if src == nil { return errors.New("edge: src is nil") } b := src.Bounds() srcGray, ok := src.(*image.Gray) if !ok { srcGray = image.NewGray(b) draw.Draw(srcGray, b, src, b.Min, draw.Src) } if err := graphics.Blur(srcGray, srcGray, nil); err != nil { return err } mag, dir := image.NewGray(b), image.NewGray(b) if err := Sobel(mag, dir, srcGray); err != nil { return err } // Non-maximum supression. for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { d := dir.Pix[(y-b.Min.Y)*dir.Stride+(x-b.Min.X)*1] var m0, m1 uint8 switch d { case 0: // west and east m0 = atOrZero(mag, x-1, y) m1 = atOrZero(mag, x+1, y) case 45: // north-east and south-west m0 = atOrZero(mag, x+1, y-1) m1 = atOrZero(mag, x-1, y+1) case 90: // north and south m0 = atOrZero(mag, x, y-1) m1 = atOrZero(mag, x, y+1) case 135: // north-west and south-east m0 = atOrZero(mag, x-1, y-1) m1 = atOrZero(mag, x+1, y+1) default: return fmt.Errorf("edge: bad direction (%d, %d): %d", x, y, d) } m := mag.Pix[(y-b.Min.Y)*mag.Stride+(x-b.Min.X)*1] if m > m0 && m > m1 { m = 0xff } else if m > m0 || m > m1 { m = 0x80 } else { m = 0x00 } dst.Pix[(y-b.Min.Y)*dst.Stride+(x-b.Min.X)*1] = m } } return nil }
func diffOp(mag, dir *image.Gray, src image.Image, opX, opY *convolve.SeparableKernel) error { if src == nil { return errors.New("graphics: src is nil") } b := src.Bounds() srcg, ok := src.(*image.Gray) if !ok { srcg = image.NewGray(b) draw.Draw(srcg, b, src, b.Min, draw.Src) } mx := image.NewGray(b) if err := convolve.Convolve(mx, srcg, opX); err != nil { return err } my := image.NewGray(b) if err := convolve.Convolve(my, srcg, opY); err != nil { return err } for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { off := (y-mx.Rect.Min.Y)*mx.Stride + (x-mx.Rect.Min.X)*1 cx := float64(mx.Pix[off]) cy := float64(my.Pix[off]) if mag != nil { off = (y-mag.Rect.Min.Y)*mag.Stride + (x-mag.Rect.Min.X)*1 mag.Pix[off] = uint8(math.Sqrt(cx*cx + cy*cy)) } if dir != nil { off = (y-dir.Rect.Min.Y)*dir.Stride + (x-dir.Rect.Min.X)*1 angle := math.Atan(cy / cx) // Round the angle to 0, 45, 90, or 135 degrees. angle = math.Mod(angle, 2*math.Pi) var degree uint8 if angle <= math.Pi/8 { degree = 0 } else if angle <= math.Pi*3/8 { degree = 45 } else if angle <= math.Pi*5/8 { degree = 90 } else if angle <= math.Pi*7/8 { degree = 135 } else { degree = 0 } dir.Pix[off] = degree } } } return nil }
func (cm *ComMaker) Convert(src image.Image) *image.Gray { // Make Grey Img b := src.Bounds() gSrc := image.NewGray(b) draw.Draw(gSrc, b, src, image.ZP, draw.Src) // Make Smaller gDst := image.NewGray(cm.bound) cm.rConv.Convert(gDst, gSrc) return gDst }
func TestGrayPlanes(t *testing.T) { w, h := 256, 256 src := readImage(t, "testdata/gray.png") ref := image.NewGray(src.Bounds()) err := Convert(ref, src, nil) expect(t, err, nil) raw := image.NewGray(image.Rect(0, 0, w*2, h*2)) dst := raw.SubImage(image.Rect(7, 7, 7+w, 7+h)) err = Convert(dst, src, NewBicubicFilter()) expect(t, err, nil) err = Convert(src, dst, NewBicubicFilter()) expect(t, err, nil) checkPsnrs(t, ref, src, image.Rectangle{}, []float64{38}) }
func TestSobel(t *testing.T) { testData := []struct { desc string srcb, dstb image.Rectangle srcPix, dstPix []uint8 }{ { "sobel 0x0", image.Rect(0, 0, 0, 0), image.Rect(0, 0, 0, 0), []uint8{}, []uint8{}, }, { "sobel 6x6", image.Rect(-1, -1, 5, 5), image.Rect(0, 0, 6, 6), []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, }, []uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, }, }, } for _, d := range testData { src := image.NewGray(d.srcb) src.Pix = d.srcPix f := Sobel() dst := image.NewGray(f.Bounds(src.Bounds())) f.Draw(dst, src, nil) if !checkBoundsAndPix(dst.Bounds(), d.dstb, dst.Pix, d.dstPix) { t.Errorf("test [%s] failed: %#v, %#v", d.desc, dst.Bounds(), dst.Pix) } } }
func TestInvert(t *testing.T) { src := image.NewGray(image.Rect(0, 0, 256, 1)) for i := 0; i <= 255; i++ { src.Pix[i] = uint8(i) } g := New(Invert()) dst := image.NewGray(g.Bounds(src.Bounds())) g.Draw(dst, src) for i := 0; i <= 255; i++ { if dst.Pix[i] != 255-src.Pix[i] { t.Errorf("InvertColors: index %d: expected %d got %d", i, 255-src.Pix[i], dst.Pix[i]) } } }
// newIntegrals returns the integral and the squared integral. func newIntegrals(src image.Image) (*integral, *integral) { b := src.Bounds() srcg, ok := src.(*image.Gray) if !ok { srcg = image.NewGray(b) draw.Draw(srcg, b, src, b.Min, draw.Src) } m := integral{ pix: make([]uint64, b.Max.Y*b.Max.X), stride: b.Max.X, rect: b, } mSq := integral{ pix: make([]uint64, b.Max.Y*b.Max.X), stride: b.Max.X, rect: b, } for y := b.Min.Y; y < b.Max.Y; y++ { for x := b.Min.X; x < b.Max.X; x++ { os := (y-b.Min.Y)*srcg.Stride + x - b.Min.X om := (y-b.Min.Y)*m.stride + x - b.Min.X c := uint64(srcg.Pix[os]) m.pix[om] = c mSq.pix[om] = c * c } } m.integrate() mSq.integrate() return &m, &mSq }
// from fib_test.go func BenchmarkFractalGeneration(b *testing.B) { // run the Fib function b.N times for n := 0; n < b.N; n++ { im := image.NewGray(image.Rectangle{image.Point{0, 0}, image.Point{1000, 1000}}) GenerateFractal(im) } }
func decodeRawBW(r io.Reader, c PNMConfig) (image.Image, error) { m := image.NewGray(image.Rect(0, 0, c.Width, c.Height)) byteCount := c.Width / 8 if c.Width%8 != 0 { byteCount += 1 } row := make([]byte, byteCount) pos := 0 for y := 0; y < c.Height; y++ { if _, err := io.ReadFull(r, row); err != nil { return nil, err } bitsLeft := c.Width for _, b := range row { n := bitsLeft if n > 8 { n = 8 } unpackByte(m.Pix[pos:pos+n], b) bitsLeft -= n pos += n } } return m, nil }
// makeTestImages generates an RGBA and a grayscale image and returns // testImages containing the JPEG encoded form as bytes and the expected color // model of the image when decoded. func makeTestImages() ([]testImage, error) { var ims []testImage w := bytes.NewBuffer(nil) im1 := image.NewRGBA(image.Rect(0, 0, width, height)) for i := range im1.Pix { switch { case i%4 == 3: im1.Pix[i] = 255 default: im1.Pix[i] = uint8(i) } } if err := jpeg.Encode(w, im1, nil); err != nil { return nil, err } ims = append(ims, testImage{im: im1, buf: w.Bytes()}) w = bytes.NewBuffer(nil) im2 := image.NewGray(image.Rect(0, 0, width, height)) for i := range im2.Pix { im2.Pix[i] = uint8(i) } if err := jpeg.Encode(w, im2, nil); err != nil { return nil, err } ims = append(ims, testImage{im: im2, buf: w.Bytes()}) return ims, nil }
func ExampleDrawer_floydSteinberg() { const width = 130 const height = 50 im := image.NewGray(image.Rectangle{Max: image.Point{X: width, Y: height}}) for x := 0; x < width; x++ { for y := 0; y < height; y++ { dist := math.Sqrt(math.Pow(float64(x-width/2), 2)/3+math.Pow(float64(y-height/2), 2)) / (height / 1.5) * 255 var gray uint8 if dist > 255 { gray = 255 } else { gray = uint8(dist) } im.SetGray(x, y, color.Gray{Y: 255 - gray}) } } pi := image.NewPaletted(im.Bounds(), []color.Color{ color.Gray{Y: 255}, color.Gray{Y: 160}, color.Gray{Y: 70}, color.Gray{Y: 35}, color.Gray{Y: 0}, }) draw.FloydSteinberg.Draw(pi, im.Bounds(), im, image.ZP) shade := []string{" ", "░", "▒", "▓", "█"} for i, p := range pi.Pix { fmt.Print(shade[p]) if (i+1)%width == 0 { fmt.Print("\n") } } }
func PlotSpectogram(sr Reader, outpath string, from, to int) error { d, err := dft(sr, from, to) if err != nil { return err } // make image height, width := len(d[0]), len(d) image := image.NewGray(image.Rect(0, 0, width, height)) // find maximum value in DFT max := maxAmp(d) max = math.Log(1 + max) // plot each point on image for i, col := range d { for j, amp := range col { // Log(Xk+1) will give us a positive value // Using log here allows low amplitudes to be more visible bright := uint8(float64(255) * math.Log(1+amp) / max) image.Set(i, height-j, color.RGBA{bright, bright, bright, 255}) } } of, err := os.Create(outpath) if err != nil { return err } return png.Encode(of, image) }
func (p *Pane) render(filename string) error { w := p.w h := p.h mtp := 1 / dx img := image.NewGray(image.Rect(0, 0, w, h)) for y := 0; y < h; y++ { for x := 0; x < w; x++ { img.SetGray(x, y, color.Gray{uint8(math.Sqrt(p.coat[y*w+x]) * 80)}) } } for _, d := range p.droplets { drawDroplet(img, d.x*mtp, d.y*mtp, d.r*mtp, d.h*mtp) } file, err := os.Create(filename) if err != nil { return err } defer file.Close() err = png.Encode(file, img) if err != nil { return err } return nil }
func main() { const order = 8 const width = 1 << order const margin = 10 bounds := image.Rect(-margin, -margin, width+2*margin, width+2*margin) im := image.NewGray(bounds) gBlack := color.Gray{0} gWhite := color.Gray{255} draw.Draw(im, bounds, image.NewUniform(gWhite), image.ZP, draw.Src) for y := 0; y < width; y++ { for x := 0; x < width; x++ { if x&y == 0 { im.SetGray(x, y, gBlack) } } } f, err := os.Create("sierpinski.png") if err != nil { fmt.Println(err) return } if err = png.Encode(f, im); err != nil { fmt.Println(err) } if err = f.Close(); err != nil { fmt.Println(err) } }
// Render draws rune r front the specified font at the specified dpi and scale. It returns a // grayscale image that is just large enough to contain the rune. func Render(font *truetype.Font, r rune, dpi, scale float64) (*image.Gray, error) { glyph := truetype.NewGlyphBuf() index := font.Index(r) glyph.Load(font, font.FUnitsPerEm(), index, truetype.FullHinting) ctx := freetype.NewContext() boxer := makeBoundingBoxer() ctx.SetSrc(image.NewUniform(color.White)) ctx.SetDst(boxer) ctx.SetClip(boxer.largeBounds) ctx.SetFontSize(250) ctx.SetDPI(dpi) ctx.SetFont(font) if err := glyph.Load(font, font.FUnitsPerEm(), font.Index(r), truetype.FullHinting); err != nil { return nil, fmt.Errorf("Unable to load glyph: %v\n", err) } var rp raster.Point rp.X = ctx.PointToFix32(0) rp.Y = ctx.PointToFix32(100) ctx.DrawString(string(r), rp) boxer.complete() g := gift.New( gift.Resize(int(float64(boxer.Bounds().Dx())*scale+0.5), int(float64(boxer.Bounds().Dy())*scale+0.5), gift.CubicResampling), ) dst := image.NewGray(g.Bounds(boxer.Bounds())) g.Draw(dst, boxer) return dst, nil }
func NewImageOfTypeRect(src image.Image, bounds image.Rectangle) image.Image { switch i := src.(type) { case *image.Alpha: return image.NewAlpha(bounds) case *image.Alpha16: return image.NewAlpha16(bounds) case *image.Gray: return image.NewGray(bounds) case *image.Gray16: return image.NewGray16(bounds) case *image.NRGBA: return image.NewNRGBA(bounds) case *image.NRGBA64: return image.NewNRGBA64(bounds) case *image.Paletted: return image.NewPaletted(bounds, i.Palette) case *image.RGBA: return image.NewRGBA(bounds) case *image.RGBA64: return image.NewRGBA64(bounds) case *image.YCbCr: return image.NewYCbCr(bounds, i.SubsampleRatio) } panic("Unknown image type") }
func TestHoughLines(t *testing.T) { timg := image.NewGray(image.Rect(0, 0, 700, 500)) timg.SetGray(10, 10, color.Gray{1}) timg.SetGray(200, 10, color.Gray{1}) timg.SetGray(400, 10, color.Gray{1}) timg.SetGray(10, 200, color.Gray{1}) timg.SetGray(10, 400, color.Gray{1}) lines := houghLines(*timg, nil, 0, 10) if !assert.Len(t, lines, 6) { t.FailNow() } expectedLines := []polarLine{ polarLine{Theta: 1.570796, Distance: 10, Count: 3}, polarLine{Theta: 0.000000, Distance: 10, Count: 3}, polarLine{Theta: 0.785398, Distance: 148, Count: 2}, polarLine{Theta: 0.453786, Distance: 184, Count: 2}, polarLine{Theta: 1.117011, Distance: 184, Count: 2}, polarLine{Theta: 0.785398, Distance: 290, Count: 2}, } for i, line := range lines { expected := expectedLines[i] thetaOk := assert.InDelta(t, expected.Theta, line.Theta, 0.0001) distanceOk := assert.Equal(t, expected.Distance, line.Distance) countOk := assert.Equal(t, expected.Count, line.Count) if !thetaOk || !distanceOk || !countOk { t.Fatalf("%v expected to equal %v", line, expected) } } }
func writeToJP() { imgRect := image.Rect(0, 0, gridSize*10, gridSize*10) img := image.NewGray(imgRect) draw.Draw(img, img.Bounds(), &image.Uniform{color.White}, image.ZP, draw.Src) for x := 0; x < gridSize; x++ { for y := 0; y < gridSize; y++ { fill := &image.Uniform{color.White} if Env[x][y] == -1 { fill = &image.Uniform{color.Black} } else if Env[x][y] > 1 { c := color.Gray{uint8(Env[x][y] * 20)} fill = &image.Uniform{c} } draw.Draw(img, image.Rect((x-1)*10, (y-1)*10, x*10, y*10), fill, image.ZP, draw.Src) } } buf := bytes.Buffer{} // ok, write out the data into the new JPEG file err := gif.Encode(&buf, img, nil) if err != nil { fmt.Println(err) os.Exit(1) } tmpimg, err := gif.Decode(&buf) if err != nil { log.Printf("Skipping frame due to weird error reading the temporary gif :%s", err) } frames = append(frames, tmpimg.(*image.Paletted)) }
// DifferenceHash computes the difference hash of an image. func DifferenceHash(source image.Image) uint64 { const sw, sh, hw, hh = 9, 8, 8, 8 // Convert the image to the grayscale colourspace. bounds := source.Bounds() width, height := bounds.Max.X, bounds.Max.Y gray := image.NewGray(source.Bounds()) for x := 0; x < width; x++ { for y := 0; y < height; y++ { gray.Set(x, y, source.At(x, y)) } } // Resize the image. shrunk := resize.Resize(sw, sh, gray, resize.NearestNeighbor).(*image.Gray) // Compute the difference hash. var hash uint64 for y := 0; y < hh; y++ { for x := 0; x < hw; x++ { if shrunk.GrayAt(x, y).Y < shrunk.GrayAt(x+1, y).Y { hash |= 1 << uint64((y*hw)+x) } } } return hash }
// TestWriteGrayscale tests that a grayscale images survives a round-trip // through encode/decode cycle. func TestWriteGrayscale(t *testing.T) { m0 := image.NewGray(image.Rect(0, 0, 32, 32)) for i := range m0.Pix { m0.Pix[i] = uint8(i) } var buf bytes.Buffer if err := Encode(&buf, m0, nil); err != nil { t.Fatal(err) } m1, err := Decode(&buf) if err != nil { t.Fatal(err) } if m0.Bounds() != m1.Bounds() { t.Fatalf("bounds differ: %v and %v", m0.Bounds(), m1.Bounds()) } if _, ok := m1.(*image.Gray); !ok { t.Errorf("got %T, want *image.Gray", m1) } // Compare the average delta to the tolerance level. want := int64(2 << 8) if got := averageDelta(m0, m1); got > want { t.Errorf("average delta too high; got %d, want <= %d", got, want) } }
func main() { flag.Parse() rand.Seed(time.Now().UTC().UnixNano()) out, err := os.Create(*outfile) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(1) } imgRect := image.Rect(0, 0, 200, 200) img := image.NewGray(imgRect) draw.Draw(img, img.Bounds(), &image.Uniform{color.White}, image.ZP, draw.Src) for y := 0; y < 200; y += 10 { for x := 0; x < 200; x += 10 { fill := &image.Uniform{color.Black} if rand.Intn(10)%2 == 0 { fill = &image.Uniform{color.White} } draw.Draw(img, image.Rect(x, y, x+10, y+10), fill, image.ZP, draw.Src) } } err = png.Encode(out, img) if err != nil { fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(2) } fmt.Printf("Wrote random image to \"%s\"\n", *outfile) os.Exit(0) }
func hough(im image.Image, ntx, mry int) draw.Image { nimx := im.Bounds().Max.X mimy := im.Bounds().Max.Y mry = int(mry/2) * 2 him := image.NewGray(image.Rect(0, 0, ntx, mry)) draw.Draw(him, him.Bounds(), image.NewUniform(color.White), image.ZP, draw.Src) rmax := math.Hypot(float64(nimx), float64(mimy)) dr := rmax / float64(mry/2) dth := math.Pi / float64(ntx) for jx := 0; jx < nimx; jx++ { for iy := 0; iy < mimy; iy++ { col := color.GrayModel.Convert(im.At(jx, iy)).(color.Gray) if col.Y == 255 { continue } for jtx := 0; jtx < ntx; jtx++ { th := dth * float64(jtx) r := float64(jx)*math.Cos(th) + float64(iy)*math.Sin(th) iry := mry/2 - int(math.Floor(r/dr+.5)) col = him.At(jtx, iry).(color.Gray) if col.Y > 0 { col.Y-- him.SetGray(jtx, iry, col) } } } } return him }
// makeImg allocates and initializes the destination image. func (d *decoder) makeImg(h0, v0, mxx, myy int) { if d.nComp == nGrayComponent { d.img1 = image.NewGray(8*mxx, 8*myy) d.img1.Rect = image.Rect(0, 0, d.width, d.height) return } var subsampleRatio ycbcr.SubsampleRatio n := h0 * v0 switch n { case 1: subsampleRatio = ycbcr.SubsampleRatio444 case 2: subsampleRatio = ycbcr.SubsampleRatio422 case 4: subsampleRatio = ycbcr.SubsampleRatio420 default: panic("unreachable") } b := make([]byte, mxx*myy*(1*8*8*n+2*8*8)) d.img3 = &ycbcr.YCbCr{ Y: b[mxx*myy*(0*8*8*n+0*8*8) : mxx*myy*(1*8*8*n+0*8*8)], Cb: b[mxx*myy*(1*8*8*n+0*8*8) : mxx*myy*(1*8*8*n+1*8*8)], Cr: b[mxx*myy*(1*8*8*n+1*8*8) : mxx*myy*(1*8*8*n+2*8*8)], SubsampleRatio: subsampleRatio, YStride: mxx * 8 * h0, CStride: mxx * 8, Rect: image.Rect(0, 0, d.width, d.height), } }