Beispiel #1
0
func getGray(src *image.Gray, x, y, borderMethod int) uint8 {
	bound := src.Bounds()
	if x < 0 {
		switch borderMethod {
		case BORDER_COPY:
			x = 0
		default:
			return 0
		}
	} else if x >= bound.Max.X {
		switch borderMethod {
		case BORDER_COPY:
			x = bound.Max.X - 1
		default:
			return 0
		}
	}
	if y < 0 {
		switch borderMethod {
		case BORDER_COPY:
			y = 0
		default:
			return 0
		}
	} else if y >= bound.Max.Y {
		switch borderMethod {
		case BORDER_COPY:
			y = bound.Max.Y - 1
		default:
			return 0
		}
	}
	i := (y-bound.Min.Y)*src.Stride + (x - bound.Min.X)
	return src.Pix[i]
}
Beispiel #2
0
func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
	newBounds := out.Bounds()
	maxX := in.Bounds().Dx() - 1

	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
		row := in.Pix[x*in.Stride:]
		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
			var gray float32
			var sum float32
			start := offset[y]
			ci := y * filterLength
			for i := 0; i < filterLength; i++ {
				if coeffs[ci+i] {
					xi := start + i
					switch {
					case xi < 0:
						xi = 0
					case xi >= maxX:
						xi = maxX
					}
					gray += float32(row[xi])
					sum++
				}
			}

			offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X)
			out.Pix[offset] = floatToUint8(gray / sum)
		}
	}
}
Beispiel #3
0
func resizeGray(in *image.Gray, out *image.Gray, scale float64, coeffs []int16, offset []int, filterLength int) {
	newBounds := out.Bounds()
	maxX := in.Bounds().Dx() - 1

	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
		row := in.Pix[(x-newBounds.Min.X)*in.Stride:]
		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
			var gray int32
			var sum int32
			start := offset[y]
			ci := y * filterLength
			for i := 0; i < filterLength; i++ {
				coeff := coeffs[ci+i]
				if coeff != 0 {
					xi := start + i
					switch {
					case xi < 0:
						xi = 0
					case xi >= maxX:
						xi = maxX
					}
					gray += int32(coeff) * int32(row[xi])
					sum += int32(coeff)
				}
			}

			offset := (y-newBounds.Min.Y)*out.Stride + (x - newBounds.Min.X)
			out.Pix[offset] = clampUint8(gray / sum)
		}
	}
}
Beispiel #4
0
func New(im image.Gray) *Integral {
	rect := im.Bounds()
	width := rect.Dx()
	height := rect.Dy()

	data := make([]uint32, width*height)
	for x := rect.Min.X; x < rect.Max.X; x++ {
		for y := rect.Min.Y; y < rect.Max.Y; y++ {
			if x == 0 && y == 0 {
				data[0] = uint32(im.Pix[0])
			} else if x == 0 && y != 0 {
				data[y*height+x] = data[(y-1)*height+x] + uint32(im.Pix[y*im.Stride+x])
			} else if y == 0 && x != 0 {
				data[y*height+x] = data[y*height+x-1] + uint32(im.Pix[y*im.Stride+x])
			} else {
				data[y*height+x] = data[(y-1)*height+x] + data[y*height+x-1] - data[(y-1)*height+x-1] + uint32(im.Pix[y*im.Stride+x])
			}
		}
	}

	intImg := &Integral{
		Data:   data,
		Width:  width,
		Height: height,
	}

	return intImg
}
Beispiel #5
0
func Contrast(picture *image.Gray, contrast uint8) *image.Gray {
	bounds := picture.Bounds()
	newPic := image.NewGray(bounds)
	average := getAverage(picture)
	for x := 0; x < bounds.Dx(); x++ {
		for y := 0; y < bounds.Dy(); y++ {
			pixel := picture.At(x, y).(color.Gray).Y
			if pixel > average {
				if pixel+contrast < pixel {
					pixel = 0xff
				} else {
					pixel += contrast
				}
			} else if pixel < average {
				if pixel-contrast > pixel {
					pixel = 0x00
				} else {
					pixel -= contrast
				}
			}
			newPic.Set(x, y, color.Gray{pixel})
		}
	}
	return newPic
}
Beispiel #6
0
func valueAt(img *image.Gray, x, y float32) float32 {
	dx, dy := x/float32(screenWidth), y/float32(screenHeight)
	b := img.Bounds().Max
	px, py := int(dx*float32(b.X)), int(dy*float32(b.Y))
	v := float32(img.At(px, py).(color.Gray).Y) / 255
	return v
}
Beispiel #7
0
func GenerateFractal(im *image.Gray) {

	z := &cn{}

	c := &cn{}
	g := color.Gray{}
	for x := 0; x < 1000; x++ {
		for y := 0; y < 1000; y++ {

			c.r = (*width * float64(x) / float64(1000)) - *width/float64(2)
			c.i = (*height * float64(y) / float64(1000)) - *height/float64(2)
			c.r += *centerx
			c.i += *centery

			z.r = 0
			z.i = 0
			zrsqr := z.r * z.r
			zisqr := z.i * z.i

			var i uint8 = 0
			for zrsqr+zisqr < 4.0 && i < 255 {
				i++
				z.i = square(z.r+z.i) - zrsqr - zisqr
				z.i += c.i
				z.r = zrsqr - zisqr + c.r
				zrsqr = square(z.r)
				zisqr = square(z.i)
			}
			g.Y = i
			im.SetGray(x, y, g)

		}
	}
}
Beispiel #8
0
func drawRect(img *image.Gray, c color.Gray, xPos, yPos, width, height float64) {
	for h := 0.0; h < height; h += 1.0 {
		for w := 0.0; w < width; w += 1.0 {
			img.SetGray(int(xPos+w), int(yPos+h), c)
		}
	}
}
Beispiel #9
0
func Blobify(img *image.Gray) Blobs {
	var blobs Blobs
	visited := make([]bool, img.Bounds().Max.X*img.Bounds().Max.Y)

	// Scan for first/next blob.
	x, y := 0, 0

	for {
		x, y = nextPixel(x, y, img, visited)
		if x < 0 || y < 0 {
			for _, b := range blobs.blobs {
				// Only compute bridges for wide blobs
				if float64(b.Bounds.Dx()) >= blobs.avgWidth()*1.75 {
					b.computeBridges(blobs.avgWidth())
				}
			}
			log.Printf("Returning Blobs with count: %d\n", len(blobs.blobs))

			return blobs
		}

		// Extract blob.
		b := blobAt(x, y, img, visited)
		x = b.Bounds.Max.X + 1
		blobs.addBlob(b)
	}
}
Beispiel #10
0
// checkCircle checks that a circle with a center in (x, y) and a radius r fits to the base image and all pixels are high.
func checkCircle(base *image.Gray, level byte, pxSize, x, y, r float64) bool {
	width := float64(base.Bounds().Dx()) * pxSize
	height := float64(base.Bounds().Dy()) * pxSize
	if x < r || x > width-r || y < r || y > height-r {
		return false
	}
	x0 := int((x - r) / pxSize)
	y0 := int((y - r) / pxSize)
	x1 := int((x + r) / pxSize)
	y1 := int((y + r) / pxSize)
	for cy := y0; cy <= y1; cy++ {
		i0 := cy * base.Stride
		for cx := x0; cx <= x1; cx++ {
			if !inside(x, y, r, (x-r)+float64(cx-x0)*pxSize, (y-r)+float64(cy-y0)*pxSize) {
				continue
			}
			if base.Pix[i0+cx] != level {
				// circle hits background
				//fmt.Printf("checkCircle(pxSize=%f, x=%f, y=%f, r=%f, i0=%d, cx=%d, base.Pix[i0+cx]=%d\n",
				//	pxSize, x, y, r, i0, cx, base.Pix[i0+cx])
				return false
			}
		}
	}
	return true
}
Beispiel #11
0
func fillTriangle(base *image.Gray, level byte, bbox image.Rectangle, ox, oy float64) []Point {
	basePxSize := *pxSize / float64(*n)
	width := float64(base.Bounds().Dx()) * basePxSize
	height := float64(base.Bounds().Dy()) * basePxSize

	dy := (*toolDiameter) / 2
	dx := dy * 1.73205080757 // sqrt(3)
	var centers []Point
	for i := 0; ; i++ {
		cx := ox + float64(i)*dx
		if cx >= width {
			break
		}
		if cx < float64(bbox.Min.X-1)*basePxSize || cx >= float64(bbox.Max.X+1)*basePxSize {
			continue
		}
		for j := 0; ; j++ {
			cy := oy + float64(j)*dy
			if cy >= height {
				break
			}
			if cy < float64(bbox.Min.Y-1)*basePxSize || cy >= float64(bbox.Max.Y+1)*basePxSize {
				continue
			}
			if (i+j)%2 == 1 {
				continue
			}
			if checkCircle(base, level, basePxSize, cx, cy, (*toolDiameter)/2) {
				centers = append(centers, Point{cx, cy})
			}
		}
	}
	return centers
}
Beispiel #12
0
func fillQuad(base *image.Gray, level byte, bbox image.Rectangle, ox, oy float64) []Point {
	basePxSize := *pxSize / float64(*n)
	width := float64(base.Bounds().Dx()) * basePxSize
	height := float64(base.Bounds().Dy()) * basePxSize
	dx := *toolDiameter
	dy := *toolDiameter
	var centers []Point
	for i := 0; ; i++ {
		cx := ox + float64(i)*dx
		if cx >= width {
			break
		}
		if cx < float64(bbox.Min.X-1)*basePxSize || cx >= float64(bbox.Max.X+1)*basePxSize {
			//fmt.Printf("bbox={%f,%f}-{%f,%f}, cx: %f, skip...\n",
			//	float64(bbox.Min.X)*basePxSize, float64(bbox.Min.Y)*basePxSize, float64(bbox.Max.X)*basePxSize, float64(bbox.Max.Y)*basePxSize, cx)
			continue
		}
		for j := 0; ; j++ {
			cy := oy + float64(j)*dy
			if cy >= height {
				break
			}
			if cy < float64(bbox.Min.Y-1)*basePxSize || cy >= float64(bbox.Max.Y+1)*basePxSize {
				//fmt.Printf("bbox={%f,%f}-{%f,%f}, cy: %f, skip...\n",
				//	float64(bbox.Min.X)*basePxSize, float64(bbox.Min.Y)*basePxSize, float64(bbox.Max.X)*basePxSize, float64(bbox.Max.Y)*basePxSize, cy)
				continue
			}
			if checkCircle(base, level, basePxSize, cx, cy, (*toolDiameter)/2) {
				centers = append(centers, Point{cx, cy})
			}
		}
	}
	return centers
}
Beispiel #13
0
//BackProjectGray computes back projection of img
// in Gray16 by performing an addition
// of backprojection by line.
// 16Gray avoids white noise.
func BackProjectGray(img image.Gray) (*image.Gray16, error) {
	size := img.Bounds().Size()
	width := size.Y
	nbProj := size.X
	step := 180.0 / float64(nbProj)

	out := image.NewGray16(image.Rect(0, 0, width, width))

	for X := 0; X < nbProj; X++ {
		//Extract a 1D-projection (one row Y of sinogram)
		line := img.SubImage(image.Rect(X, 0, X+1, width)).(*image.Gray)

		// 3- Do the backprojection and rotate accordingly
		wideLine := resize.Resize(uint(width), uint(width), line, resize.Lanczos3).(*image.Gray)

		θ := manipulator.Rad(float64(X)*step) + math.Pi/2
		rotatedWideLine := image.NewGray(image.Rect(0, 0, width, width))
		err := graphics.Rotate(rotatedWideLine, wideLine, &graphics.RotateOptions{Angle: θ})
		if err != nil {
			return out, err
		}

		// 4- Add the rotated backprojection in the output image
		for x := 0; x < width; x++ {
			for y := 0; y < width; y++ {
				point := uint16(out.At(x, y).(color.Gray16).Y) + uint16(rotatedWideLine.At(x, y).(color.Gray).Y)
				out.Set(x, y, color.Gray16{uint16(point)})
			}
		}
	}

	return out, nil
}
Beispiel #14
0
// GreyscaleDct Computes the Dct of a greyscale image
func GreyscaleDct(img image.Gray) uint64 {
	// func DctImageHashOne(img image.Image) ([][]float64) {
	R := img.Bounds()
	N := R.Dx() // width
	M := R.Dy() // height
	DCTMatrix := make([][]float64, N)
	for u := 0; u < N; u++ {
		DCTMatrix[u] = make([]float64, M)
		for v := 0; v < M; v++ {
			DCTMatrix[u][v] = dctPoint(img, u, v, N, M)
			// fmt.Println( "DCTMatrix[", u, "][", v, "] is ", DCTMatrix[u][v])
		}
	}

	total := 0.0
	for u := 0; u < N/2; u++ {
		for v := 0; v < M/2; v++ {
			total += DCTMatrix[u][v]
		}
	}
	total -= DCTMatrix[0][0]
	avg := total / float64(((N/2)*(M/2))-1)
	fmt.Println("got average ", avg)
	var hash uint64
	for u := 0; u < N/2; u++ {
		for v := 0; v < M/2; v++ {
			hash = hash * 2
			if DCTMatrix[u][v] > avg {
				hash++
			}
		}
	}

	return hash
}
Beispiel #15
0
func ImageEnhanceGrey(img *image.Gray, enhanceDegress float32, enhanceOffset float32) *image.RGBA {
	rgbFunc := func(xpos, ypos int) (r0, g0, b0, a0 uint8) {
		gray := img.GrayAt(xpos, ypos)
		return gray.Y, gray.Y, gray.Y, gray.Y
	}
	imgEnhanced := imenhance(enhanceDegress, enhanceOffset, [3]bool{true, true, true}, false, img.Rect, rgbFunc)
	return imgEnhanced
}
Beispiel #16
0
func emptyCol(m *image.Gray, r image.Rectangle, x int) bool {
	for y := r.Min.Y; y < r.Max.Y; y++ {
		if m.GrayAt(x, y).Y > 0 {
			return false
		}
	}
	return true
}
Beispiel #17
0
func newAtFuncGray(p *image.Gray) AtFunc {
	return func(x, y int) (r, g, b, a uint32) {
		i := p.PixOffset(x, y)
		yy := uint32(p.Pix[i])
		yy |= yy << 8
		return yy, yy, yy, 0xffff
	}
}
Beispiel #18
0
func emptyRow(m *image.Gray, r image.Rectangle, y int) bool {
	for x := r.Min.X; x < r.Max.X; x++ {
		if m.GrayAt(x, y).Y > 0 {
			return false
		}
	}
	return true
}
Beispiel #19
0
func meanHeight(g *image.Gray) uint8 {
	b := g.Bounds()
	var total uint64
	for i := b.Min.X; i < b.Max.X; i++ {
		for j := b.Min.Y; j < b.Max.Y; j++ {
			total += uint64(g.GrayAt(i, j).Y)
		}
	}
	return uint8(total / uint64((b.Dx() * b.Dy())))
}
Beispiel #20
0
func getAverage(picture *image.Gray) uint8 {
	var sum uint64 = 0
	bounds := picture.Bounds()
	for x := 0; x < bounds.Dx(); x++ {
		for y := 0; y < bounds.Dy(); y++ {
			sum += uint64(picture.At(x, y).(color.Gray).Y)
		}
	}
	return uint8(sum / uint64(bounds.Dx()*bounds.Dy()))
}
Beispiel #21
0
// Interpolate uint8/pixel images.
func interpolate1x8(src *image.Gray, dstW, dstH int) image.Image {
	srcRect := src.Bounds()
	srcW := srcRect.Dx()
	srcH := srcRect.Dy()

	ww, hh := uint64(dstW), uint64(dstH)
	dx, dy := uint64(srcW), uint64(srcH)

	n, sum := dx*dy, make([]uint64, dstW*dstH)
	for y := 0; y < srcH; y++ {
		pixOffset := src.PixOffset(0, y)
		for x := 0; x < srcW; x++ {
			// Get the source pixel.
			val64 := uint64(src.Pix[pixOffset])
			pixOffset++

			// Spread the source pixel over 1 or more destination rows.
			py := uint64(y) * hh
			for remy := hh; remy > 0; {
				qy := dy - (py % dy)
				if qy > remy {
					qy = remy
				}
				// Spread the source pixel over 1 or more destination columns.
				px := uint64(x) * ww
				index := (py/dy)*ww + (px / dx)
				for remx := ww; remx > 0; {
					qx := dx - (px % dx)
					if qx > remx {
						qx = remx
					}
					qxy := qx * qy
					sum[index] += val64 * qxy
					index++
					px += qx
					remx -= qx
				}
				py += qy
				remy -= qy
			}
		}
	}
	dst := image.NewGray(image.Rect(0, 0, dstW, dstH))
	index := 0
	for y := 0; y < dstH; y++ {
		pixOffset := dst.PixOffset(0, y)
		for x := 0; x < dstW; x++ {
			dst.Pix[pixOffset] = uint8(sum[index] / n)
			pixOffset++
			index++
		}
	}
	return dst
}
Beispiel #22
0
func GrayImageToMatrix(src image.Gray) (*matrix.Dense, error) {
	bounds := src.Bounds()
	mtx := make([][]float64, bounds.Max.X)
	for x := 0; x < bounds.Max.X; x++ {
		mtx[x] = make([]float64, bounds.Max.Y)
		for y := 0; y < bounds.Max.Y; y++ {
			_, _, b, _ := src.At(x, y).RGBA()
			mtx[x][y] = float64(b)
		}
	}
	return matrix.NewDense(mtx)
}
Beispiel #23
0
func toGray(o *ora.ORA, name string) (*image.Gray, error) {
	var p *image.Gray
	if l := o.Layer(name); l != nil {
		p = image.NewGray(o.Bounds())
		i, err := l.Image()
		if err != nil {
			return nil, err
		}
		draw.Draw(p, image.Rect(0, 0, p.Bounds().Max.X, p.Bounds().Max.Y), i, image.Point{}, draw.Src)
	}
	return p, nil
}
Beispiel #24
0
func tightBounds(m *image.Gray) (r image.Rectangle) {
	r = m.Bounds()
	for ; r.Min.Y < r.Max.Y && emptyRow(m, r, r.Min.Y+0); r.Min.Y++ {
	}
	for ; r.Min.Y < r.Max.Y && emptyRow(m, r, r.Max.Y-1); r.Max.Y-- {
	}
	for ; r.Min.X < r.Max.X && emptyCol(m, r, r.Min.X+0); r.Min.X++ {
	}
	for ; r.Min.X < r.Max.X && emptyCol(m, r, r.Max.X-1); r.Max.X-- {
	}
	return r
}
Beispiel #25
0
// grayToY stores the 8x8 region of m whose top-left corner is p in yBlock.
func grayToY(m *image.Gray, p image.Point, yBlock *block) {
	b := m.Bounds()
	xmax := b.Max.X - 1
	ymax := b.Max.Y - 1
	pix := m.Pix
	for j := 0; j < 8; j++ {
		for i := 0; i < 8; i++ {
			idx := m.PixOffset(min(p.X+i, xmax), min(p.Y+j, ymax))
			yBlock[8*j+i] = int32(pix[idx])
		}
	}
}
Beispiel #26
0
func scaleGray(src *image.Gray, scale uint8) *image.Gray {
	bounds := src.Bounds()

	dst := image.NewGray(bounds)
	copy(dst.Pix, src.Pix)

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			dst.SetGray(x, y, color.Gray{grayAt(src, x, y).Y * scale})
		}
	}
	return dst
}
Beispiel #27
0
func drawRect(img *image.Gray, r image.Rectangle, c color.Gray) {
	// Draw top and bottom lines
	for x := r.Min.X - 1; x <= r.Max.X; x++ {
		img.SetGray(x, r.Min.Y-1, c)
		img.SetGray(x, r.Max.Y+1, c)
	}

	// Draw side lines
	for y := r.Min.Y - 1; y <= r.Max.Y; y++ {
		img.SetGray(r.Min.X-1, y, c)
		img.SetGray(r.Max.X+1, y, c)
	}
}
Beispiel #28
0
func GrayImageToMatrix(src image.Gray) (*mat64.Dense, error) {
	bounds := src.Bounds()
	rows := bounds.Max.Y
	cols := bounds.Max.X

	mtx := make([]float64, rows*cols)
	for x := 0; x < cols; x++ {
		for y := 0; y < rows; y++ {
			_, _, b, _ := src.At(x, y).RGBA()
			mtx[y*cols+x] = float64(b)
		}
	}
	return mat64.NewDense(rows, cols, mtx), nil
}
Beispiel #29
0
func (entity *Entity) deviation(model *image.Gray) float64 {
	deviation := 0.0
	actual := entity.render()

	for x := 0; x < entity.width; x++ {
		for y := 0; y < entity.height; y++ {
			actualColor := float64(actual.At(x, y).(color.Gray).Y)
			modelColor := float64(model.At(x, y).(color.Gray).Y)
			dev := actualColor - modelColor
			deviation += dev * dev
		}
	}

	return deviation
}
Beispiel #30
0
func dctPoint(img image.Gray, u, v, N, M int) float64 {
	sum := 0.0
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			_, _, b, _ := img.At(i, j).RGBA()
			// sum += math.Cos( ( float64(2*i+1)/float64(2*N) ) * float64( u ) * math.Pi ) *
			//        math.Cos( ( float64(2*j+1)/float64(2*M) ) * float64( v ) * math.Pi ) *
			//        float64(b)

			sum += math.Cos(math.Pi/(float64(N))*(float64(i)+1/2)*float64(u)) *
				math.Cos(math.Pi/(float64(M))*(float64(j)+1/2)*float64(v)) *
				float64(b)
		}
	}
	return sum * ((coefficient(u) * coefficient(v)) / 4.0)
}