sego_b
sego_b

Reputation: 31

Error: Failed to compile fragment shader. while slice() with Tensorflow.js

I am developing a web application for image classification using Tensorflow.js. I take an image with my webcam and I want to extract a part of the image using the coordinates of a bounding box that I previously got. The bounding box structure is : [x, y, width, height]. The shape of the original webcam photo is [ 480, 640, 1 ]

I use the following code to extract the bounding box with Tensorflow.js :

function cropImage(webcamElement, bbox){
    const webcamImage = tf.browser.fromPixels(webcamElement)
                                    .mean(2)
                                    .toFloat()
                                    .expandDims(-1);

    let crop_width = bbox[2];
    let crop_height = bbox[3];

    // Get valid bbox width in canvas
    if (bbox[2] > webcamImage.shape[1] - bbox[0]){
        crop_width =  webcamImage.shape[1] - bbox[0];
    }

    // Get valid bbox height in canvas
    if (bbox[3] > webcamImage.shape[0] - bbox[1]){
        crop_height =  webcamImage.shape[0] - bbox[1];
    }

    let crop = webcamImage.slice(
        [bbox[1], bbox[0], 0],
        [crop_height, crop_width, 1]
    );
    console.log(crop);

but it returns the following message Error: Failed to compile fragment shader. at the execution level of the slice()

In spite of my research I have not found anything that can help me solve my problem. Do you have any ideas? Thank you in advance

Upvotes: 0

Views: 1025

Answers (2)

edkeveked
edkeveked

Reputation: 18381

The parameter passed to tf.slice are wrong. It should rather be

tensor.slice([y, x], [h, w]) 

where (y, x) are the coordinates where to start the slicing and (h, w) are the height and with of the slice.

const a = tf.ones([480, 640, 1]).slice([25, 60], [20, 30])
console.log(a.shape) // [20, 30, 1]

Upvotes: 0

Jason Mayes
Jason Mayes

Reputation: 301

Instead of using Tensors, why not just use Canvas directly if you want to crop the image?

Remove all the tf.browser.fromPixels stuff and instead pass canvas to function that holds the drawn image, and then take a crop of that. Eg:

Use the method getImageData with bounding box data:

var imageData = ctx.getImageData(bbox[0], bbox[1], bbox[2], bbox[3]);

Then create 2nd canvas with the desired size and use puImageData to set the pixels:

var canvas2 = document.createElement("canvas");
canvas2.width = bbox[2];
canvas2.height = bbox[3];
var ctx2 = canvas2.getContext("2d");
ctx2.putImageData(imageData, 0, 0);

If you want to save that as an image to the webpage you can then do:

dstImg.src = canvas1.toDataURL("image/png");

Upvotes: 1

Related Questions