// Convert the image in filename to a Tensor suitable as input to the Inception model.
func makeTensorFromImage(filename string) (*tf.Tensor, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	// DecodeJpeg uses a scalar String-valued tensor as input.
	tensor, err := tf.NewTensor(string(bytes))
	if err != nil {
		return nil, err
	}
	// Construct a graph to normalize the image
	graph, input, output, err := constructGraphToNormalizeImage()
	if err != nil {
		return nil, err
	}
	// Execute that graph to normalize this one image
	session, err := tf.NewSession(graph, nil)
	if err != nil {
		return nil, err
	}
	defer session.Close()
	normalized, err := session.Run(
		map[tf.Output]*tf.Tensor{input: tensor},
		[]tf.Output{output},
		nil)
	if err != nil {
		return nil, err
	}
	return normalized[0], nil
}
Exemplo n.º 2
0
// Const adds an operation to graph that produces value as output.
func Const(scope *Scope, value interface{}) (tf.Output, error) {
	if t, ok := value.(*tf.Tensor); ok {
		return makeConst(scope, t)
	}
	t, err := tf.NewTensor(value)
	if err != nil {
		return tf.Output{}, err
	}
	return makeConst(scope, t)
}
// Conver the image in filename to a Tensor suitable as input to the Inception model.
func makeTensorFromImage(filename string) (*tf.Tensor, error) {
	// Load the pixels from the file
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	img, _, err := image.Decode(file)
	file.Close()
	if err != nil {
		return nil, err
	}
	// Represent the image as [H][W][B,G,R]byte
	contents := make([][][3]byte, img.Bounds().Size().Y)
	for y := 0; y < len(contents); y++ {
		contents[y] = make([][3]byte, img.Bounds().Size().X)
		for x := 0; x < len(contents[y]); x++ {
			px := x + img.Bounds().Min.X
			py := y + img.Bounds().Min.Y
			r, g, b, _ := img.At(px, py).RGBA()
			// image.Image uses 16-bits for each color.
			// We want 8-bits.
			contents[y][x][0] = byte(b >> 8)
			contents[y][x][1] = byte(g >> 8)
			contents[y][x][2] = byte(r >> 8)
		}
	}
	tensor, err := tf.NewTensor(contents)
	if err != nil {
		return nil, err
	}
	// Construct a graph to normalize the image
	graph, input, output, err := constructGraphToNormalizeImage()
	if err != nil {
		return nil, err
	}
	// Execute that graph to normalize this one image
	session, err := tf.NewSession(graph, nil)
	if err != nil {
		return nil, err
	}
	defer session.Close()
	normalized, err := session.Run(
		map[tf.Output]*tf.Tensor{input: tensor},
		[]tf.Output{output},
		nil)
	if err != nil {
		return nil, err
	}
	return normalized[0], nil
}
// Given an image stored in filename, returns a Tensor which is suitable for
// providing the image data to the pre-defined model.
func makeTensorFromImageForInception(filename string) (*tf.Tensor, error) {
	const (
		// Some constants specific to the pre-trained model at:
		// https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip
		//
		// - The model was trained after with images scaled to 224x224 pixels.
		// - The colors, represented as R, G, B in 1-byte each were converted to
		//   float using (value - Mean)/Std.
		//
		// If using a different pre-trained model, the values will have to be adjusted.
		H, W = 224, 224
		Mean = 117
		Std  = float32(1)
	)
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	img, _, err := image.Decode(file)
	if err != nil {
		return nil, err
	}
	sz := img.Bounds().Size()
	if sz.X != W || sz.Y != H {
		return nil, fmt.Errorf("input image is required to be %dx%d pixels, was %dx%d", W, H, sz.X, sz.Y)
	}
	// 4-dimensional input:
	// - 1st dimension: Batch size (the model takes a batch of images as
	//                  input, here the "batch size" is 1)
	// - 2nd dimension: Rows of the image
	// - 3rd dimension: Columns of the row
	// - 4th dimension: Colors of the pixel as (B, G, R)
	// Thus, the shape is [1, 224, 224, 3]
	var ret [1][H][W][3]float32
	for y := 0; y < H; y++ {
		for x := 0; x < W; x++ {
			px := x + img.Bounds().Min.X
			py := y + img.Bounds().Min.Y
			r, g, b, _ := img.At(px, py).RGBA()
			ret[0][y][x][0] = float32((int(b>>8) - Mean)) / Std
			ret[0][y][x][1] = float32((int(g>>8) - Mean)) / Std
			ret[0][y][x][2] = float32((int(r>>8) - Mean)) / Std
		}
	}
	return tf.NewTensor(ret)
}
Exemplo n.º 5
0
// Const adds an operation to graph that produces value as output.
func Const(scope *Scope, value interface{}) (output tf.Output) {
	if scope.Err() != nil {
		return
	}
	t, ok := value.(*tf.Tensor)
	if !ok {
		var err error
		if t, err = tf.NewTensor(value); err != nil {
			scope.UpdateErr("Const", err)
			return
		}
	}
	return scope.AddOperation(tf.OpSpec{
		Type: "Const",
		Attrs: map[string]interface{}{
			"dtype": t.DataType(),
			"value": t,
		}}).Output(0)
}