React native tensorflow reconhecimento de imagem

Para quem não conhece tesorflow, recomendo fortemente ler esse post. Nele demostramos como fazer o treinamento de uma rede neural com Tensorflow para reconhecimento de padrões em imagens. Treinamos nossa rede para reconhecer se uma foto é do mestre Yoda ou Darth vader. 

O modelo da nossa rede neural fica armazenada em um arquivo. Nesse post mostramos como gerar um model para ser utilizado em dispositivos móveis. Para fazer esse mesmo reconhecimento de imagem usando React native, vamos usar esse mesmo arquivo que já deixei compactado para baixar aqui

Como de costume, vamos usar como exemplo o projeto criado nesse post. Agora vamos instalar a depedência do Tensorflow para React native executando esse comando na raiz do projeto:

npm install react-native-tensorflow --save

e depois esse outro comando 

react-native link react-native-tensorflow

Agora vamos no arquivo android/app/build.gradle e conferir se existe essa linha na chave dependencies{ ...

dependencies {
          ... 
          compile project(':react-native-tensorflow') 
          ...
}

Se não existir, adicione manualmente. Agora vamos fazer o mesmo parar o arquivo android/sttings.gradle. Verificar se existe essas linhas:

include ':react-native-tensorflow'
project(':react-native-tensorflow').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-tensorflow/android')

Se não existir, adicione manualmente.

Agora na raiz do projeto, vamos criar uma pasta chamada assets/, baixar uma foto do mestre yoda da internet e colocar dentro dessa pasta. 

Depois baixamos os arquivos .pb e label.txt clique aqui e colocar na pasta assets junto com a foto do mestre yoda:

Imagem

Renomeei os arquivos label.txt para a.txt e star_wars_graph.pg para graph.pb. Se quiser pode dixar com mesmo nome, não tem problema. Não esquecer de referenciar os arquivos pelos nomes corretos no App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */
import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableHighlight
} from 'react-native';
import { TfImageRecognition } from 'react-native-tensorflow';
type Props = {};
export default class App extends Component<Props> {
  constructor(props) {
    super(props)
    this.state = {texto:''}
  }    
    
  vai = async function(){
    
    this.setState({
        ...this.state,
        texto:'carregando...'
    });
    
    const tfImageRecognition = new TfImageRecognition({
      model: require('./assets/graph.pb'),
      labels: require('./assets/a.txt'),
      imageMean: 117, // Optional, defaults to 117
      imageStd: 1 // Optional, defaults to 1
    });
  
    this.setState({
        ...this.state,
        texto:'foi!!!'
    });
    
    const results = await tfImageRecognition.recognize({
      image: require('./assets/YodaWhiteHouse.jpg'),
      inputName: "Mul", //Optional, defaults to "input"
      inputSize: 299, //Optional, defaults to 224
      imageMean:128,
      imageStd:128,
      outputName: "final_result", //Optional, defaults to "output"
      maxResults: 3, //Optional, defaults to 3
      threshold: 0.1, //Optional, defaults to 0.1
    })
    results.forEach(result =>
      this.setState({
            ...this.state,
            texto:`${this.state.texto} ${result.id} ${result.name} ${result.confidence} `
        })
    )
    
  }    
    
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          {this.state.texto}
        </Text>
        <TouchableHighlight 
            onPress={this.vai.bind(this)}
        >
        <Image source={require('./assets/YodaWhiteHouse.jpg')} />
        </TouchableHighlight>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

Os nomes dos arquivos YodaWhiteHouse.jpg, a.txt e graph.pb deve corresponder aos nomes dos arquivo na pasta assets.

Na documentação oficial mostra as configurações feitas usando u m mode na arquitetura inception-v1 mas como estamos usando um model treinado com inception-v3, alteramos as configurações correspondentes para inception v3

Se tudo estiver ok, basta executar o app, clicar na foto do mestre yoda e ver o resultado:

Imagem

Comentários

 

(há 1 ano) WILLIAN ROSA DUARTE:

Olá, testei aqui esse algoritmo, porem o react-native impaca na parte do require dos arquivos dando erro de unable to resolve module e diz Indeed, none of theses file exist.
Os arquivos estão todos la nesse mesmo diretorio que coloquei, o problema mesmo está sendo que ele não está reconhecendo esse formato de arquivo .txt e .pb


Aqui está o código:

import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    View,
    Image,
    TouchableHighlight
} from 'react-native';
import { TfImageRecognition } from 'react-native-tensorflow';

type Props = {};
export default class App extends Component<Props> {
    constructor(props) {
        super(props)

        this.state = {
          texto: ''
        }
    }

    vai = async function(){
        this.setState({texto: 'carregando...'});

        const tfImageRecognition = new TfImageRecognition({
            model: require('./android/app/src/main/assets/graph.pb'),
            labels: require('./android/app/src/main/assets/a.txt'),
            imageMean: 117, // Optional, defaults to 117
            imageStd: 1 // Optional, defaults to 1
        });

        this.setState({texto: 'foi!!!'});

        const results = await tfImageRecognition.recognize({
            image: require('./android/app/src/main/assets/YodaWhiteHouse.jpg'),
            inputName: "Mul", //Optional, defaults to "input"
            inputSize: 299, //Optional, defaults to 224
            imageMean:128,
            imageStd:128,
            outputName: "final_result", //Optional, defaults to "output"
            maxResults: 3, //Optional, defaults to 3
            threshold: 0.1, //Optional, defaults to 0.1
        })
        results.forEach((result) => {
          this.setState({texto: this.state.texto+' '+result.id+' '+result.name})
        })

    }

    render() {
        return (
            <View style={styles.container}>
              <Text style={styles.welcome}>
                Welcome to React Native!
              </Text>
              <Text style={styles.instructions}>
                  {this.state.texto}
              </Text>
              <TouchableHighlight
                  onPress={this.vai.bind(this)}
              >
                <Image source={require('./android/app/src/main/assets/YodaWhiteHouse.jpg')} />
              </TouchableHighlight>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

 

 

 
[responder]
 
(há 1 ano) WILLIAN ROSA DUARTE:

David, refiz tudo novamente, iniciei um novo projeto, fiz a instalação do tensorFlow, linkei e confirmei e ta tudo certo as referencias e a própria instalação dele no node modules,
Criei a pasta assets na pasta raiz do projeto, contendo os 4 arquivos:

a.txt 

graph.pb

yoda.jpg

YodaWhiteHouse.jpg

 

Coloquei a referencia correta, ./assets/nomedoarquivocorreto e mesmo assim da no mesmo erro do projeto anterior que tinha feito também do zero, onde reclama do

originModulePath: "E\\Projetos\\tensorFlowExemplo\\App.js,targetModuleName":"./assets/graph.pb","message":"Unable to resolve module './assets/graph.pb' from E\\Projetos\\testes\\tensorFlow\\App.js": The module ./assets/graph.pb' could not be found from 'E:Projetos\\testes\\tensorFlowExemplo\\App.js' indeed, none of theses files exist E tem mais coisa escrita nesse erro.

Já deletei as pastas builds, dei um gradlew.bat clean na pasta android e mandei executar novamente, da no mesmo erro.

Retirei essa função "vai" e comentei ela no touchable, a foto do YodaWhiteHouse.jpg carrega no componente <Image> corretamente e não é apresentado nenhum erro, indicando que a referencia do caminho usado também está correto, todos os 4 arquivos estão certinho na pasta, com os nomes indicados.

Vou adicionar o código aqui e o do package.json, suspeito que seja a versão.


import React, { Component } from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    View,
    Image,
    TouchableHighlight
} from 'react-native';
import { TfImageRecognition } from 'react-native-tensorflow';


type Props = {};
export default class App extends Component<Props> {
    constructor(props) {
        super(props)

        this.state = {
            texto: ''
        }
    }

    vai = async function(){
        this.setState({texto: 'carregando...'});

        const tfImageRecognition = new TfImageRecognition({
            model: require('./assets/graph.pb'),
            labels: require('./assets/a.txt'),
            imageMean: 117, // Optional, defaults to 117
            imageStd: 1 // Optional, defaults to 1
        });

        this.setState({texto: 'foi!!!'});

        const results = await tfImageRecognition.recognize({
            image: require('./assets/YodaWhiteHouse.jpg'),
            inputName: "Mul", //Optional, defaults to "input"
            inputSize: 299, //Optional, defaults to 224
            imageMean:128,
            imageStd:128,
            outputName: "final_result", //Optional, defaults to "output"
            maxResults: 3, //Optional, defaults to 3
            threshold: 0.1, //Optional, defaults to 0.1
        })
        results.forEach((result) => {
            this.setState({texto: this.state.texto+' '+result.id+' '+result.name})
        })

    }

    render() {
        return (
            <View>
              <Text>
                Welcome to React Native!
              </Text>
              <Text>
                  {this.state.texto}
              </Text>
              <TouchableHighlight
                  onPress={this.vai.bind(this)}
              >
                <Image source={require('./assets/YodaWhiteHouse.jpg')} />
              </TouchableHighlight>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

 

 

 

Esse aqui é o package.json

 

{
  "name": "tensorFlowExemplo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.3.1",
    "react-native": "0.55.4",
    "react-native-tensorflow": "^0.1.7"
  },
  "devDependencies": {
    "babel-jest": "23.0.1",
    "babel-preset-react-native": "4.0.0",
    "jest": "23.1.0",
    "react-test-renderer": "16.3.1"
  },
  "jest": {
    "preset": "react-native"
  }
}


OBS: Esse projeto do react-native que estou fazendo é gerado usando o comando react-native init nomeDoProjeto

Talvez até seja esse o problema, por que lembro que a duas maneiras de se criar um novo projeto, uma através do Expo usando create alguma coisa e esse que é puro, não utiliza o Expo.

(há 1 ano) Davi Sousa:

Willian,

Esse print no final do post foi tirado de um projeto criado do zero no react native e com o código exatamente como está aí.

Nem precisa colocar o caminho absoluto ./android/app/src/main/assets/.. basta colocar o caminho relativo mesmo ./assets/.. 

No erro que aparece diz "..resolve module e diz Indeed, none of theses file exist..." Lambrando que você deve baixar os arquivo .txt e bp para dentro da pasta assets que fica dentro do projeto. Assim também como a imagem a ser classificada com nome YodaWhiteHouse.jpg 

Recomendo que verifique se tanto o arquivo YodaWhiteHouse.jpg como os .txt e .bp existem e estão com os mesmos nomes nos requires.

É recomendável também extrair o arquivo apk gerado na hora de fazer o deploy e verificar se os arquivos citados acima estão entro da pasta assets.

Se o problema persistir, tente criando um novo projeto do zero. O React não deve reclamar por causa do formato do arquivo .txt nem .bp. Deve funcionar desse jeito mesmo.

Quem Sou

Graduado em ADS (Análise e desenvolvimento de sistemas).

Não sou "devoto" de nenhuma linguagem de programação. Procuro aproveitar o melhor de cada uma de acordo com a necessidade do projeto. Prezo por uma arquitetura bem feita, código limpo, puro e simples! 

anuncio atendente