tensorflowjs : show predicted array as image

Viewed 799

As in the following js code, I am loading the model as a promise: tf.loadLayersModel('../tfjs-models/hadwritten-digits/model.json')

Now, I am using model.predict that will return an tensor of shape (1, 128, 128, 1) i.e. one grayscale image. I am having a lot of issue now on with promises and awaits. I have a canvas with known id in index.html, I want to put the image into. Needed some help now.

async function generate() {

    let input =  document.getElementById("slider").value
    console.log(`Random Noisy Input Mean is ${input}`)

    tf.loadLayersModel('../tfjs-models/hadwritten-digits/model.json').then(async (model) => {

    tensor = tf.tensor([randomnormal(100, input, 0.5)]);
    result = await model.predict(tensor).array()
    document.getElementById("myCanvas").getContext("3d").putImageData(
        new ImageData(Uint8ClampedArray.from(result), 1, 1), 1, 1);
    });
}

Error

model.js:39 Uncaught (in promise) TypeError: Cannot read property 'putImageData' of null
    at model.js:39

I am very new to javascript, python being my main lang. I needed to put up a frontend for my GAN model. And I felt adventurous using tfjs than serving results from flask or django. So any help will be a lot to me :)

Solved

async function generate() {

    let input =  document.getElementById("slider").value
    console.log(`Random Noisy Input Mean is ${input}`)

    inputtensor = tf.tensor([randomnormal(100, input, 0.5)]);
    outputtensor = await model.predict(inputtensor)

    result = outputtensor.mul([1, 1, 1, 1]).dataSync()
    for(var i=0;i<result.length;i++){
        result[i]=result[i]*255.0 + 128.0;
    }
    document.getElementById("myCanvas").getContext("2d").putImageData(
        new ImageData(Uint8ClampedArray.from(result), 128, 128), 1, 1);

}

var model;

tf.loadLayersModel('../tfjs-models/hadwritten-digits/model.json').then(async (resolve) => {
    model=resolve
});
1 Answers

There are a couple of things that needs to be changed in the code

  • There is not 3d context for now, there is the 2d context.

  • Additionnally, Uint8ClampedArray expects a flatten array. So instead of using array(respectively arraySync), it should rather be data(respectively dataSync).

  • ImageData expects the width and the height of the image. It is unlikely that the image width and height are 1 pixel each. So there might need to change the parameters given to ImageData

short example

tensor = tf.ones([5, 5, 4]);
new ImageData(Uint8ClampedArray.from(tensor.dataSync()), 5, 5);
Related