Skip to content

Commit 8bf4bd4

Browse files
committed
COMPONENT/ADD:
Recognition PAGE/ADD: ObjectDetection COMPONENT/UPDATE: Button (add translate prop)
1 parent f15496b commit 8bf4bd4

File tree

9 files changed

+235
-9
lines changed

9 files changed

+235
-9
lines changed

src/components/Button/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ import { TRANSLATE } from '~/services/Translate/types'
1111
interface iBUTTON_PROPS {
1212
onPress : (event : GestureResponderEvent) => void,
1313
style ?: StyleProp<ViewStyle>,
14-
text : keyof TRANSLATE
14+
text : keyof TRANSLATE,
15+
translate ?: boolean
1516
}
1617

1718

18-
function Button ({ onPress, text, style } : iBUTTON_PROPS) {
19+
function Button ({ onPress, text, style, translate = true } : iBUTTON_PROPS) {
1920
return (
2021
<TouchableOpacity
2122
activeOpacity={0.6}
@@ -33,7 +34,7 @@ function Button ({ onPress, text, style } : iBUTTON_PROPS) {
3334
textAlign: 'center'
3435
}}
3536
>
36-
{ Translate(text) }
37+
{ translate ? Translate(text) : text }
3738
</Text>
3839
</View>
3940
</TouchableOpacity>

src/components/Recognition/index.tsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react'
2+
import { Text, useWindowDimensions, View } from 'react-native'
3+
4+
5+
export type RECOGNITION = {
6+
detectedClass : string,
7+
confidenceInClass : number,
8+
rect : {
9+
x : number,
10+
y : number,
11+
w : number,
12+
h : number
13+
}
14+
}
15+
16+
interface iRECOGNITION_PROPS {
17+
recognition : RECOGNITION[]
18+
}
19+
20+
21+
function Recognition ({ recognition } : iRECOGNITION_PROPS) {
22+
const { width, height } = useWindowDimensions()
23+
const isPortrait = height >= width
24+
25+
26+
return recognition.map((response, key) => {
27+
const { detectedClass } = response
28+
const { x, y, w, h } = response.rect
29+
let left, top, width, height
30+
left = x * 97 + '%'
31+
width = w * 100 + '%'
32+
if (isPortrait) {
33+
top = y * 94 + '%'
34+
height = h * 62 + '%'
35+
}
36+
else {
37+
top = y * 100 + '%'
38+
height = h * 100 + '%'
39+
}
40+
41+
42+
return (
43+
<View
44+
key={key}
45+
style={{
46+
position: 'absolute', borderColor: '#ff033e', borderWidth: 2,
47+
left, top, width, height
48+
}}
49+
>
50+
<Text
51+
style={{
52+
color: '#fff', fontSize: 14, fontWeight: 'bold'
53+
}}
54+
>
55+
{ detectedClass }
56+
</Text>
57+
</View>
58+
)
59+
})
60+
}
61+
62+
63+
export default Recognition

src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Button from './Button'
33
import ButtonContainer from './ButtonContainer'
44
import CameraNotAuthorized from './CameraNotAuthorized'
55
import ImagePreview from './ImagePreview'
6+
import Recognition from './Recognition'
67
import Result from './Result'
78
import Title from './Title'
89

@@ -13,6 +14,7 @@ export {
1314
ButtonContainer,
1415
CameraNotAuthorized,
1516
ImagePreview,
17+
Recognition,
1618
Result,
1719
Title
1820
}

src/pages/ObjectDetection/index.tsx

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import React, { useState, useEffect } from 'react'
2+
import { Alert } from 'react-native'
3+
// @ts-ignore
4+
import Tflite from 'tflite-react-native'
5+
6+
import { ChooseFile, TakePicture, Translate } from '~/services'
7+
8+
import { Button, ButtonContainer, ImagePreview, Recognition, Title } from '~/components'
9+
10+
import { RECOGNITION } from '~/components/Recognition'
11+
12+
13+
type MODELS = {
14+
ssdMobileNet : () => any,
15+
yolo : () => any
16+
}
17+
18+
19+
const tflite = new Tflite()
20+
21+
22+
function ObjectDetection () {
23+
const [chosenModel, setChosenModel] = useState<keyof MODELS | null>(null)
24+
const [fileUri, setFileUri] = useState('')
25+
const [recognition, setRecognition] = useState<RECOGNITION[]>([])
26+
27+
28+
const loadModel : MODELS = {
29+
ssdMobileNet: () => tflite.loadModel({
30+
model: 'models/ssd_mobilenet.tflite',
31+
labels: 'models/ssd_mobilenet.txt',
32+
numThreads: 1
33+
},
34+
(error : string) => {
35+
if (error) {
36+
Alert.alert(Translate('error'), Translate('errorLoadModel'))
37+
}
38+
}),
39+
yolo: () => tflite.loadModel({
40+
model: 'models/yolov2_tiny.tflite',
41+
labels: 'models/yolov2_tiny.txt',
42+
numThreads: 1
43+
},
44+
(error : string) => {
45+
if (error) {
46+
Alert.alert(Translate('error'), Translate('errorLoadModel'))
47+
}
48+
})
49+
}
50+
51+
52+
const performObjectDetection : MODELS = {
53+
ssdMobileNet: () => tflite.detectObjectOnImage({
54+
path: fileUri,
55+
model: 'SSDMobileNet',
56+
imageMean: 127.5,
57+
imageStd: 127.5,
58+
threshold: 0.3,
59+
numResultsPerClass: 2
60+
},
61+
(error : string, response : RECOGNITION[]) => {
62+
if (error) {
63+
Alert.alert(Translate('error'), Translate('errorProcessingTflite'))
64+
return
65+
}
66+
setRecognition(response)
67+
}),
68+
yolo: () => tflite.detectObjectOnImage({
69+
path: fileUri,
70+
model: 'YOLO',
71+
imageMean: 0.0,
72+
imageStd: 255.0,
73+
threshold: 0.3,
74+
numResultsPerClass: 2
75+
},
76+
(error : string, response : RECOGNITION[]) => {
77+
if (error) {
78+
Alert.alert(Translate('error'), Translate('errorProcessingTflite'))
79+
return
80+
}
81+
setRecognition(response)
82+
})
83+
}
84+
85+
86+
function ChooseModel () {
87+
return (
88+
<>
89+
<Title text='chooseModel' />
90+
<ButtonContainer style={{ width: '60%', maxWidth: 300 }}>
91+
<Button
92+
onPress={() => setChosenModel('ssdMobileNet')}
93+
text='SSD MobileNet'
94+
translate={false}
95+
/>
96+
<Button
97+
onPress={() => setChosenModel('yolo')}
98+
text='Tiny YOLO'
99+
translate={false}
100+
/>
101+
</ButtonContainer>
102+
</>
103+
)
104+
}
105+
106+
107+
useEffect(() => {
108+
if (chosenModel && fileUri) {
109+
performObjectDetection[chosenModel]()
110+
}
111+
}, [chosenModel, fileUri])
112+
113+
114+
useEffect(() => {
115+
if (chosenModel) {
116+
loadModel[chosenModel]()
117+
}
118+
119+
return () => {
120+
if (chosenModel) {
121+
tflite.close()
122+
}
123+
}
124+
}, [chosenModel])
125+
126+
127+
if (!chosenModel) return (
128+
<ChooseModel />
129+
)
130+
131+
132+
return (
133+
<>
134+
<Title text='pickImagesCG' />
135+
<ImagePreview uri={fileUri}>
136+
{ /* @ts-ignore */ recognition && (
137+
<Recognition recognition={recognition} />
138+
) }
139+
</ImagePreview>
140+
<ButtonContainer style={{ width: '60%', maxWidth: 300 }}>
141+
<Button onPress={() => ChooseFile(setFileUri)} text='chooseFile' />
142+
<Button onPress={() => TakePicture(setFileUri)} text='takePicture' />
143+
</ButtonContainer>
144+
</>
145+
)
146+
}
147+
148+
149+
export default ObjectDetection

src/pages/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { NAVIGATE } from './Home'
44
import ImageClassification from './ImageClassification'
55
import ImageClassificationLiveFeed from './ImageClassificationLiveFeed'
66
import ImageSegmentation from './ImageSegmentation'
7+
import ObjectDetection from './ObjectDetection'
78

89

910
export interface iPAGES_PROPS {
@@ -18,7 +19,8 @@ export interface iPAGES {
1819
FruitRecognitionLiveFeed : PAGE,
1920
ImageClassification : PAGE,
2021
ImageClassificationLiveFeed : PAGE,
21-
ImageSegmentation : PAGE
22+
ImageSegmentation : PAGE,
23+
ObjectDetection : PAGE
2224
}
2325

2426

@@ -27,7 +29,8 @@ const PAGES : iPAGES = {
2729
FruitRecognitionLiveFeed,
2830
ImageClassification,
2931
ImageClassificationLiveFeed,
30-
ImageSegmentation
32+
ImageSegmentation,
33+
ObjectDetection
3134
}
3235

3336

src/services/Translate/en-US.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const EN_US : TRANSLATE = {
55
appName: 'Machine Learning React Native Practical Guide',
66
chooseFile: 'Choose File',
77
chooseFunction: 'Choose a function:',
8+
chooseModel: 'Choose a model:',
89
error: 'Error',
910
errorLoadModel: 'Error trying to load TensorFlow Lite model.',
1011
errorProcessingTflite: 'Something went wrong while processing in TensorFlow Lite.',
@@ -22,7 +23,8 @@ const EN_US : TRANSLATE = {
2223
Home: 'Home',
2324
ImageClassification: 'Image Classification',
2425
ImageClassificationLiveFeed: 'Image Classification Live',
25-
ImageSegmentation: 'Image Segmentation'
26+
ImageSegmentation: 'Image Segmentation',
27+
ObjectDetection: 'Object Detection'
2628
}
2729

2830

src/services/Translate/es-ES.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const ES_ES : TRANSLATE = {
55
appName: 'Guía Práctica de Aprendizaje de Máquina React Native',
66
chooseFile: 'Elegir Archivo',
77
chooseFunction: 'Elige una función:',
8+
chooseModel: 'Escoge un modelo:',
89
error: 'Error',
910
errorLoadModel: 'Error al intentar cargar modelo de TensorFlow Lite.',
1011
errorProcessingTflite: 'Algo salió mal durante el procesamiento en TensorFlow Lite.',
@@ -22,7 +23,8 @@ const ES_ES : TRANSLATE = {
2223
Home: 'Home',
2324
ImageClassification: 'Clasificación de Imagen',
2425
ImageClassificationLiveFeed: 'Clasificación de Imagen En Vivo',
25-
ImageSegmentation: 'Segmentación de Imagen'
26+
ImageSegmentation: 'Segmentación de Imagen',
27+
ObjectDetection: 'Detección de Objetos'
2628
}
2729

2830

src/services/Translate/pt-BR.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const PT_BR : TRANSLATE = {
55
appName: 'Guia Prático de Aprendizado de Máquina React Native',
66
chooseFile: 'Escolher Arquivo',
77
chooseFunction: 'Escolha uma função:',
8+
chooseModel: 'Escolha um modelo:',
89
error: 'Erro',
910
errorLoadModel: 'Erro ao tentar carregar modelo do TensorFlow Lite.',
1011
errorProcessingTflite: 'Algo deu errado durante o processamento no TensorFlow Lite.',
@@ -22,7 +23,8 @@ const PT_BR : TRANSLATE = {
2223
Home: 'Home',
2324
ImageClassification: 'Classificação de Imagem',
2425
ImageClassificationLiveFeed: 'Classificação de Imagem Ao Vivo',
25-
ImageSegmentation: 'Segmentação de Imagem'
26+
ImageSegmentation: 'Segmentação de Imagem',
27+
ObjectDetection: 'Detecção de Objetos'
2628
}
2729

2830

src/services/Translate/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export type TRANSLATE = {
33
appName : string,
44
chooseFile : string,
55
chooseFunction : string,
6+
chooseModel : string,
67
error : string,
78
errorLoadModel : string,
89
errorProcessingTflite : string,
@@ -20,5 +21,6 @@ export type TRANSLATE = {
2021
Home : string,
2122
ImageClassification : string,
2223
ImageClassificationLiveFeed : string,
23-
ImageSegmentation : string
24+
ImageSegmentation : string,
25+
ObjectDetection : string
2426
}

0 commit comments

Comments
 (0)