Exemple #1
0
func writeImagePng(filename string, pixels []float32, xres, yres int) {
	outImage := image.NewNRGBA(image.Rect(0, 0, xres, yres))

	to_byte := func(v float32) uint8 {
		// apply gamma and convert to 0..255
		return uint8(Clamp(255.0*math.Pow(float64(v), 1.0/2.2), 0.0, 255.0))
	}

	for y := 0; y < yres; y++ {
		for x := 0; x < xres; x++ {
			var fcolor color.NRGBA
			fcolor.R = to_byte(pixels[3*(y*xres+x)+0])
			fcolor.G = to_byte(pixels[3*(y*xres+x)+1])
			fcolor.B = to_byte(pixels[3*(y*xres+x)+2])
			fcolor.A = 0xff
			outImage.Set(x, y, fcolor)
		}
	}
	f, err := os.Create(filename)
	defer f.Close()

	if err != nil {
		Error("Error writing PNG \"%s\"", filename)
	} else {
		png.Encode(f, outImage)
	}
}
Exemple #2
0
func hexToColorNRGBA(hex string) color.NRGBA {
	c := color.NRGBA{}

	getIntensity := func(str string) uint8 {
		if u, err := hexToUint8(str); err == nil {
			return u
		}

		return 0
	}

	if len(hex) >= 6 {
		c.R = getIntensity(hex[0:2])
		c.G = getIntensity(hex[2:4])
		c.B = getIntensity(hex[4:6])
	}

	if len(hex) == 8 {
		c.A = getIntensity(hex[6:8])
	} else {
		c.A = 255
	}

	return c
}
Exemple #3
0
// render one row of pixels by calculating a colour for each pixel.
// The image pixel row number is r. Fill the pixel colour into the
// image after the colour has been calculated.
func (r row) render(rt *rtrace, a, b, c lin.V3, img *image.NRGBA, seed *uint32) {
	rgba := color.NRGBA{0, 0, 0, 255}
	t, v1, v2 := lin.NewV3(), lin.NewV3(), lin.NewV3() // temp vectors.
	colour, orig, dir := lin.NewV3(), lin.NewV3(), lin.NewV3()
	for x := (rt.iw - 1); x >= 0; x-- {
		colour.SetS(13, 13, 13) // Use a very dark default colour.

		// Cast 64 rays per pixel for blur (stochastic sampling) and soft-shadows.
		for cnt := 0; cnt < 64; cnt++ {

			// Add randomness to the camera origin 17,16,8
			t.Scale(&a, rnd(seed)-0.5).Scale(t, 99).Add(t, v1.Scale(&b, rnd(seed)-0.5).Scale(v1, 99))
			orig.SetS(17, 16, 8).Add(orig, t)

			// Add randomness to the camera direction.
			rnda := rnd(seed) + float64(x)
			rndb := float64(r) + rnd(seed)
			dir.Scale(t, -1)
			dir.Add(dir, v1.Scale(&a, rnda).Add(v1, v2.Scale(&b, rndb)).Add(v1, &c).Scale(v1, 16))
			dir.Unit()

			// accumulate the colour from each of the 64 rays.
			sample := rt.sample(*orig, *dir, seed)
			colour = sample.Scale(&sample, 3.5).Add(&sample, colour)
		}

		// set the final pixel colour in the image.
		rgba.R = byte(colour.X) // red
		rgba.G = byte(colour.Y) // green
		rgba.B = byte(colour.Z) // blue
		img.SetNRGBA(rt.iw-x, int(r), rgba)
	}
}
Exemple #4
0
func setRandomBrightness(c *color.NRGBA, max uint8) {
	minc := min3(c.R, c.G, c.B)
	maxc := max3(c.R, c.G, c.B)
	if maxc > max {
		return
	}
	n := rand.Intn(int(max-maxc)) - int(minc)
	c.R = uint8(int(c.R) + n)
	c.G = uint8(int(c.G) + n)
	c.B = uint8(int(c.B) + n)
}
func drawMotionMap(ske0, ske1 *image.NRGBA, m *MotionMap, shift *ShiftMap) (img *image.RGBA) {

	bounds := ske0.Bounds().Intersect(ske1.Bounds()).Intersect(m.Bounds)

	if shift != nil {
		bounds = bounds.Intersect(shift.Bounds)
	}

	s := 10

	img = image.NewRGBA(image.Rectangle{bounds.Min.Mul(s), bounds.Max.Mul(s)})
	gc := draw2d.NewGraphicContext(img)

	for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
		for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ {
			c := color.NRGBA{255, 255, 255, 255}

			if ske0.At(x/s, y/s).(color.NRGBA).A > 0 {
				c.R = 0
			}

			if ske1.At(x/s, y/s).(color.NRGBA).A > 0 {
				c.G = 0
			}

			img.Set(x, y, c)
		}
	}

	count := 0

	for y := m.Bounds.Min.Y; y < m.Bounds.Max.Y; y++ {
		for x := m.Bounds.Min.X; x < m.Bounds.Max.X; x++ {
			v := GetMotion(m, x, y)

			if v.X != 0 || v.Y != 0 {
				cx, cy := x*s+s/2, y*s+s/2
				dx, dy := v.X*s, v.Y*s
				gc.SetStrokeColor(color.RGBA{0, 0, 0, 255})
				gc.MoveTo(float64(cx), float64(cy))
				gc.LineTo(float64(cx+dx), float64(cy+dy))
				gc.Stroke()
				count++
			}

			if shift != nil {
				sv := GetShift(shift, x, y)

				if sv.Dx != 0.0 || sv.Dy != 0.0 {
					cx, cy := x*s+s/2, y*s+s/2
					sf := float64(s)
					//fmt.Println(x, y, sv)
					gc.SetStrokeColor(color.RGBA{0, 200, 0, 255})
					gc.MoveTo(float64(cx), float64(cy))
					gc.LineTo(float64(cx)+sv.Dx*sf, float64(cy)+sv.Dy*sf)
					gc.Stroke()
				}
			}
		}
	}

	fmt.Println("count:", count)

	return
}
Exemple #6
0
// Compare compares a and b using pdiff algorithm.
func (d *perceptual) Compare(a, b image.Image) (image.Image, int, error) {
	ab, bb := a.Bounds(), b.Bounds()
	w, h := ab.Dx(), ab.Dy()
	if w != bb.Dx() || h != bb.Dy() {
		return nil, -1, ErrSize
	}

	diff := image.NewNRGBA(image.Rect(0, 0, w, h))

	var (
		wg         sync.WaitGroup
		aLAB, bLAB [][]*labColor
		aLap, bLap [][][]float64
	)

	wg.Add(2)
	go func() {
		aLAB, aLap = labLap(a, d.gamma, d.lum)
		wg.Done()
	}()
	go func() {
		bLAB, bLap = labLap(b, d.gamma, d.lum)
		wg.Done()
	}()

	cpd := make([]float64, lapLevels) // cycles per degree
	cpd[0] = 0.5 * float64(w) / d.odp // 0.5 * pixels per degree
	for i := 1; i < lapLevels; i++ {
		cpd[i] = 0.5 * cpd[i-1]
	}
	csfMax := csf(3.248, 100.0)
	freq := make([]float64, lapLevels-2)
	for i := 0; i < lapLevels-2; i++ {
		freq[i] = csfMax / csf(cpd[i], 100.0)
	}

	wg.Wait()

	var npix int // num of diff pixels
	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			adapt := math.Max(0.5*(aLap[d.ai][y][x]+bLap[d.ai][y][x]), 1e-5)
			mask := make([]float64, lapLevels-2)
			contrast := make([]float64, lapLevels-2)
			var contrastSum float64
			for i := 0; i < lapLevels-2; i++ {
				n1 := math.Abs(aLap[i][y][x] - aLap[i+1][y][x])
				n2 := math.Abs(bLap[i][y][x] - bLap[i+1][y][x])
				d1 := math.Abs(aLap[i+2][y][x])
				d2 := math.Abs(bLap[i+2][y][x])
				d := math.Max(d1, d2)
				contrast[i] = math.Max(n1, n2) / math.Max(d, 1e-5)
				mask[i] = vmask(contrast[i] * csf(cpd[i], adapt))
				contrastSum += contrast[i]
			}
			if contrastSum < 1e-5 {
				contrastSum = 1e-5
			}

			var factor float64
			for i := 0; i < lapLevels-2; i++ {
				factor += contrast[i] * freq[i] * mask[i] / contrastSum
			}
			if factor < 1 {
				factor = 1
			} else if factor > 10 {
				factor = 10
			}

			delta := math.Abs(aLap[0][y][x] - bLap[0][y][x])
			pass := true
			// pure luminance test
			if delta > factor*tvi(adapt) {
				pass = false
			} else if !d.nocolor {
				// CIE delta E test with modifications
				cf := d.cf
				// ramp down the color test in scotopic regions
				if adapt < 10.0 {
					// don't do color test at all
					cf = 0.0
				}
				da := aLAB[y][x].a - bLAB[y][x].a
				db := aLAB[y][x].b - bLAB[y][x].b
				if (da*da+db*db)*cf > factor {
					pass = false
				}
			}

			c := color.NRGBA{0, 0, 0, 0xff}
			if !pass {
				npix++
				c.R = 0xff
				//ar, ag, ab, _ := a.At(x, y).RGBA()
				//br, bg, bb, _ := b.At(x, y).RGBA()
				//c.R = uint8((math.Abs(float64(ar)-float64(br)) / 0xffff) * 0xff)
				//c.G = uint8((math.Abs(float64(ag)-float64(bg)) / 0xffff) * 0xff)
				//c.B = uint8((math.Abs(float64(ab)-float64(bb)) / 0xffff) * 0xff)
			}
			diff.Set(x, y, c)
		}
	}

	return diff, npix, nil
}