Пример #1
0
func drawsq(b *draw.Image, p image.Point, ptx int) {
	var r image.Rectangle
	r.Min = p
	r.Max.X = r.Min.X + pcsz
	r.Max.Y = r.Min.Y + pcsz
	b.Draw(r, display.Black, nil, image.ZP)
	b.Draw(r.Inset(1), tx[ptx], nil, image.ZP)
}
Пример #2
0
func drawsq(b draw.Image, p image.Point, ptx int) {
	var r image.Rectangle
	r.Min = p
	r.Max.X = r.Min.X + pcsz
	r.Max.Y = r.Min.Y + pcsz
	draw.Draw(b, r, image.Black, image.ZP)
	draw.Draw(b, r.Inset(1), txpix[ptx], image.ZP)
}
Пример #3
0
func FeatSize(pix image.Point, conf Config) image.Point {
	// Leave a one-pixel border to compute derivatives.
	inside := image.Rectangle{image.ZP, pix}.Inset(1)
	// Leave a half-cell border.
	half := conf.CellSize / 2
	valid := inside.Inset(half)
	// Number of whole cells inside valid region.
	cells := valid.Size().Div(conf.CellSize)
	if cells.X <= 0 || cells.Y <= 0 {
		return image.ZP
	}
	// Remove one cell on all sides for output.
	out := cells.Sub(image.Pt(2, 2))
	return out
}
Пример #4
0
func drawRectangle(img draw.Image, rectangle *image.Rectangle) {
	diff := rectangle.Inset(-5)
	red := &image.Uniform{color.RGBA{255, 0, 0, 255}}
	minX := diff.Min.X
	maxX := diff.Max.X
	minY := diff.Min.Y
	maxY := diff.Max.Y
	topLine := image.Rect(minX-lineWidth, minY, maxX+lineWidth, minY-lineWidth)
	bottomLine := image.Rect(minX-lineWidth, maxY, maxX+lineWidth, maxY+lineWidth)
	leftLine := image.Rect(minX-lineWidth, minY-lineWidth, minX, maxY+lineWidth)
	rightLine := image.Rect(maxX, minY-lineWidth, maxX+lineWidth, maxY+lineWidth)
	draw.Draw(img, topLine, red, image.ZP, draw.Src)
	draw.Draw(img, bottomLine, red, image.ZP, draw.Src)
	draw.Draw(img, leftLine, red, image.ZP, draw.Src)
	draw.Draw(img, rightLine, red, image.ZP, draw.Src)
}
Пример #5
0
func setpiece(p *Piece) {
	bb.Draw(bb.R, display.White, nil, image.ZP)
	bbmask.Draw(bb.R, display.Transparent, nil, image.ZP)
	br = image.Rect(0, 0, 0, 0)
	br2 = br
	piece = p
	if p == nil {
		return
	}
	var op image.Point
	var r image.Rectangle
	r.Min = bb.R.Min
	for i, pt := range p.d {
		r.Min.X += pt.X * pcsz
		r.Min.Y += pt.Y * pcsz
		r.Max.X = r.Min.X + pcsz
		r.Max.Y = r.Min.Y + pcsz
		if i == 0 {
			bb.Draw(r, display.Black, nil, image.ZP)
			bb.Draw(r.Inset(1), tx[piece.tx], nil, image.ZP)
			bbmask.Draw(r, display.Opaque, nil, image.ZP)
			op = r.Min
		} else {
			bb.Draw(r, bb, nil, op)
			bbmask.Draw(r, bbmask, nil, op)
		}
		if br.Max.X < r.Max.X {
			br.Max.X = r.Max.X
		}
		if br.Max.Y < r.Max.Y {
			br.Max.Y = r.Max.Y
		}
	}
	br.Max = br.Max.Sub(bb.R.Min)
	delta := image.Pt(0, DY)
	br2.Max = br.Max.Add(delta)
	r = br.Add(bb2.R.Min)
	r2 := br2.Add(bb2.R.Min)
	bb2.Draw(r2, display.White, nil, image.ZP)
	bb2.Draw(r.Add(delta), bb, nil, bb.R.Min)
	bb2mask.Draw(r2, display.Transparent, nil, image.ZP)
	bb2mask.Draw(r, display.Opaque, bbmask, bb.R.Min)
	bb2mask.Draw(r.Add(delta), display.Opaque, bbmask, bb.R.Min)
}
Пример #6
0
func setpiece(p *Piece) {
	draw.Draw(bb, bbr, image.White, image.ZP)
	draw.Draw(bbmask, bbr, image.Transparent, image.ZP)
	br = image.Rect(0, 0, 0, 0)
	br2 = br
	piece = p
	if p == nil {
		return
	}
	var op image.Point
	var r image.Rectangle
	r.Min = bbr.Min
	for i, pt := range p.d {
		r.Min.X += pt.X * pcsz
		r.Min.Y += pt.Y * pcsz
		r.Max.X = r.Min.X + pcsz
		r.Max.Y = r.Min.Y + pcsz
		if i == 0 {
			draw.Draw(bb, r, image.Black, image.ZP)
			draw.Draw(bb, r.Inset(1), txpix[piece.tx], image.ZP)
			draw.Draw(bbmask, r, image.Opaque, image.ZP)
			op = r.Min
		} else {
			draw.Draw(bb, r, bb, op)
			draw.Draw(bbmask, r, bbmask, op)
		}
		if br.Max.X < r.Max.X {
			br.Max.X = r.Max.X
		}
		if br.Max.Y < r.Max.Y {
			br.Max.Y = r.Max.Y
		}
	}
	br.Max = br.Max.Sub(bbr.Min)
	delta := image.Pt(0, DY)
	br2.Max = br.Max.Add(delta)
	r = br.Add(bb2r.Min)
	r2 := br2.Add(bb2r.Min)
	draw.Draw(bb2, r2, image.White, image.ZP)
	draw.Draw(bb2, r.Add(delta), bb, bbr.Min)
	draw.Draw(bb2mask, r2, image.Transparent, image.ZP)
	draw.DrawMask(bb2mask, r, image.Opaque, bbr.Min, bbmask, image.ZP, draw.Over)
	draw.DrawMask(bb2mask, r.Add(delta), image.Opaque, bbr.Min, bbmask, image.ZP, draw.Over)
}
Пример #7
0
// BorderOp draws a retangular border of size r and width n, with n positive
// meaning the border is inside r, drawn with the specified draw op.
func (dst *Image) BorderOp(r image.Rectangle, n int, color *Image, sp image.Point, op Op) {
	if n < 0 {
		r = r.Inset(n)
		sp = sp.Add(image.Pt(n, n))
		n = -n
	}
	dst.Display.mu.Lock()
	defer dst.Display.mu.Unlock()
	draw(dst, image.Rect(r.Min.X, r.Min.Y, r.Max.X, r.Min.Y+n),
		color, sp, nil, sp, op)
	pt := image.Pt(sp.X, sp.Y+r.Dy()-n)
	draw(dst, image.Rect(r.Min.X, r.Max.Y-n, r.Max.X, r.Max.Y),
		color, pt, nil, pt, op)
	pt = image.Pt(sp.X, sp.Y+n)
	draw(dst, image.Rect(r.Min.X, r.Min.Y+n, r.Min.X+n, r.Max.Y-n),
		color, pt, nil, pt, op)
	pt = image.Pt(sp.X+r.Dx()-n, sp.Y+n)
	draw(dst, image.Rect(r.Max.X-n, r.Min.Y+n, r.Max.X, r.Max.Y-n),
		color, pt, nil, pt, op)
}
Пример #8
0
func HOG(f *rimg64.Multi, conf Config) *rimg64.Multi {
	const eps = 0.0001
	// Leave a one-pixel border to compute derivatives.
	inside := image.Rectangle{image.ZP, f.Size()}.Inset(1)
	// Leave a half-cell border.
	half := conf.CellSize / 2
	valid := inside.Inset(half)
	// Number of whole cells inside valid region.
	cells := valid.Size().Div(conf.CellSize)
	if cells.X <= 0 || cells.Y <= 0 {
		return nil
	}
	// Remove one cell on all sides for output.
	out := cells.Sub(image.Pt(2, 2))
	// Region to iterate over.
	size := cells.Mul(conf.CellSize).Add(image.Pt(2*half, 2*half))
	vis := image.Rectangle{inside.Min, inside.Min.Add(size)}

	// Accumulate edges into cell histograms.
	hist := rimg64.NewMulti(cells.X, cells.Y, 2*conf.Angles)
	quantizer := makeQuantizer(conf.Angles)
	for a := vis.Min.X; a < vis.Max.X; a++ {
		for b := vis.Min.Y; b < vis.Max.Y; b++ {
			x, y := a-half-vis.Min.X, b-half-vis.Min.Y
			// Pick channel with strongest gradient.
			grad, v := maxGrad(f, a, b)
			v = math.Sqrt(v)
			// Snap to orientation.
			q := quantizer.quantize(grad)

			// Add to 4 histograms around pixel using bilinear interpolation.
			xp := (float64(x)+0.5)/float64(conf.CellSize) - 0.5
			yp := (float64(y)+0.5)/float64(conf.CellSize) - 0.5
			// Extract integer and fractional part.
			ixp, vx0 := modf(xp)
			iyp, vy0 := modf(yp)
			// Complement of fraction part.
			vx1 := 1 - vx0
			vy1 := 1 - vy0

			if ixp >= 0 && iyp >= 0 {
				addToMulti(hist, ixp, iyp, q, vx1*vy1*v)
			}
			if ixp+1 < cells.X && iyp >= 0 {
				addToMulti(hist, ixp+1, iyp, q, vx0*vy1*v)
			}
			if ixp >= 0 && iyp+1 < cells.Y {
				addToMulti(hist, ixp, iyp+1, q, vx1*vy0*v)
			}
			if ixp+1 < cells.X && iyp+1 < cells.Y {
				addToMulti(hist, ixp+1, iyp+1, q, vx0*vy0*v)
			}
		}
	}

	// compute energy in each block by summing over orientations
	norm := rimg64.New(cells.X, cells.Y)
	for x := 0; x < cells.X; x++ {
		for y := 0; y < cells.Y; y++ {
			for d := 0; d < conf.Angles; d++ {
				s := hist.At(x, y, d) + hist.At(x, y, d+conf.Angles)
				addTo(norm, x, y, s*s)
			}
		}
	}

	feat := rimg64.NewMulti(out.X, out.Y, conf.Channels())
	for x := 0; x < out.X; x++ {
		for y := 0; y < out.Y; y++ {
			a, b := x+1, y+1
			// Normalization factors.
			var n [4]float64
			n[0] = 1 / math.Sqrt(adjSum(norm, a, b, a+1, b+1)+eps)
			n[1] = 1 / math.Sqrt(adjSum(norm, a, b, a+1, b-1)+eps)
			n[2] = 1 / math.Sqrt(adjSum(norm, a, b, a-1, b+1)+eps)
			n[3] = 1 / math.Sqrt(adjSum(norm, a, b, a-1, b-1)+eps)
			var off int

			// Contrast-sensitive features.
			if !conf.NoContrastVar {
				for d := 0; d < 2*conf.Angles; d++ {
					h := hist.At(a, b, d)
					var sum float64
					for _, ni := range n {
						val := h * ni
						if !conf.NoClip {
							val = math.Min(val, 0.2)
						}
						sum += val
					}
					feat.Set(x, y, off+d, sum/2)
				}
				off += 2 * conf.Angles
			}

			// Contrast-insensitive features.
			if !conf.NoContrastInvar {
				for d := 0; d < conf.Angles; d++ {
					h := hist.At(a, b, d) + hist.At(a, b, conf.Angles+d)
					var sum float64
					for _, ni := range n {
						val := h * ni
						if !conf.NoClip {
							val = math.Min(val, 0.2)
						}
						sum += val
					}
					feat.Set(x, y, off+d, sum/2)
				}
				off += conf.Angles
			}

			// Texture features.
			if !conf.NoTexture {
				for i, ni := range n {
					var sum float64
					for d := 0; d < 2*conf.Angles; d++ {
						h := hist.At(a, b, d)
						val := h * ni
						if !conf.NoClip {
							val = math.Min(val, 0.2)
						}
						sum += val
					}
					feat.Set(x, y, off+i, sum/math.Sqrt(float64(2*conf.Angles)))
				}
				off += 4
			}
		}
	}
	return feat
}