Skip to content

Commit 751f50c

Browse files
fix: issues after rebase
1 parent 7488857 commit 751f50c

File tree

13 files changed

+251
-304
lines changed

13 files changed

+251
-304
lines changed

apps/computer-vision/app/vision_camera/index.tsx

Lines changed: 117 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,19 @@ import {
2626
} from 'react-native-vision-camera';
2727
import { createSynchronizable, scheduleOnRN } from 'react-native-worklets';
2828
import {
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';
3744
import {
@@ -48,7 +55,17 @@ import Spinner from '../../components/Spinner';
4855
import ColorPalette from '../../colors';
4956

5057
type 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

5370
type TaskVariant = { id: ModelId; label: string };
5471
type 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

apps/computer-vision/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@
3131
"react-native-gesture-handler": "~2.28.0",
3232
"react-native-image-picker": "^7.2.2",
3333
"react-native-loading-spinner-overlay": "^3.0.1",
34-
"react-native-nitro-image": "^0.12.0",
35-
"react-native-nitro-modules": "^0.33.9",
34+
"react-native-nitro-image": "0.13.0",
35+
"react-native-nitro-modules": "0.35.0",
3636
"react-native-reanimated": "~4.2.2",
3737
"react-native-safe-area-context": "~5.6.0",
3838
"react-native-screens": "~4.16.0",
3939
"react-native-svg": "15.15.3",
4040
"react-native-svg-transformer": "^1.5.3",
41-
"react-native-vision-camera": "5.0.0-beta.2",
41+
"react-native-vision-camera": "5.0.0-beta.6",
4242
"react-native-worklets": "0.7.4"
4343
},
4444
"devDependencies": {

packages/react-native-executorch/common/rnexecutorch/host_objects/JsiConversions.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <codecvt>
44
#include <cstdint>
5+
#include <rnexecutorch/models/semantic_segmentation/Types.h>
56
#include <set>
67
#include <span>
78
#include <type_traits>
@@ -580,9 +581,9 @@ getJsiValue(const models::style_transfer::PixelDataResult &result,
580581
return obj;
581582
}
582583

583-
inline jsi::Value
584-
getJsiValue(const models::image_segmentation::SegmentationResult &result,
585-
jsi::Runtime &runtime) {
584+
inline jsi::Value getJsiValue(
585+
const rnexecutorch::models::image_segmentation::SegmentationResult &result,
586+
jsi::Runtime &runtime) {
586587
jsi::Object dict(runtime);
587588

588589
auto argmaxArrayBuffer = jsi::ArrayBuffer(runtime, result.argmax);

packages/react-native-executorch/common/rnexecutorch/host_objects/ModelHostObject.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -180,24 +180,6 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
180180
"generateFromString"));
181181
}
182182

183-
if constexpr (meta::HasGenerateFromFrame<Model>) {
184-
addFunctions(JSI_EXPORT_FUNCTION(
185-
ModelHostObject<Model>,
186-
promiseHostFunction<&Model::generateFromPhonemes>,
187-
"generateFromPhonemes"));
188-
addFunctions(JSI_EXPORT_FUNCTION(
189-
ModelHostObject<Model>,
190-
promiseHostFunction<&Model::streamFromPhonemes>,
191-
"streamFromPhonemes"));
192-
}
193-
194-
if constexpr (meta::HasGenerateFromString<Model>) {
195-
addFunctions(
196-
JSI_EXPORT_FUNCTION(ModelHostObject<Model>,
197-
promiseHostFunction<&Model::generateFromString>,
198-
"generateFromString"));
199-
}
200-
201183
if constexpr (meta::HasGenerateFromFrame<Model>) {
202184
addFunctions(JSI_EXPORT_FUNCTION(
203185
ModelHostObject<Model>, visionHostFunction<&Model::generateFromFrame>,
@@ -210,13 +192,6 @@ template <typename Model> class ModelHostObject : public JsiHostObject {
210192
promiseHostFunction<&Model::generateFromPixels>,
211193
"generateFromPixels"));
212194
}
213-
214-
if constexpr (meta::HasGenerateFromPixels<Model>) {
215-
addFunctions(
216-
JSI_EXPORT_FUNCTION(ModelHostObject<Model>,
217-
visionHostFunction<&Model::generateFromPixels>,
218-
"generateFromPixels"));
219-
}
220195
}
221196

222197
// A generic host function that runs synchronously, works analogously to the

packages/react-native-executorch/common/rnexecutorch/metaprogramming/TypeConcepts.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,6 @@ concept HasGenerateFromPixels = requires(T t) {
2626
{ &T::generateFromPixels };
2727
};
2828

29-
template <typename T>
30-
concept HasGenerateFromString = requires(T t) {
31-
{ &T::generateFromString };
32-
};
33-
34-
template <typename T>
35-
concept HasGenerateFromPixels = requires(T t) {
36-
{ &T::generateFromPixels };
37-
};
38-
39-
template <typename T>
40-
concept HasGenerateFromString = requires(T t) {
41-
{ &T::generateFromString };
42-
};
43-
44-
template <typename T>
45-
concept HasGenerateFromPixels = requires(T t) {
46-
{ &T::generateFromPixels };
47-
};
48-
4929
template <typename T>
5030
concept HasGenerateFromFrame = requires(T t) {
5131
{ &T::generateFromFrame };

packages/react-native-executorch/common/rnexecutorch/models/object_detection/ObjectDetection.cpp

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -78,39 +78,6 @@ cv::Mat ObjectDetection::preprocessFrame(const cv::Mat &frame) const {
7878
return rgb;
7979
}
8080

81-
cv::Mat ObjectDetection::preprocessFrame(const cv::Mat &frame) const {
82-
const std::vector<int32_t> tensorDims = getAllInputShapes()[0];
83-
cv::Size tensorSize = cv::Size(tensorDims[tensorDims.size() - 1],
84-
tensorDims[tensorDims.size() - 2]);
85-
86-
cv::Mat rgb;
87-
88-
if (frame.channels() == 4) {
89-
#ifdef __APPLE__
90-
cv::cvtColor(frame, rgb, cv::COLOR_BGRA2RGB);
91-
#else
92-
cv::cvtColor(frame, rgb, cv::COLOR_RGBA2RGB);
93-
#endif
94-
} else if (frame.channels() == 3) {
95-
rgb = frame;
96-
} else {
97-
char errorMessage[100];
98-
std::snprintf(errorMessage, sizeof(errorMessage),
99-
"Unsupported frame format: %d channels", frame.channels());
100-
throw RnExecutorchError(RnExecutorchErrorCode::InvalidUserInput,
101-
errorMessage);
102-
}
103-
104-
// Only resize if dimensions don't match
105-
if (rgb.size() != tensorSize) {
106-
cv::Mat resized;
107-
cv::resize(rgb, resized, tensorSize);
108-
return resized;
109-
}
110-
111-
return rgb;
112-
}
113-
11481
std::vector<types::Detection>
11582
ObjectDetection::postprocess(const std::vector<EValue> &tensors,
11683
cv::Size originalSize, double detectionThreshold) {

0 commit comments

Comments
 (0)