@@ -26,12 +26,19 @@ import {
2626} from 'react-native-vision-camera' ;
2727import { createSynchronizable , scheduleOnRN } from 'react-native-worklets' ;
2828import {
29- DEEPLAB_V3_RESNET50 ,
29+ DEEPLAB_V3_RESNET50_QUANTIZED ,
30+ DEEPLAB_V3_RESNET101_QUANTIZED ,
31+ DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED ,
32+ LRASPP_MOBILENET_V3_LARGE_QUANTIZED ,
33+ FCN_RESNET50_QUANTIZED ,
34+ FCN_RESNET101_QUANTIZED ,
35+ SELFIE_SEGMENTATION ,
3036 Detection ,
3137 EFFICIENTNET_V2_S ,
38+ RF_DETR_NANO ,
3239 SSDLITE_320_MOBILENET_V3_LARGE ,
3340 useClassification ,
34- useImageSegmentation ,
41+ useSemanticSegmentation ,
3542 useObjectDetection ,
3643} from 'react-native-executorch' ;
3744import {
@@ -48,7 +55,17 @@ import Spinner from '../../components/Spinner';
4855import ColorPalette from '../../colors' ;
4956
5057type TaskId = 'classification' | 'objectDetection' | 'segmentation' ;
51- type ModelId = 'classification' | 'objectDetection' | 'segmentation' ;
58+ type ModelId =
59+ | 'classification'
60+ | 'objectDetection_ssdlite'
61+ | 'objectDetection_rfdetr'
62+ | 'segmentation_deeplab_resnet50'
63+ | 'segmentation_deeplab_resnet101'
64+ | 'segmentation_deeplab_mobilenet'
65+ | 'segmentation_lraspp'
66+ | 'segmentation_fcn_resnet50'
67+ | 'segmentation_fcn_resnet101'
68+ | 'segmentation_selfie' ;
5269
5370type TaskVariant = { id : ModelId ; label : string } ;
5471type Task = { id : TaskId ; label : string ; variants : TaskVariant [ ] } ;
@@ -62,12 +79,23 @@ const TASKS: Task[] = [
6279 {
6380 id : 'segmentation' ,
6481 label : 'Segment' ,
65- variants : [ { id : 'segmentation' , label : 'DeepLab V3' } ] ,
82+ variants : [
83+ { id : 'segmentation_deeplab_resnet50' , label : 'DeepLab ResNet50' } ,
84+ { id : 'segmentation_deeplab_resnet101' , label : 'DeepLab ResNet101' } ,
85+ { id : 'segmentation_deeplab_mobilenet' , label : 'DeepLab MobileNet' } ,
86+ { id : 'segmentation_lraspp' , label : 'LRASPP MobileNet' } ,
87+ { id : 'segmentation_fcn_resnet50' , label : 'FCN ResNet50' } ,
88+ { id : 'segmentation_fcn_resnet101' , label : 'FCN ResNet101' } ,
89+ { id : 'segmentation_selfie' , label : 'Selfie' } ,
90+ ] ,
6691 } ,
6792 {
6893 id : 'objectDetection' ,
6994 label : 'Detect' ,
70- variants : [ { id : 'objectDetection' , label : 'SSDLite MobileNet' } ] ,
95+ variants : [
96+ { id : 'objectDetection_ssdlite' , label : 'SSDLite MobileNet' } ,
97+ { id : 'objectDetection_rfdetr' , label : 'RF-DETR Nano' } ,
98+ ] ,
7199 } ,
72100] ;
73101
@@ -129,20 +157,76 @@ export default function VisionCameraScreen() {
129157 model : EFFICIENTNET_V2_S ,
130158 preventLoad : activeModel !== 'classification' ,
131159 } ) ;
132- const objectDetection = useObjectDetection ( {
160+ const objectDetectionSsdlite = useObjectDetection ( {
133161 model : SSDLITE_320_MOBILENET_V3_LARGE ,
134- preventLoad : activeModel !== 'objectDetection ' ,
162+ preventLoad : activeModel !== 'objectDetection_ssdlite ' ,
135163 } ) ;
136- const segmentation = useImageSegmentation ( {
137- model : DEEPLAB_V3_RESNET50 ,
138- preventLoad : activeModel !== 'segmentation ' ,
164+ const objectDetectionRfdetr = useObjectDetection ( {
165+ model : RF_DETR_NANO ,
166+ preventLoad : activeModel !== 'objectDetection_rfdetr ' ,
139167 } ) ;
140168
141- const activeIsGenerating = {
142- classification : classification . isGenerating ,
143- objectDetection : objectDetection . isGenerating ,
144- segmentation : segmentation . isGenerating ,
145- } [ activeModel ] ;
169+ const activeObjectDetection =
170+ {
171+ objectDetection_ssdlite : objectDetectionSsdlite ,
172+ objectDetection_rfdetr : objectDetectionRfdetr ,
173+ } [ activeModel as 'objectDetection_ssdlite' | 'objectDetection_rfdetr' ] ??
174+ null ;
175+ const segDeeplabResnet50 = useSemanticSegmentation ( {
176+ model : DEEPLAB_V3_RESNET50_QUANTIZED ,
177+ preventLoad : activeModel !== 'segmentation_deeplab_resnet50' ,
178+ } ) ;
179+ const segDeeplabResnet101 = useSemanticSegmentation ( {
180+ model : DEEPLAB_V3_RESNET101_QUANTIZED ,
181+ preventLoad : activeModel !== 'segmentation_deeplab_resnet101' ,
182+ } ) ;
183+ const segDeeplabMobilenet = useSemanticSegmentation ( {
184+ model : DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED ,
185+ preventLoad : activeModel !== 'segmentation_deeplab_mobilenet' ,
186+ } ) ;
187+ const segLraspp = useSemanticSegmentation ( {
188+ model : LRASPP_MOBILENET_V3_LARGE_QUANTIZED ,
189+ preventLoad : activeModel !== 'segmentation_lraspp' ,
190+ } ) ;
191+ const segFcnResnet50 = useSemanticSegmentation ( {
192+ model : FCN_RESNET50_QUANTIZED ,
193+ preventLoad : activeModel !== 'segmentation_fcn_resnet50' ,
194+ } ) ;
195+ const segFcnResnet101 = useSemanticSegmentation ( {
196+ model : FCN_RESNET101_QUANTIZED ,
197+ preventLoad : activeModel !== 'segmentation_fcn_resnet101' ,
198+ } ) ;
199+ const segSelfie = useSemanticSegmentation ( {
200+ model : SELFIE_SEGMENTATION ,
201+ preventLoad : activeModel !== 'segmentation_selfie' ,
202+ } ) ;
203+
204+ const activeSegmentation =
205+ {
206+ segmentation_deeplab_resnet50 : segDeeplabResnet50 ,
207+ segmentation_deeplab_resnet101 : segDeeplabResnet101 ,
208+ segmentation_deeplab_mobilenet : segDeeplabMobilenet ,
209+ segmentation_lraspp : segLraspp ,
210+ segmentation_fcn_resnet50 : segFcnResnet50 ,
211+ segmentation_fcn_resnet101 : segFcnResnet101 ,
212+ segmentation_selfie : segSelfie ,
213+ } [
214+ activeModel as
215+ | 'segmentation_deeplab_resnet50'
216+ | 'segmentation_deeplab_resnet101'
217+ | 'segmentation_deeplab_mobilenet'
218+ | 'segmentation_lraspp'
219+ | 'segmentation_fcn_resnet50'
220+ | 'segmentation_fcn_resnet101'
221+ | 'segmentation_selfie'
222+ ] ?? null ;
223+
224+ const activeIsGenerating =
225+ activeModel === 'classification'
226+ ? classification . isGenerating
227+ : activeModel . startsWith ( 'objectDetection' )
228+ ? ( activeObjectDetection ?. isGenerating ?? false )
229+ : ( activeSegmentation ?. isGenerating ?? false ) ;
146230
147231 useEffect ( ( ) => {
148232 setGlobalGenerating ( activeIsGenerating ) ;
@@ -211,8 +295,8 @@ export default function VisionCameraScreen() {
211295 ) ;
212296
213297 const classRof = classification . runOnFrame ;
214- const detRof = objectDetection . runOnFrame ;
215- const segRof = segmentation . runOnFrame ;
298+ const detRof = activeObjectDetection ? .runOnFrame ?? null ;
299+ const segRof = activeSegmentation ? .runOnFrame ?? null ;
216300
217301 useEffect ( ( ) => {
218302 frameKillSwitch . setBlocking ( true ) ;
@@ -255,7 +339,7 @@ export default function VisionCameraScreen() {
255339 }
256340 scheduleOnRN ( updateClass , { label : bestLabel , score : bestScore } ) ;
257341 }
258- } else if ( activeModel === 'objectDetection' ) {
342+ } else if ( activeModel . startsWith ( 'objectDetection' ) ) {
259343 if ( ! detRof ) return ;
260344 const iw = frame . width > frame . height ? frame . height : frame . width ;
261345 const ih = frame . width > frame . height ? frame . width : frame . height ;
@@ -267,7 +351,7 @@ export default function VisionCameraScreen() {
267351 imageHeight : ih ,
268352 } ) ;
269353 }
270- } else if ( activeModel === 'segmentation' ) {
354+ } else if ( activeModel . startsWith ( 'segmentation' ) ) {
271355 if ( ! segRof ) return ;
272356 const result = segRof ( frame , [ ] , false ) ;
273357 if ( result ?. ARGMAX ) {
@@ -313,17 +397,19 @@ export default function VisionCameraScreen() {
313397 ) ,
314398 } ) ;
315399
316- const activeIsReady = {
317- classification : classification . isReady ,
318- objectDetection : objectDetection . isReady ,
319- segmentation : segmentation . isReady ,
320- } [ activeModel ] ;
400+ const activeIsReady =
401+ activeModel === 'classification'
402+ ? classification . isReady
403+ : activeModel . startsWith ( 'objectDetection' )
404+ ? ( activeObjectDetection ?. isReady ?? false )
405+ : ( activeSegmentation ?. isReady ?? false ) ;
321406
322- const activeDownloadProgress = {
323- classification : classification . downloadProgress ,
324- objectDetection : objectDetection . downloadProgress ,
325- segmentation : segmentation . downloadProgress ,
326- } [ activeModel ] ;
407+ const activeDownloadProgress =
408+ activeModel === 'classification'
409+ ? classification . downloadProgress
410+ : activeModel . startsWith ( 'objectDetection' )
411+ ? ( activeObjectDetection ?. downloadProgress ?? 0 )
412+ : ( activeSegmentation ?. downloadProgress ?? 0 ) ;
327413
328414 if ( ! cameraPermission . hasPermission ) {
329415 return (
@@ -393,7 +479,7 @@ export default function VisionCameraScreen() {
393479 } )
394480 }
395481 >
396- { activeModel === 'segmentation' && maskImage && (
482+ { activeModel . startsWith ( 'segmentation' ) && maskImage && (
397483 < Canvas style = { StyleSheet . absoluteFill } >
398484 < SkiaImage
399485 image = { maskImage }
@@ -406,7 +492,7 @@ export default function VisionCameraScreen() {
406492 </ Canvas >
407493 ) }
408494
409- { activeModel === 'objectDetection' && (
495+ { activeModel . startsWith ( 'objectDetection' ) && (
410496 < >
411497 { detections . map ( ( det , i ) => {
412498 const left = det . bbox . x1 * detScale + detOX ;
@@ -480,7 +566,6 @@ export default function VisionCameraScreen() {
480566 horizontal
481567 showsHorizontalScrollIndicator = { false }
482568 contentContainerStyle = { styles . tabsContent }
483- pointerEvents = "box-none"
484569 >
485570 { TASKS . map ( ( t ) => (
486571 < TouchableOpacity
@@ -507,7 +592,6 @@ export default function VisionCameraScreen() {
507592 horizontal
508593 showsHorizontalScrollIndicator = { false }
509594 contentContainerStyle = { styles . chipsContent }
510- pointerEvents = "box-none"
511595 >
512596 { activeTaskInfo . variants . map ( ( v ) => (
513597 < TouchableOpacity
0 commit comments