es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Objeto perdiendo su tipo después de pasar a una función en el script precargado.

Tengo una pequeña aplicación de escritorio que muestra la transmisión de video de una cámara, toma su imagen y la pasa a una red neuronal.

Cuando tomo la imagen, su tipo es Tensor, como se espera, pero después de pasarla a una función responsable de clasificarla, pierde su tipo y se convierte en un objeto simple.

La estructura es la siguiente:

CameraSource <- componente Vue.js, responsable de mostrar la transmisión de video dentro del elemento `

ImageRecognizer <- clase simple, que utiliza @tensorflow/tfjs-node y se precarga en la ventana.

Ahora el código es el siguiente:

CameraSource.vue

async test() {
      let vid: HTMLVideoElement = this.$refs.camera_preview as HTMLVideoElement;
      const img = tf.browser.fromPixels(vid);
      console.log(img); <- aquí es un Tensor
      await window.api.test(img);
}

image_recognition.ts

public async checkForObject(image: tf.Tensor): Promise<><tf.rank> | tf.Tensor<tf.rank>[]> {
        console.log(image); <- aquí pierde su tipo de Tensor y se convierte en un objeto
        let reshaped = image.reshape([-1,720,1280,1]); <- esto no funcionará, ya que la imagen no es un Tensor
        return this.model.predict(image);
}

preload.ts

const imageRecognizer = new ImageRecognition(720, 1280, 3);

contextBridge.exposeInMainWorld("api", {
    test: (image: tf.Tensor): Promise<><tf.rank> | tf.Tensor<tf.rank>[]> => {
        return imageRecognizer.checkForObject(image)
    }
});

Declaración de tipo

declare global {
    interface Window {
        api: {
            test: (image: tf.Tensor) => Promise<><tf.rank> | tf.Tensor<tf.rank>[]>
        }
    }
}

¿Esto está sucediendo porque estoy tratando de pasar el objeto al “backend” de la aplicación de electron? ¿Existe alguna forma de evitar esto?

Tensor perdiendo su tipo</tf.rank></tf.rank></tf.rank></tf.rank></tf.rank></tf.rank>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, esto está sucediendo porque estás pasando el objeto al “backend” de la aplicación de Electron. Cuando pasas un objeto desde el proceso del renderizador al proceso principal en Electron, pasa por un proceso llamado serialización. Durante este proceso, se eliminan los métodos y descriptores de propiedades del objeto, lo que resulta en un objeto plano.

    Para evitar esto, puedes serializar el tensor antes de pasarlo al proceso principal y deserializarlo una vez que llegue, o puedes usar un paquete como @tensorflow/tfjs-node-electron que proporciona una forma de usar toda la potencia de TensorFlow.js en Electron sin perder el tipo del tensor.

    Para serializar el tensor, puedes usar el método tf.tensor.toString() para convertirlo en una cadena, y luego pasar esta cadena al proceso principal. Una vez que llegue al proceso principal, puedes usar el método tf.tensor() para convertirlo nuevamente en un tensor.

    // En CameraSource.vue
    async test() {
      let vid: HTMLVideoElement = this.$refs.camera_preview as HTMLVideoElement;
      const img = tf.browser.fromPixels(vid);
      const serializedImg = img.toString(); // serializa el tensor
      await window.api.test(serializedImg);
    }
    
    // En image_recognition.ts
    public async checkForObject(image: string): Promise<><tf.rank> | tf.Tensor<tf.rank>[]> {
      const deserializedImg = tf.tensor(image); // deserializa el tensor
      console.log(deserializedImg); // esto debería ser un tensor
      let reshaped = deserializedImg.reshape([-1,720,1280,1]);
      return this.model.predict(deserializedImg);
    }
    

    Alternativamente, como se mencionó antes, puedes usar @tensorflow/tfjs-node-electron para preservar el tipo del tensor. Así es como puedes usarlo:

    // En preload.ts
    import * as tfn from '@tensorflow/tfjs-node-electron';
    
    const imageRecognizer = new ImageRecognition(720, 1280, 3);
    
    // Reemplaza tf con tfn
    contextBridge.exposeInMainWorld("api", {
      test: (image: tf.Tensor): Promise<><tf.rank> | tf.Tensor<tf.rank>[]> => {
          return imageRecognizer.checkForObject(tfn.tensor(image.dataSync(), image.shape));
      }
    });
    
    // En image_recognition.ts
    import * as tfn from '@tensorflow/tfjs-node-electron';
    
    public async checkForObject(image: tf.Tensor): Promise<><tf.rank> | tf.Tensor<tf.rank>[]> {
      console.log(image); // esto debería ser un tensor
      let reshaped = image.reshape([-1,720,1280,1]);
      return this.model.predict(image);
    }
    

    Con @tensorflow/tfjs-node-electron, puedes convertir el tensor de ida y vuelta entre los procesos del renderizador y principal sin perder su tipo.</tf.rank></tf.rank></tf.rank></tf.rank></tf.rank></tf.rank>

Comments are closed.