Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 122 additions & 62 deletions apps/computer-vision/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,133 @@
import { Drawer } from 'expo-router/drawer';
import ColorPalette from '../colors';
import React from 'react';
import React, { useState } from 'react';
import { Text, StyleSheet, View } from 'react-native';

import {
DrawerContentComponentProps,
DrawerContentScrollView,
DrawerItemList,
} from '@react-navigation/drawer';
import { GeneratingContext } from '../context';

interface CustomDrawerProps extends DrawerContentComponentProps {
isGenerating: boolean;
}

function CustomDrawerContent(props: CustomDrawerProps) {
const { isGenerating, ...otherProps } = props;
return (
<DrawerContentScrollView {...otherProps}>
{!isGenerating ? (
<DrawerItemList {...otherProps} />
) : (
<View style={styles.centerContent}>
<Text style={styles.mainText}>Model is generating...</Text>
<Text style={styles.subText}>Interrupt before switching model</Text>
</View>
)}
</DrawerContentScrollView>
);
}

export default function _layout() {
const [isGenerating, setIsGenerating] = useState(false);

return (
<Drawer
screenOptions={{
drawerActiveTintColor: ColorPalette.primary,
drawerInactiveTintColor: '#888',
headerTintColor: ColorPalette.primary,
headerTitleStyle: { color: ColorPalette.primary },
<GeneratingContext
value={{
setGlobalGenerating: (newState: boolean) => {
setIsGenerating(newState);
},
}}
>
<Drawer.Screen
name="index"
options={{
drawerLabel: 'Menu',
title: 'Main Menu',
<Drawer
drawerContent={(props) => (
<CustomDrawerContent {...props} isGenerating={isGenerating} />
)}
screenOptions={{
drawerActiveTintColor: ColorPalette.primary,
drawerInactiveTintColor: '#888',
headerTintColor: ColorPalette.primary,
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="classification/index"
options={{
drawerLabel: 'Classification',
title: 'Classification',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="image_segmentation/index"
options={{
drawerLabel: 'Image Segmentation',
title: 'Image Segmentation',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="object_detection/index"
options={{
drawerLabel: 'Object Detection',
title: 'Object Detection',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="ocr/index"
options={{
drawerLabel: 'OCR',
title: 'OCR',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="ocr_vertical/index"
options={{
drawerLabel: 'OCR Vertical',
title: 'Vertical OCR',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="style_transfer/index"
options={{
drawerLabel: 'Style Transfer',
title: 'Style Transfer',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
</Drawer>
>
<Drawer.Screen
name="classification/index"
options={{
drawerLabel: 'Classification',
title: 'Classification',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="image_segmentation/index"
options={{
drawerLabel: 'Image Segmentation',
title: 'Image Segmentation',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="object_detection/index"
options={{
drawerLabel: 'Object Detection',
title: 'Object Detection',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="ocr/index"
options={{
drawerLabel: 'OCR',
title: 'OCR',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="ocr_vertical/index"
options={{
drawerLabel: 'OCR Vertical',
title: 'Vertical OCR',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="style_transfer/index"
options={{
drawerLabel: 'Style Transfer',
title: 'Style Transfer',
headerTitleStyle: { color: ColorPalette.primary },
}}
/>
<Drawer.Screen
name="index"
options={{
drawerLabel: () => null,
title: 'Main Menu',
drawerItemStyle: { display: 'none' },
}}
/>
</Drawer>
</GeneratingContext>
);
}

const styles = StyleSheet.create({
centerContent: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
mainText: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
color: ColorPalette.primary,
},
subText: {
fontSize: 14,
color: ColorPalette.strongPrimary,
},
});
12 changes: 9 additions & 3 deletions apps/computer-vision/app/classification/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useState } from 'react';
import Spinner from 'react-native-loading-spinner-overlay';
import { getImage } from '../../utils';
import { useClassification, EFFICIENTNET_V2_S } from 'react-native-executorch';
import { View, StyleSheet, Image, Text, ScrollView } from 'react-native';
import { BottomBar } from '../../components/BottomBar';
import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../screenWrapper';

export default function ClassificationScreen() {
const [results, setResults] = useState<{ label: string; score: number }[]>(
Expand All @@ -14,6 +16,10 @@ export default function ClassificationScreen() {
const model = useClassification({
modelSource: EFFICIENTNET_V2_S,
});
const { setGlobalGenerating } = useContext(GeneratingContext);
useEffect(() => {
setGlobalGenerating(model.isGenerating);
}, [model.isGenerating, setGlobalGenerating]);

const handleCameraPress = async (isCamera: boolean) => {
const image = await getImage(isCamera);
Expand Down Expand Up @@ -48,7 +54,7 @@ export default function ClassificationScreen() {
);
}
return (
<>
<ScreenWrapper>
<View style={styles.imageContainer}>
<Image
style={styles.image}
Expand Down Expand Up @@ -77,7 +83,7 @@ export default function ClassificationScreen() {
handleCameraPress={handleCameraPress}
runForward={runForward}
/>
</>
</ScreenWrapper>
);
}

Expand Down
12 changes: 9 additions & 3 deletions apps/computer-vision/app/image_segmentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import {
ColorType,
} from '@shopify/react-native-skia';
import { View, StyleSheet, Image } from 'react-native';
import { useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../screenWrapper';

const width = 224;
const height = 224;
Expand Down Expand Up @@ -62,6 +64,10 @@ export default function ImageSegmentationScreen() {
const model = useImageSegmentation({
modelSource: DEEPLAB_V3_RESNET50,
});
const { setGlobalGenerating } = useContext(GeneratingContext);
useEffect(() => {
setGlobalGenerating(model.isGenerating);
}, [model.isGenerating, setGlobalGenerating]);
const [imageUri, setImageUri] = useState('');

const handleCameraPress = async (isCamera: boolean) => {
Expand Down Expand Up @@ -118,7 +124,7 @@ export default function ImageSegmentationScreen() {
}

return (
<>
<ScreenWrapper>
<View style={styles.imageCanvasContainer}>
<View style={styles.imageContainer}>
<Image
Expand Down Expand Up @@ -150,7 +156,7 @@ export default function ImageSegmentationScreen() {
handleCameraPress={handleCameraPress}
runForward={runForward}
/>
</>
</ScreenWrapper>
);
}

Expand Down
12 changes: 9 additions & 3 deletions apps/computer-vision/app/object_detection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useState } from 'react';
import Spinner from 'react-native-loading-spinner-overlay';
import { BottomBar } from '../../components/BottomBar';
import { getImage } from '../../utils';
Expand All @@ -9,6 +8,9 @@ import {
} from 'react-native-executorch';
import { View, StyleSheet, Image } from 'react-native';
import ImageWithBboxes from '../../components/ImageWithBboxes';
import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../screenWrapper';

export default function ObjectDetectionScreen() {
const [imageUri, setImageUri] = useState('');
Expand All @@ -21,6 +23,10 @@ export default function ObjectDetectionScreen() {
const ssdLite = useObjectDetection({
modelSource: SSDLITE_320_MOBILENET_V3_LARGE,
});
const { setGlobalGenerating } = useContext(GeneratingContext);
useEffect(() => {
setGlobalGenerating(ssdLite.isGenerating);
}, [ssdLite.isGenerating, setGlobalGenerating]);

const handleCameraPress = async (isCamera: boolean) => {
const image = await getImage(isCamera);
Expand Down Expand Up @@ -57,7 +63,7 @@ export default function ObjectDetectionScreen() {
}

return (
<>
<ScreenWrapper>
<View style={styles.imageContainer}>
<View style={styles.image}>
{imageUri && imageDimensions?.width && imageDimensions?.height ? (
Expand All @@ -82,7 +88,7 @@ export default function ObjectDetectionScreen() {
handleCameraPress={handleCameraPress}
runForward={runForward}
/>
</>
</ScreenWrapper>
);
}

Expand Down
12 changes: 9 additions & 3 deletions apps/computer-vision/app/ocr/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {
useOCR,
} from 'react-native-executorch';
import { View, StyleSheet, Image, Text, ScrollView } from 'react-native';
import { useState } from 'react';
import ImageWithBboxes2 from '../../components/ImageWithOCRBboxes';
import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../screenWrapper';

export default function OCRScreen() {
const [imageUri, setImageUri] = useState('');
Expand All @@ -29,6 +31,10 @@ export default function OCRScreen() {
},
language: 'en',
});
const { setGlobalGenerating } = useContext(GeneratingContext);
useEffect(() => {
setGlobalGenerating(model.isGenerating);
}, [model.isGenerating, setGlobalGenerating]);

const handleCameraPress = async (isCamera: boolean) => {
const image = await getImage(isCamera);
Expand Down Expand Up @@ -62,7 +68,7 @@ export default function OCRScreen() {
}

return (
<>
<ScreenWrapper>
<View style={styles.container}>
<View style={styles.imageContainer}>
{imageUri && imageDimensions?.width && imageDimensions?.height ? (
Expand Down Expand Up @@ -100,7 +106,7 @@ export default function OCRScreen() {
handleCameraPress={handleCameraPress}
runForward={runForward}
/>
</>
</ScreenWrapper>
);
}

Expand Down
Loading
Loading