async runImageClassifier()

in interactive-visualizers/src/app/app.component.ts [576:662]


  async runImageClassifier(image: HTMLImageElement, index: number):
      Promise<void> {
    let results = [];
    if (this.modelFormat === 'tflite') {
      const startTs = Date.now();
      const rawResults = this.tfWebApi.run(image);
      this.resultsLatency = Date.now() - startTs;
      rawResults.getClassificationsList()[0].getClassesList().forEach(cls => {
        if (cls.getDisplayName()) {
          results.push({
            displayName: cls.getDisplayName(),
            score: cls.getScore(),
          });
        } else {
          results.push({
            displayName: cls.getClassName(),
            score: cls.getScore(),
          });
        }
      });
    } else {
      // Prepare inputs.
      const inputTensorMetadata =
          this.modelMetadata.tfjs_classifier_model_metadata.input_tensor_metadata;
      const imageTensor = this.prepareImageInput(image, inputTensorMetadata);

      // Execute the model.
      const startTs = Date.now();
      const outputTensor: tf.Tensor =
          await this.model.executeAsync(imageTensor) as tf.Tensor;
      this.resultsLatency = Date.now() - startTs;
      tf.dispose(imageTensor);
      const squeezedOutputTensor = outputTensor.squeeze();
      tf.dispose(outputTensor);
      const predictions: number[] =
          await squeezedOutputTensor.array() as number[];
      tf.dispose(squeezedOutputTensor);

      // Fetch the labelmap and score thresholds, then assign labels to the
      // prediction results.
      const outputHeadMetadata = this.modelMetadata.tfjs_classifier_model_metadata
                                     .output_head_metadata[0];
      let scoreThreshold = 0.0;
      if (outputHeadMetadata.score_threshold != null) {
        scoreThreshold = outputHeadMetadata.score_threshold;
      }
      if (this.labelmap == null && outputHeadMetadata.labelmap_path != null) {
        await this.fetchLabelmap(outputHeadMetadata.labelmap_path);
      }
      for (let i = 0; i < predictions.length; i++) {
        if (predictions[i] > scoreThreshold) {
          if (this.labelmap != null && this.labelmap.length > i) {
            results.push({
              displayName: this.labelmap[i],
              score: predictions[i],
            });
          } else {
            results.push({
              displayName: UNKNOWN_LABEL_DISPLAY_NAME,
              score: predictions[i],
            });
          }
        }
      }
    }

    // Sort remaining results in descending order.
    results.sort((a, b) => {
      if (a.score > b.score) {
        return -1;
      }
      return 1;
    });

    // Keep a maximum of MAX_NB_RESULTS for the UI.
    if (results.length > MAX_NB_RESULTS) {
      results = results.slice(0, MAX_NB_RESULTS);
    }

    if (this.imageSelectedIndex === index) {
      // Display results only for the last selected image (as the user may
      // have switched selection while inference was running).
      this.classifierResults = results;
      this.resultsKeyName = 'Type';
      this.resultsValueName = 'Score';
    }
  }