in src/engine/Segm2d.js [141:268]
async startApplyImage() {
this.stage = STAGE_IMAGE_PROCESSED;
console.log('Start apply segm to image ...');
// prepare tensor
const imgTensor = tf.browser.fromPixels(this.srcImageData).toFloat();
// this.printTensor(imgTensor);
// resize
const IN_W = 320;
const IN_H = 480;
const imgResized = imgTensor.resizeBilinear([IN_W, IN_H]);
// normalize to [-127..+127]
const mean = tf.tensor([123.0, 116.0, 103.0]);
const imgNormalized = imgResized.sub(mean);
// reshape tensor => [1, 320, 480, 3]
const imgReshaped = imgNormalized.reshape([1, IN_W, IN_H, 3]);
// apply prediction
const prediction = this.model.predict(imgReshaped);
// this.printTensor(prediction, 150*3);
const outpTensor = prediction.as2D(OUT_W * OUT_H, NUM_CLASSES);
const outRes = outpTensor.reshape([OUT_H, OUT_W, NUM_CLASSES]);
// get argmax: replace vec float[96] with index of maximum element
const tensorPreData = outRes.dataSync();
this.tensorIndices = new tf.zeros([OUT_H, OUT_W], 'int32');
const tensorIndData = this.tensorIndices.dataSync();
let iSrc = 0;
let iDst = 0;
for (let y = 0; y < OUT_H; y++) {
for (let x = 0; x < OUT_W; x++) {
let bestIndex = -1;
let valMax = -0.1;
for (let i = 0; i < NUM_CLASSES; i++) {
if (tensorPreData[iSrc + i] > valMax) {
valMax = tensorPreData[iSrc + i];
bestIndex = i;
} // if
} // for (i)
tensorIndData[iDst] = bestIndex;
iSrc += NUM_CLASSES;
iDst += 1;
} // for (x)
} // for (y)
// debug print tesor indices
// this.printTensorIndices(this.tensorIndices, 200*3);
// scale up image with indices
const pixelsUpScale = new Uint8ClampedArray(this.wSrc * this.hSrc);
this.scaleUp(tensorIndData, OUT_W, OUT_H, pixelsUpScale, this.wSrc, this.hSrc);
// generate 96-colors palette
const palette = new Uint8ClampedArray(256 * 4);
let i, j;
i = 0;
j = 0;
// fill 5 first elements by hand
palette[j++] = 0;
palette[j++] = 0;
palette[j++] = 255;
palette[j++] = 255;
i++;
palette[j++] = 0;
palette[j++] = 255;
palette[j++] = 0;
palette[j++] = 255;
i++;
palette[j++] = 255;
palette[j++] = 0;
palette[j++] = 0;
palette[j++] = 255;
i++;
palette[j++] = 255;
palette[j++] = 0;
palette[j++] = 255;
palette[j++] = 255;
i++;
palette[j++] = 64;
palette[j++] = 200;
palette[j++] = 255;
palette[j++] = 255;
i++;
for (; i < 256; i++, j += 4) {
palette[j + 0] = Math.floor(Math.random() * 255);
palette[j + 1] = Math.floor(Math.random() * 255);
palette[j + 2] = Math.floor(Math.random() * 255);
palette[j + 3] = 255;
}
// convert 96-classes output image into colors image
this.pixels = new Uint8ClampedArray(this.wSrc * this.hSrc * 4);
const pixels = this.pixels;
const w = this.wSrc;
const h = this.hSrc;
i = 0;
j = 0;
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const ind = pixelsUpScale[i];
pixels[j + 0] = palette[ind * 4 + 0];
pixels[j + 1] = palette[ind * 4 + 1];
pixels[j + 2] = palette[ind * 4 + 2];
pixels[j + 3] = 255;
i++;
j += 4;
}
}
this.stage = STAGE_SEGMENTATION_READY;
console.log('Segm complete now ');
this.objGraphics2d.forceRender();
}