// 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 }
// 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) }
// 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) }