Использование face-api.js в Cordova с Android - PullRequest
0 голосов
/ 11 июня 2019

Cordova не позволяет загружать локальные файлы в тренинг TensorFlow, используемый в face-api.js, однако эта проблема не возникает в iOS или браузере. Как решить?

1 Ответ

0 голосов
/ 11 июня 2019

Чтобы загрузить файлы локально, которые будут распакованы и использованы для обучения в TensorFlow, вы должны сообщить библиотеке Face-api.js, какой метод будет вызываться для чтения файлов, задав значения в faceapi.env.monkeyPatch.

Не могу сказать, что это лучшее решение, но это было решение, которое сработало.Я отделил платформу Android от других платформ (что проблем нет), а внутри Android я отделил файлы JSON от бинарных файлов.

Вот полный пример, учитывающий загрузку изображения 512x512 вместе сface:

PS: код Javascript в VueJS.

Список плагинов

cordoba-plugin-device

cordova-plugin-file

App.vue

<script>
import * as faceapi from "face-api.js";

export default {
  data: () => ({}),
  mounted() {
    let cls = this;
    document.addEventListener(
      "deviceready",
      function() {
        cls.loadFaceDetectModels();
      },
      false
    );
  },
  methods: {
    async loadFaceDetectModels() {
      let MODEL_URL;
      if (window.device.platform === "Android") {
        MODEL_URL =
          window.cordova.file.applicationDirectory + "www/static/models/";
        faceapi.env.monkeyPatch({
          readFile: filePath =>
            new Promise(resolve => {
              window.resolveLocalFileSystemURL(
                filePath,
                function(fileEntry) {
                  fileEntry.file(
                    function(file) {
                      var reader = new FileReader();

                      let fileExtension = filePath
                        .split("?")[0]
                        .split(".")
                        .pop();
                      if (fileExtension === "json") {
                        reader.onloadend = function() {
                          resolve(this.result);
                        };
                        reader.readAsText(file);
                      } else {
                        reader.onloadend = function() {
                          resolve(new Uint8Array(this.result));
                        };

                        reader.readAsArrayBuffer(file);
                      }
                    },
                    function() {
                      resolve(false);
                    }
                  );
                },
                function() {
                  resolve(false);
                }
              );
            }),
          Canvas: HTMLCanvasElement,
          Image: HTMLImageElement,
          ImageData: ImageData,
          Video: HTMLVideoElement,
          createCanvasElement: () => document.createElement("canvas"),
          createImageElement: () => document.createElement("img")
        });
        await faceapi.nets.tinyFaceDetector.loadFromDisk(MODEL_URL);
        await faceapi.nets.faceRecognitionNet.loadFromDisk(MODEL_URL);
      } else {
        MODEL_URL = "./static/models";
        await faceapi.loadTinyFaceDetectorModel(MODEL_URL);
        await faceapi.loadFaceRecognitionModel(MODEL_URL);
      }

      this.testFaceDetector();
    },
    testFaceDetector() {
      let cls = this;
      let baseImage = new Image();
      baseImage.src = "./static/img/faceWillSmith.jpg";
      baseImage.onload = function() {
        faceapi
          .detectSingleFace(baseImage, new faceapi.TinyFaceDetectorOptions())
          .run()
          .then(res => {
            alert(JSON.stringify(res));
          });
      };
    }
  }
};
</script>

config.xml

<platform name="android">
    <allow-intent href="market:*" />
    <preference name="loadUrlTimeoutValue" value="700000" />
    <preference name="android-minSdkVersion" value="21" />
    <preference name="android-targetSdkVersion" value="21" />
    <preference name="AndroidPersistentFileLocation" value="Compatibility" />
    <preference name="AndroidPersistentFileLocation" value="Internal" />
    <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,assets,root,applicationDirectory" />
</platform>
...