-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: V3 tensorflow plugin #1633
base: main
Are you sure you want to change the base?
Changes from all commits
4b7fa85
2648c3d
339f5e9
de0dbb9
966e2c7
ff84d65
cb3de60
383c7ed
a1c24f4
5f10c63
1a2222f
6c3cde4
fe39800
36b6b98
1eff854
5721263
fa47a85
72ef8c1
6d14868
e0b17f9
bec364e
7722b11
bdf7d14
31b9f84
4cd34a1
6635fec
963afc9
697e6c8
35f4b3b
eb2de8d
fe354ad
53fac8c
de1d969
deccdac
01d2ecf
61216f0
32b8b9d
00bb39b
978325e
ed9a336
f8e0b14
c6e25a5
4dcc8e9
25b0d61
aa6b8cf
acb7e2a
9166aa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import * as React from 'react'; | ||
import { useRef, useState, useMemo, useCallback } from 'react'; | ||
import { Platform, StyleSheet, Text, View } from 'react-native'; | ||
import { StyleSheet, Text, View } from 'react-native'; | ||
import { PinchGestureHandler, PinchGestureHandlerGestureEvent, TapGestureHandler } from 'react-native-gesture-handler'; | ||
import { | ||
CameraDeviceFormat, | ||
|
@@ -9,6 +9,7 @@ import { | |
sortFormats, | ||
useCameraDevices, | ||
useFrameProcessor, | ||
useTensorflowModel, | ||
VideoFile, | ||
} from 'react-native-vision-camera'; | ||
import { Camera, frameRateIncluded } from 'react-native-vision-camera'; | ||
|
@@ -21,12 +22,10 @@ import { CaptureButton } from './views/CaptureButton'; | |
import { PressableOpacity } from 'react-native-pressable-opacity'; | ||
import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons'; | ||
import IonIcon from 'react-native-vector-icons/Ionicons'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <7016> reported by reviewdog 🐶 |
||
import { examplePlugin } from './frame-processors/ExamplePlugin'; | ||
import type { Routes } from './Routes'; | ||
import type { NativeStackScreenProps } from '@react-navigation/native-stack'; | ||
import { useIsFocused } from '@react-navigation/core'; | ||
import { Skia } from '@shopify/react-native-skia'; | ||
import { FACE_SHADER } from './Shaders'; | ||
import { PaintStyle, Skia } from '@shopify/react-native-skia'; | ||
|
||
const ReanimatedCamera = Reanimated.createAnimatedComponent(Camera); | ||
Reanimated.addWhitelistedNativeProps({ | ||
|
@@ -198,36 +197,50 @@ export function CameraPage({ navigation }: Props): React.ReactElement { | |
console.log('re-rendering camera page without active camera'); | ||
} | ||
|
||
const radius = (format?.videoHeight ?? 1080) * 0.1; | ||
const width = radius; | ||
const height = radius; | ||
const x = (format?.videoHeight ?? 1080) / 2 - radius / 2; | ||
const y = (format?.videoWidth ?? 1920) / 2 - radius / 2; | ||
const centerX = x + width / 2; | ||
const centerY = y + height / 2; | ||
|
||
const runtimeEffect = Skia.RuntimeEffect.Make(FACE_SHADER); | ||
if (runtimeEffect == null) throw new Error('Shader failed to compile!'); | ||
const shaderBuilder = Skia.RuntimeShaderBuilder(runtimeEffect); | ||
shaderBuilder.setUniform('r', [width]); | ||
shaderBuilder.setUniform('x', [centerX]); | ||
shaderBuilder.setUniform('y', [centerY]); | ||
shaderBuilder.setUniform('resolution', [1920, 1080]); | ||
const imageFilter = Skia.ImageFilter.MakeRuntimeShader(shaderBuilder, null, null); | ||
const plugin = useTensorflowModel(require('../assets/object_detection_mobile_object_localizer_v1_1_default_1.tflite')); | ||
|
||
if (plugin.state === 'loaded') console.log(JSON.stringify(plugin.model, null, 2)); | ||
|
||
const paint = Skia.Paint(); | ||
paint.setImageFilter(imageFilter); | ||
paint.setStyle(PaintStyle.Stroke); | ||
paint.setStrokeWidth(20); | ||
paint.setColor(Skia.Color('red')); | ||
|
||
const inputShape = plugin.model?.inputs[0]?.shape; | ||
const inputFrameSize = { | ||
width: inputShape?.[1] ?? 0, | ||
height: inputShape?.[2] ?? 0, | ||
}; | ||
|
||
const isIOS = Platform.OS === 'ios'; | ||
const frameProcessor = useFrameProcessor( | ||
(frame) => { | ||
'worklet'; | ||
console.log(`Width: ${frame.width}`); | ||
|
||
if (isIOS) frame.render(paint); | ||
else console.log('Drawing to the Frame is not yet available on Android. WIP PR'); | ||
if (plugin.state === 'loaded') { | ||
const [boundingBoxes, classes, scores, count] = plugin.model.run(frame); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <6133> reported by reviewdog 🐶 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <6133> reported by reviewdog 🐶 |
||
|
||
for (let i = 0; i < scores.length; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 |
||
const confidence = scores[i] ?? 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 |
||
if (confidence > 0.4) { | ||
const scale = (1 / frame.width) * frame.height; | ||
|
||
const top = boundingBoxes[i] / scale + 0.22; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <2532> reported by reviewdog 🐶 |
||
const left = boundingBoxes[i + 1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 |
||
const bottom = boundingBoxes[i + 2] / scale + 0.22; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <2532> reported by reviewdog 🐶 |
||
const right = boundingBoxes[i + 3]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 |
||
|
||
frame.drawRect( | ||
Skia.XYWHRect(left * frame.width, top * frame.height, (right - left) * frame.width, (bottom - top) * frame.height), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [tsc] <18048> reported by reviewdog 🐶 |
||
paint, | ||
); | ||
console.log(left, top, right, bottom); | ||
} | ||
} | ||
} else { | ||
console.log(`Model state: ${plugin.state}..`); | ||
} | ||
}, | ||
[isIOS, paint], | ||
[inputFrameSize.height, paint, plugin.model, plugin.state], | ||
); | ||
|
||
return ( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// | ||
// FrameResizer.h | ||
// VisionCamera | ||
// | ||
// Created by Marc Rousavy on 29.06.23. | ||
// Copyright © 2023 mrousavy. All rights reserved. | ||
// | ||
|
||
#pragma once | ||
|
||
#import <memory> | ||
#import <Foundation/Foundation.h> | ||
#import <Accelerate/Accelerate.h> | ||
#import <AVFoundation/AVFoundation.h> | ||
#import <TensorFlowLiteObjC/TFLTensorFlowLite.h> | ||
|
||
class FrameResizer { | ||
public: | ||
/** | ||
Create a new instance of the Frame Resizer. The Frame Resizer can resize incoming Frames to the given target width, height, and byte size. | ||
It uses Accelerate to downscale, crop, and re-sample Frames to the correct pixelformat. | ||
The constructor will allocate a few buffers used for internal steps. | ||
|
||
`targetWidth`: The width to resize all incoming frames to | ||
`targetHeight`: The height to resize all incoming frames to | ||
`channels`: The number of channels to use for the output. E.g. for RGB this should be 3, for RGBA this should be 4. | ||
`dataType`: The type of the output data as a Tensorflow type. | ||
|
||
Examples: | ||
- FrameResizer(192, 192, 3, TFLTensorDataTypeUInt8) will create a buffer with the size of 110.592 | ||
- FrameResizer(192, 192, 3, TFLTensorDataTypeFloat32) will create a buffer with the size of 442.368 | ||
*/ | ||
explicit FrameResizer(size_t targetWidth, size_t targetHeight, size_t channels, TFLTensorDataType dataType); | ||
~FrameResizer(); | ||
|
||
/** | ||
Resize the given Frame to the target dimensions and pixel formats. | ||
*/ | ||
const vImage_Buffer& resizeFrame(CVPixelBufferRef pixelBuffer); | ||
|
||
private: | ||
vImage_Buffer _inputDownscaledBuffer; | ||
vImage_Buffer _inputReformattedBuffer; | ||
|
||
// target image with (e.g. 192) | ||
size_t _targetWidth; | ||
// target image height (e.g. 192) | ||
size_t _targetHeight; | ||
// target image bytes per row (e.g. 192*192*3) | ||
size_t _targetBytesPerRow; | ||
// target image channels (e.g. 3 for RGB, 4 for RGBA) | ||
size_t _targetChannels; | ||
// target image data type (e.g. UInt8) | ||
TFLTensorDataType _targetDataType; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[tsc] <7016> reported by reviewdog 🐶
Could not find a declaration file for module 'react-native-vector-icons/MaterialCommunityIcons'. '/home/runner/work/react-native-vision-camera/react-native-vision-camera/example/node_modules/react-native-vector-icons/MaterialCommunityIcons.js' implicitly has an 'any' type.