async startApplyImage()

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();
  }