Exemplo n.º 1
0
func maskFor(in image.Image) image.Image {
	b := in.Bounds()

	// thumb size, corresponds to first convert command
	thumbWidth := int(b.Dx() / 5)
	thumbHeight := int(b.Dy() / 5)

	thumb := image.NewRGBA(image.Rect(0, 0, thumbWidth, thumbHeight))
	final := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))

	// fill black (xc:black)
	// draw white rectangle  (1,1 : thumbWidth-1,thumbHeight-1)
	for y := 0; y < thumbHeight; y++ {
		for x := 0; x < thumbWidth; x++ {
			if (y > 0 && y < thumbHeight-1) && (x > 0 && x < thumbWidth-1) {
				thumb.Set(x, y, color.White)
			} else {
				thumb.Set(x, y, color.Black)
			}
		}
	}

	// apply Gaussian blur with radius=7, sigma=15
	graphics.Blur(thumb, thumb, &graphics.BlurOptions{2, 7})

	// now resize to original image size
	resized := resize.Resize(uint(b.Dx()), uint(b.Dy()), thumb, resize.Bilinear)

	// with gaussian blur radius=0, sigma=5
	graphics.Blur(final, resized, &graphics.BlurOptions{5, 0})

	return final
}
Exemplo n.º 2
0
// 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
}
Exemplo n.º 3
0
// DifferenceOfGaussians produces the difference of Gaussians sd0 and sd1.
func DifferenceOfGaussians(dst *image.Gray, src image.Image, sd0, sd1 float64) {
	b := src.Bounds()
	srcg := image.NewGray(b)
	m0 := image.NewGray(b)
	m1 := image.NewGray(b)

	draw.Draw(srcg, b, src, b.Min, draw.Src)

	graphics.Blur(m0, srcg, &graphics.BlurOptions{StdDev: sd0})
	graphics.Blur(m1, srcg, &graphics.BlurOptions{StdDev: sd1})

	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			off := (y-m0.Rect.Min.Y)*m0.Stride + (x - m0.Rect.Min.X)
			c := m0.Pix[off] - m1.Pix[off]
			if c < 0 {
				c = -c
			}

			doff := (y-dst.Rect.Min.Y)*dst.Stride + (x - dst.Rect.Min.X)
			dst.Pix[doff] = c
		}
	}
}