react-native-yolo 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/android/src/main/java/com/yolo/HybridYolo.kt +204 -4
  2. package/android/src/main/java/com/yolo/loader/YoloModelLoader.kt +31 -0
  3. package/lib/typescript/src/specs/yolo.nitro.d.ts +13 -0
  4. package/lib/typescript/src/specs/yolo.nitro.d.ts.map +1 -1
  5. package/nitrogen/generated/android/c++/JBoundingBox.hpp +69 -0
  6. package/nitrogen/generated/android/c++/JDetection.hpp +66 -0
  7. package/nitrogen/generated/android/c++/JHybridYoloSpec.cpp +23 -0
  8. package/nitrogen/generated/android/c++/JHybridYoloSpec.hpp +1 -0
  9. package/nitrogen/generated/android/kotlin/com/margelo/nitro/yolo/BoundingBox.kt +66 -0
  10. package/nitrogen/generated/android/kotlin/com/margelo/nitro/yolo/Detection.kt +61 -0
  11. package/nitrogen/generated/android/kotlin/com/margelo/nitro/yolo/HybridYoloSpec.kt +4 -0
  12. package/nitrogen/generated/ios/Yolo-Swift-Cxx-Bridge.hpp +27 -0
  13. package/nitrogen/generated/ios/Yolo-Swift-Cxx-Umbrella.hpp +7 -0
  14. package/nitrogen/generated/ios/c++/HybridYoloSpecSwift.hpp +15 -0
  15. package/nitrogen/generated/ios/swift/BoundingBox.swift +44 -0
  16. package/nitrogen/generated/ios/swift/Detection.swift +39 -0
  17. package/nitrogen/generated/ios/swift/HybridYoloSpec.swift +1 -0
  18. package/nitrogen/generated/ios/swift/HybridYoloSpec_cxx.swift +22 -0
  19. package/nitrogen/generated/shared/c++/BoundingBox.hpp +95 -0
  20. package/nitrogen/generated/shared/c++/Detection.hpp +92 -0
  21. package/nitrogen/generated/shared/c++/HybridYoloSpec.cpp +1 -0
  22. package/nitrogen/generated/shared/c++/HybridYoloSpec.hpp +5 -0
  23. package/package.json +1 -1
  24. package/src/specs/yolo.nitro.ts +18 -2
@@ -18,11 +18,26 @@ import android.util.Base64
18
18
  import com.yolo.utils.FrameJpegConverter
19
19
  import com.yolo.utils.FrameValidator
20
20
 
21
+ import com.margelo.nitro.yolo.Detection
22
+ import com.margelo.nitro.yolo.BoundingBox
21
23
 
24
+ import java.nio.ByteBuffer
25
+ import java.nio.ByteOrder
26
+ import org.tensorflow.lite.DataType
27
+ import kotlin.math.roundToInt
22
28
 
23
29
 
24
30
  class HybridYolo : HybridYoloSpec() {
31
+ companion object {
32
+ private const val TAG = "YOLO_TAG"
33
+ }
25
34
  private var interpreter: Interpreter? = null
35
+
36
+ private var inputBuffer: ByteBuffer? = null
37
+ private var inputWidth = 0
38
+ private var inputHeight = 0
39
+ private var inputDataType: DataType? = null
40
+
26
41
  private val modelLoader = YoloModelLoader()
27
42
 
28
43
  override fun sum(num1: Double, num2: Double): Double {
@@ -33,7 +48,7 @@ class HybridYolo : HybridYoloSpec() {
33
48
  val context =
34
49
  NitroModules.applicationContext ?: throw IllegalStateException("Context is null")
35
50
 
36
- Log.d("YOLO_TAG", "Trying to load: $modelPath")
51
+ Log.d(TAG, "Trying to load: $modelPath")
37
52
 
38
53
  try {
39
54
  val modelBuffer = modelLoader.load(modelPath)
@@ -41,9 +56,25 @@ class HybridYolo : HybridYoloSpec() {
41
56
  interpreter?.close()
42
57
  interpreter = Interpreter(modelBuffer)
43
58
 
44
- Log.d("YOLO_TAG", "✅ Model loaded successfully!")
59
+ val inputTensor = interpreter!!.getInputTensor(0)
60
+ val shape = inputTensor.shape()
61
+
62
+ inputHeight = shape[1]
63
+ inputWidth = shape[2]
64
+ inputDataType = inputTensor.dataType()
65
+ inputBuffer = modelLoader.makeInputBuffer(interpreter!!)
66
+
67
+ val outputTensor = interpreter!!.getOutputTensor(0)
68
+ Log.d(TAG, "✅ YOLO model loaded")
69
+ Log.d(TAG, "📥 Input shape: ${inputTensor.shape().contentToString()}")
70
+ Log.d(TAG, "📤 Output shape: ${outputTensor.shape().contentToString()}")
71
+ Log.d(TAG, "📥 Input type: ${inputTensor.dataType()}")
72
+ Log.d(TAG, "📤 Output type: ${outputTensor.dataType()}")
73
+
74
+ Log.d(TAG, "Input shape=${shape.contentToString()} type=$inputDataType")
75
+ Log.d(TAG, "✅ Model loaded successfully!")
45
76
  } catch (e: Exception) {
46
- Log.e("YOLO_TAG", "❌ Failed to load model: ${e.message}", e)
77
+ Log.e(TAG, "❌ Failed to load model: ${e.message}", e)
47
78
  }
48
79
  }
49
80
  override fun frameToBase64(frame: HybridFrameSpec): String {
@@ -57,9 +88,178 @@ class HybridYolo : HybridYoloSpec() {
57
88
 
58
89
  Base64.encodeToString(jpegBytes, Base64.NO_WRAP)
59
90
  } catch (e: Exception) {
60
- Log.e("YOLO_TAG", "❌ frameToBase64 failed", e)
91
+ Log.e(TAG, "❌ frameToBase64 failed", e)
61
92
  ""
62
93
  }
63
94
  }
64
95
 
96
+ override fun detect(frame: HybridFrameSpec): Array<Detection> {
97
+ val localInterpreter = interpreter ?: run {
98
+ Log.e(TAG, "❌ Model is not loaded. Please call loadModel() first.")
99
+ return emptyArray()
100
+ }
101
+
102
+ if (!FrameValidator.isValidYuv(frame)) {
103
+ Log.e(TAG, "❌ Invalid frame provided for detection.")
104
+ return emptyArray()
105
+ }
106
+
107
+ val input = inputBuffer ?: return emptyArray()
108
+
109
+ fillInputFromYuvFrame(
110
+ frame = frame,
111
+ input = input,
112
+ dstWidth = inputWidth,
113
+ dstHeight = inputHeight,
114
+ dataType = inputDataType ?: DataType.FLOAT32
115
+ )
116
+
117
+ val output = Array(1) { Array(300) { FloatArray(6) } }
118
+
119
+ localInterpreter.run(input, output)
120
+
121
+ val detections = parseNmsOutput(output, confidenceThreshold = 0.5f)
122
+ if (detections.isEmpty()) {
123
+ val best = output[0].maxByOrNull { it[4] }
124
+ Log.d(TAG, "No detections. Best row=${best?.contentToString()}")
125
+ } else {
126
+ Log.d(TAG, "✅ Detections: ${detections.size}")
127
+ }
128
+
129
+
130
+ return detections.toTypedArray()
131
+ }
132
+
133
+ private fun parseNmsOutput(
134
+ output: Array<Array<FloatArray>>,
135
+ confidenceThreshold: Float = 0.5f
136
+ ): List<Detection> {
137
+ val detections = mutableListOf<Detection>()
138
+
139
+ val batchMatrix = output[0]
140
+
141
+ for (i in batchMatrix.indices) {
142
+ val row = batchMatrix[i]
143
+
144
+ val score = row[4]
145
+ if (score < confidenceThreshold) continue
146
+
147
+ val x1 = row[0].toDouble()
148
+ val y1 = row[1].toDouble()
149
+ val x2 = row[2].toDouble()
150
+ val y2 = row[3].toDouble()
151
+ val classId = row[5].toDouble()
152
+
153
+ detections.add(
154
+ Detection(
155
+ boundingBox = BoundingBox(
156
+ x1 = x1,
157
+ y1 = y1,
158
+ x2 = x2,
159
+ y2 = y2
160
+ ),
161
+ score = score.toDouble(),
162
+ classId = classId
163
+ )
164
+ )
165
+ }
166
+
167
+ return detections
168
+ }
169
+
170
+
171
+
172
+ private fun fillInputFromYuvFrame(
173
+ frame: HybridFrameSpec,
174
+ input: ByteBuffer,
175
+ dstWidth: Int,
176
+ dstHeight: Int,
177
+ dataType: DataType
178
+ ) {
179
+ val srcWidth = frame.width.toInt()
180
+ val srcHeight = frame.height.toInt()
181
+
182
+ val planes = frame.getPlanes()
183
+
184
+ val yPlane = planes[0]
185
+ val uPlane = planes[1]
186
+ val vPlane = planes[2]
187
+
188
+ val yBytes = yPlane.getPixelBuffer().toByteArray()
189
+ val uBytes = uPlane.getPixelBuffer().toByteArray()
190
+ val vBytes = vPlane.getPixelBuffer().toByteArray()
191
+
192
+ val yRowStride = yPlane.bytesPerRow.roundToInt()
193
+ val uRowStride = uPlane.bytesPerRow.roundToInt()
194
+ val vRowStride = vPlane.bytesPerRow.roundToInt()
195
+
196
+ input.rewind()
197
+
198
+ for (dy in 0 until dstHeight) {
199
+ // val sy = dy * srcHeight / dstHeight
200
+
201
+ for (dx in 0 until dstWidth) {
202
+ val srcX = dy * srcWidth / dstHeight
203
+ val srcY = srcHeight - 1 - (dx * srcHeight / dstWidth)
204
+
205
+ val yIndex = srcY * yRowStride + srcX
206
+
207
+ val uvX = srcX / 2
208
+ val uvY = srcY / 2
209
+
210
+ val uIndex = uvY * uRowStride + uvX * 2
211
+ val vIndex = uvY * vRowStride + uvX * 2
212
+
213
+ if (
214
+ yIndex >= yBytes.size ||
215
+ uIndex >= uBytes.size ||
216
+ vIndex >= vBytes.size
217
+ ) {
218
+ continue
219
+ }
220
+
221
+ val y = yBytes[yIndex].toInt() and 0xFF
222
+ val u = uBytes[uIndex].toInt() and 0xFF
223
+ val v = vBytes[vIndex].toInt() and 0xFF
224
+
225
+ val rFloat = y + 1.402f * (v - 128)
226
+ val gFloat = y - 0.344136f * (u - 128) - 0.714136f * (v - 128)
227
+ val bFloat = y + 1.772f * (u - 128)
228
+
229
+ val r = rFloat.roundToInt().coerceIn(0, 255)
230
+ val g = gFloat.roundToInt().coerceIn(0, 255)
231
+ val b = bFloat.roundToInt().coerceIn(0, 255)
232
+
233
+ when (dataType) {
234
+ DataType.FLOAT32 -> {
235
+ input.putFloat(r / 255f)
236
+ input.putFloat(g / 255f)
237
+ input.putFloat(b / 255f)
238
+ }
239
+
240
+ DataType.UINT8 -> {
241
+ input.put(r.toByte())
242
+ input.put(g.toByte())
243
+ input.put(b.toByte())
244
+ }
245
+
246
+ else -> error("Unsupported input type: $dataType")
247
+ }
248
+ }
249
+ }
250
+ input.rewind()
251
+ }
252
+
253
+ private fun yuvToRgb(y: Int, u: Int, v: Int): IntArray {
254
+ val yf = y.toFloat()
255
+ val uf = u.toFloat() - 128f
256
+ val vf = v.toFloat() - 128f
257
+
258
+ val r = (yf + 1.402f * vf).roundToInt().coerceIn(0, 255)
259
+ val g = (yf - 0.344136f * uf - 0.714136f * vf).roundToInt().coerceIn(0, 255)
260
+ val b = (yf + 1.772f * uf).roundToInt().coerceIn(0, 255)
261
+
262
+ return intArrayOf(r, g, b)
263
+ }
264
+
65
265
  }
@@ -10,6 +10,12 @@ import java.nio.MappedByteBuffer
10
10
  import java.nio.channels.FileChannel
11
11
  import org.tensorflow.lite.support.common.FileUtil
12
12
 
13
+ import org.tensorflow.lite.DataType
14
+ import java.nio.ByteBuffer
15
+ import java.nio.ByteOrder
16
+ import kotlin.math.roundToInt
17
+ import org.tensorflow.lite.Interpreter
18
+
13
19
 
14
20
 
15
21
  /**
@@ -127,4 +133,29 @@ class YoloModelLoader {
127
133
 
128
134
  return file
129
135
  }
136
+
137
+
138
+ fun makeInputBuffer(interpreter: Interpreter): ByteBuffer {
139
+ val inputTensor = interpreter.getInputTensor(0)
140
+ val shape = inputTensor.shape() // usually [1, 640, 640, 3]
141
+ val dataType = inputTensor.dataType()
142
+
143
+ val batch = shape[0]
144
+ val height = shape[1]
145
+ val width = shape[2]
146
+ val channels = shape[3]
147
+
148
+ require(batch == 1)
149
+ require(channels == 3)
150
+
151
+ val bytesPerValue = when (dataType) {
152
+ DataType.FLOAT32 -> 4
153
+ DataType.UINT8 -> 1
154
+ else -> error("Unsupported input type: $dataType")
155
+ }
156
+
157
+ return ByteBuffer
158
+ .allocateDirect(batch * width * height * channels * bytesPerValue)
159
+ .order(ByteOrder.nativeOrder())
160
+ }
130
161
  }
@@ -1,5 +1,16 @@
1
1
  import type { HybridObject } from 'react-native-nitro-modules';
2
2
  import type { Frame } from 'react-native-vision-camera';
3
+ type Detection = {
4
+ classId: number;
5
+ score: number;
6
+ boundingBox: BoundingBox;
7
+ };
8
+ type BoundingBox = {
9
+ x1: number;
10
+ y1: number;
11
+ x2: number;
12
+ y2: number;
13
+ };
3
14
  export interface Yolo extends HybridObject<{
4
15
  ios: 'swift';
5
16
  android: 'kotlin';
@@ -7,5 +18,7 @@ export interface Yolo extends HybridObject<{
7
18
  sum(num1: number, num2: number): number;
8
19
  loadModel(modelPath: string): void;
9
20
  frameToBase64(frame: Frame): string;
21
+ detect(frame: Frame): Detection[];
10
22
  }
23
+ export {};
11
24
  //# sourceMappingURL=yolo.nitro.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"yolo.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/yolo.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAEvD,MAAM,WAAW,IAAK,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IAC7E,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACvC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAA;CACpC"}
1
+ {"version":3,"file":"yolo.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/yolo.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAEvD,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,WAAW,CAAA;CACzB,CAAA;AACD,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX,CAAA;AAED,MAAM,WAAW,IAAK,SAAQ,YAAY,CAAC;IACzC,GAAG,EAAE,OAAO,CAAA;IACZ,OAAO,EAAE,QAAQ,CAAA;CAClB,CAAC;IACA,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IACvC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAA;IACnC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,CAAA;CAClC"}
@@ -0,0 +1,69 @@
1
+ ///
2
+ /// JBoundingBox.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include "BoundingBox.hpp"
12
+
13
+
14
+
15
+ namespace margelo::nitro::yolo {
16
+
17
+ using namespace facebook;
18
+
19
+ /**
20
+ * The C++ JNI bridge between the C++ struct "BoundingBox" and the the Kotlin data class "BoundingBox".
21
+ */
22
+ struct JBoundingBox final: public jni::JavaClass<JBoundingBox> {
23
+ public:
24
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/yolo/BoundingBox;";
25
+
26
+ public:
27
+ /**
28
+ * Convert this Java/Kotlin-based struct to the C++ struct BoundingBox by copying all values to C++.
29
+ */
30
+ [[maybe_unused]]
31
+ [[nodiscard]]
32
+ BoundingBox toCpp() const {
33
+ static const auto clazz = javaClassStatic();
34
+ static const auto fieldX1 = clazz->getField<double>("x1");
35
+ double x1 = this->getFieldValue(fieldX1);
36
+ static const auto fieldY1 = clazz->getField<double>("y1");
37
+ double y1 = this->getFieldValue(fieldY1);
38
+ static const auto fieldX2 = clazz->getField<double>("x2");
39
+ double x2 = this->getFieldValue(fieldX2);
40
+ static const auto fieldY2 = clazz->getField<double>("y2");
41
+ double y2 = this->getFieldValue(fieldY2);
42
+ return BoundingBox(
43
+ x1,
44
+ y1,
45
+ x2,
46
+ y2
47
+ );
48
+ }
49
+
50
+ public:
51
+ /**
52
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
53
+ */
54
+ [[maybe_unused]]
55
+ static jni::local_ref<JBoundingBox::javaobject> fromCpp(const BoundingBox& value) {
56
+ using JSignature = JBoundingBox(double, double, double, double);
57
+ static const auto clazz = javaClassStatic();
58
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
59
+ return create(
60
+ clazz,
61
+ value.x1,
62
+ value.y1,
63
+ value.x2,
64
+ value.y2
65
+ );
66
+ }
67
+ };
68
+
69
+ } // namespace margelo::nitro::yolo
@@ -0,0 +1,66 @@
1
+ ///
2
+ /// JDetection.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <fbjni/fbjni.h>
11
+ #include "Detection.hpp"
12
+
13
+ #include "BoundingBox.hpp"
14
+ #include "JBoundingBox.hpp"
15
+
16
+ namespace margelo::nitro::yolo {
17
+
18
+ using namespace facebook;
19
+
20
+ /**
21
+ * The C++ JNI bridge between the C++ struct "Detection" and the the Kotlin data class "Detection".
22
+ */
23
+ struct JDetection final: public jni::JavaClass<JDetection> {
24
+ public:
25
+ static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/yolo/Detection;";
26
+
27
+ public:
28
+ /**
29
+ * Convert this Java/Kotlin-based struct to the C++ struct Detection by copying all values to C++.
30
+ */
31
+ [[maybe_unused]]
32
+ [[nodiscard]]
33
+ Detection toCpp() const {
34
+ static const auto clazz = javaClassStatic();
35
+ static const auto fieldClassId = clazz->getField<double>("classId");
36
+ double classId = this->getFieldValue(fieldClassId);
37
+ static const auto fieldScore = clazz->getField<double>("score");
38
+ double score = this->getFieldValue(fieldScore);
39
+ static const auto fieldBoundingBox = clazz->getField<JBoundingBox>("boundingBox");
40
+ jni::local_ref<JBoundingBox> boundingBox = this->getFieldValue(fieldBoundingBox);
41
+ return Detection(
42
+ classId,
43
+ score,
44
+ boundingBox->toCpp()
45
+ );
46
+ }
47
+
48
+ public:
49
+ /**
50
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
51
+ */
52
+ [[maybe_unused]]
53
+ static jni::local_ref<JDetection::javaobject> fromCpp(const Detection& value) {
54
+ using JSignature = JDetection(double, double, jni::alias_ref<JBoundingBox>);
55
+ static const auto clazz = javaClassStatic();
56
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
57
+ return create(
58
+ clazz,
59
+ value.classId,
60
+ value.score,
61
+ JBoundingBox::fromCpp(value.boundingBox)
62
+ );
63
+ }
64
+ };
65
+
66
+ } // namespace margelo::nitro::yolo
@@ -7,10 +7,19 @@
7
7
 
8
8
  #include "JHybridYoloSpec.hpp"
9
9
 
10
+ // Forward declaration of `Detection` to properly resolve imports.
11
+ namespace margelo::nitro::yolo { struct Detection; }
12
+ // Forward declaration of `BoundingBox` to properly resolve imports.
13
+ namespace margelo::nitro::yolo { struct BoundingBox; }
10
14
  // Forward declaration of `HybridFrameSpec` to properly resolve imports.
11
15
  namespace margelo::nitro::camera { class HybridFrameSpec; }
12
16
 
13
17
  #include <string>
18
+ #include "Detection.hpp"
19
+ #include <vector>
20
+ #include "JDetection.hpp"
21
+ #include "BoundingBox.hpp"
22
+ #include "JBoundingBox.hpp"
14
23
  #include <memory>
15
24
  #include <VisionCamera/HybridFrameSpec.hpp>
16
25
  #include <VisionCamera/JHybridFrameSpec.hpp>
@@ -62,5 +71,19 @@ namespace margelo::nitro::yolo {
62
71
  auto __result = method(_javaPart, std::dynamic_pointer_cast<margelo::nitro::camera::JHybridFrameSpec>(frame)->getJavaPart());
63
72
  return __result->toStdString();
64
73
  }
74
+ std::vector<Detection> JHybridYoloSpec::detect(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) {
75
+ static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JDetection>>(jni::alias_ref<margelo::nitro::camera::JHybridFrameSpec::JavaPart> /* frame */)>("detect");
76
+ auto __result = method(_javaPart, std::dynamic_pointer_cast<margelo::nitro::camera::JHybridFrameSpec>(frame)->getJavaPart());
77
+ return [&](auto&& __input) {
78
+ size_t __size = __input->size();
79
+ std::vector<Detection> __vector;
80
+ __vector.reserve(__size);
81
+ for (size_t __i = 0; __i < __size; __i++) {
82
+ auto __element = __input->getElement(__i);
83
+ __vector.push_back(__element->toCpp());
84
+ }
85
+ return __vector;
86
+ }(__result);
87
+ }
65
88
 
66
89
  } // namespace margelo::nitro::yolo
@@ -57,6 +57,7 @@ namespace margelo::nitro::yolo {
57
57
  double sum(double num1, double num2) override;
58
58
  void loadModel(const std::string& modelPath) override;
59
59
  std::string frameToBase64(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) override;
60
+ std::vector<Detection> detect(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) override;
60
61
 
61
62
  private:
62
63
  jni::global_ref<JHybridYoloSpec::JavaPart> _javaPart;
@@ -0,0 +1,66 @@
1
+ ///
2
+ /// BoundingBox.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.yolo
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.proguard.annotations.DoNotStrip
12
+ import java.util.Objects
13
+
14
+
15
+ /**
16
+ * Represents the JavaScript object/struct "BoundingBox".
17
+ */
18
+ @DoNotStrip
19
+ @Keep
20
+ data class BoundingBox(
21
+ @DoNotStrip
22
+ @Keep
23
+ val x1: Double,
24
+ @DoNotStrip
25
+ @Keep
26
+ val y1: Double,
27
+ @DoNotStrip
28
+ @Keep
29
+ val x2: Double,
30
+ @DoNotStrip
31
+ @Keep
32
+ val y2: Double
33
+ ) {
34
+ /* primary constructor */
35
+
36
+ override fun equals(other: Any?): Boolean {
37
+ if (this === other) return true
38
+ if (other !is BoundingBox) return false
39
+ return Objects.deepEquals(this.x1, other.x1)
40
+ && Objects.deepEquals(this.y1, other.y1)
41
+ && Objects.deepEquals(this.x2, other.x2)
42
+ && Objects.deepEquals(this.y2, other.y2)
43
+ }
44
+
45
+ override fun hashCode(): Int {
46
+ return arrayOf<Any?>(
47
+ x1,
48
+ y1,
49
+ x2,
50
+ y2
51
+ ).contentDeepHashCode()
52
+ }
53
+
54
+ companion object {
55
+ /**
56
+ * Constructor called from C++
57
+ */
58
+ @DoNotStrip
59
+ @Keep
60
+ @Suppress("unused")
61
+ @JvmStatic
62
+ private fun fromCpp(x1: Double, y1: Double, x2: Double, y2: Double): BoundingBox {
63
+ return BoundingBox(x1, y1, x2, y2)
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,61 @@
1
+ ///
2
+ /// Detection.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.yolo
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.proguard.annotations.DoNotStrip
12
+ import java.util.Objects
13
+
14
+
15
+ /**
16
+ * Represents the JavaScript object/struct "Detection".
17
+ */
18
+ @DoNotStrip
19
+ @Keep
20
+ data class Detection(
21
+ @DoNotStrip
22
+ @Keep
23
+ val classId: Double,
24
+ @DoNotStrip
25
+ @Keep
26
+ val score: Double,
27
+ @DoNotStrip
28
+ @Keep
29
+ val boundingBox: BoundingBox
30
+ ) {
31
+ /* primary constructor */
32
+
33
+ override fun equals(other: Any?): Boolean {
34
+ if (this === other) return true
35
+ if (other !is Detection) return false
36
+ return Objects.deepEquals(this.classId, other.classId)
37
+ && Objects.deepEquals(this.score, other.score)
38
+ && Objects.deepEquals(this.boundingBox, other.boundingBox)
39
+ }
40
+
41
+ override fun hashCode(): Int {
42
+ return arrayOf<Any?>(
43
+ classId,
44
+ score,
45
+ boundingBox
46
+ ).contentDeepHashCode()
47
+ }
48
+
49
+ companion object {
50
+ /**
51
+ * Constructor called from C++
52
+ */
53
+ @DoNotStrip
54
+ @Keep
55
+ @Suppress("unused")
56
+ @JvmStatic
57
+ private fun fromCpp(classId: Double, score: Double, boundingBox: BoundingBox): Detection {
58
+ return Detection(classId, score, boundingBox)
59
+ }
60
+ }
61
+ }
@@ -40,6 +40,10 @@ abstract class HybridYoloSpec: HybridObject() {
40
40
  @DoNotStrip
41
41
  @Keep
42
42
  abstract fun frameToBase64(frame: com.margelo.nitro.camera.HybridFrameSpec): String
43
+
44
+ @DoNotStrip
45
+ @Keep
46
+ abstract fun detect(frame: com.margelo.nitro.camera.HybridFrameSpec): Array<Detection>
43
47
 
44
48
  // Default implementation of `HybridObject.toString()`
45
49
  override fun toString(): String {
@@ -8,6 +8,10 @@
8
8
  #pragma once
9
9
 
10
10
  // Forward declarations of C++ defined types
11
+ // Forward declaration of `BoundingBox` to properly resolve imports.
12
+ namespace margelo::nitro::yolo { struct BoundingBox; }
13
+ // Forward declaration of `Detection` to properly resolve imports.
14
+ namespace margelo::nitro::yolo { struct Detection; }
11
15
  // Forward declaration of `HybridFrameSpec` to properly resolve imports.
12
16
  namespace margelo::nitro::camera { class HybridFrameSpec; }
13
17
  // Forward declaration of `HybridYoloSpec` to properly resolve imports.
@@ -20,12 +24,15 @@ namespace VisionCamera { class HybridFrameSpec_cxx; }
20
24
  namespace Yolo { class HybridYoloSpec_cxx; }
21
25
 
22
26
  // Include C++ defined types
27
+ #include "BoundingBox.hpp"
28
+ #include "Detection.hpp"
23
29
  #include "HybridYoloSpec.hpp"
24
30
  #include <NitroModules/Result.hpp>
25
31
  #include <VisionCamera/HybridFrameSpec.hpp>
26
32
  #include <exception>
27
33
  #include <memory>
28
34
  #include <string>
35
+ #include <vector>
29
36
 
30
37
  /**
31
38
  * Contains specialized versions of C++ templated types so they can be accessed from Swift,
@@ -45,6 +52,17 @@ namespace margelo::nitro::yolo::bridge::swift {
45
52
  using std__weak_ptr_margelo__nitro__camera__HybridFrameSpec_ = std::weak_ptr<margelo::nitro::camera::HybridFrameSpec>;
46
53
  inline std__weak_ptr_margelo__nitro__camera__HybridFrameSpec_ weakify_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& strong) noexcept { return strong; }
47
54
 
55
+ // pragma MARK: std::vector<Detection>
56
+ /**
57
+ * Specialized version of `std::vector<Detection>`.
58
+ */
59
+ using std__vector_Detection_ = std::vector<Detection>;
60
+ inline std::vector<Detection> create_std__vector_Detection_(size_t size) noexcept {
61
+ std::vector<Detection> vector;
62
+ vector.reserve(size);
63
+ return vector;
64
+ }
65
+
48
66
  // pragma MARK: std::shared_ptr<HybridYoloSpec>
49
67
  /**
50
68
  * Specialized version of `std::shared_ptr<HybridYoloSpec>`.
@@ -83,5 +101,14 @@ namespace margelo::nitro::yolo::bridge::swift {
83
101
  inline Result_std__string_ create_Result_std__string_(const std::exception_ptr& error) noexcept {
84
102
  return Result<std::string>::withError(error);
85
103
  }
104
+
105
+ // pragma MARK: Result<std::vector<Detection>>
106
+ using Result_std__vector_Detection__ = Result<std::vector<Detection>>;
107
+ inline Result_std__vector_Detection__ create_Result_std__vector_Detection__(const std::vector<Detection>& value) noexcept {
108
+ return Result<std::vector<Detection>>::withValue(value);
109
+ }
110
+ inline Result_std__vector_Detection__ create_Result_std__vector_Detection__(const std::exception_ptr& error) noexcept {
111
+ return Result<std::vector<Detection>>::withError(error);
112
+ }
86
113
 
87
114
  } // namespace margelo::nitro::yolo::bridge::swift
@@ -8,18 +8,25 @@
8
8
  #pragma once
9
9
 
10
10
  // Forward declarations of C++ defined types
11
+ // Forward declaration of `BoundingBox` to properly resolve imports.
12
+ namespace margelo::nitro::yolo { struct BoundingBox; }
13
+ // Forward declaration of `Detection` to properly resolve imports.
14
+ namespace margelo::nitro::yolo { struct Detection; }
11
15
  // Forward declaration of `HybridFrameSpec` to properly resolve imports.
12
16
  namespace margelo::nitro::camera { class HybridFrameSpec; }
13
17
  // Forward declaration of `HybridYoloSpec` to properly resolve imports.
14
18
  namespace margelo::nitro::yolo { class HybridYoloSpec; }
15
19
 
16
20
  // Include C++ defined types
21
+ #include "BoundingBox.hpp"
22
+ #include "Detection.hpp"
17
23
  #include "HybridYoloSpec.hpp"
18
24
  #include <NitroModules/Result.hpp>
19
25
  #include <VisionCamera/HybridFrameSpec.hpp>
20
26
  #include <exception>
21
27
  #include <memory>
22
28
  #include <string>
29
+ #include <vector>
23
30
 
24
31
  // C++ helpers for Swift
25
32
  #include "Yolo-Swift-Cxx-Bridge.hpp"
@@ -14,10 +14,17 @@ namespace Yolo { class HybridYoloSpec_cxx; }
14
14
 
15
15
  // Forward declaration of `HybridFrameSpec` to properly resolve imports.
16
16
  namespace margelo::nitro::camera { class HybridFrameSpec; }
17
+ // Forward declaration of `Detection` to properly resolve imports.
18
+ namespace margelo::nitro::yolo { struct Detection; }
19
+ // Forward declaration of `BoundingBox` to properly resolve imports.
20
+ namespace margelo::nitro::yolo { struct BoundingBox; }
17
21
 
18
22
  #include <string>
19
23
  #include <memory>
20
24
  #include <VisionCamera/HybridFrameSpec.hpp>
25
+ #include "Detection.hpp"
26
+ #include <vector>
27
+ #include "BoundingBox.hpp"
21
28
 
22
29
  #include "Yolo-Swift-Cxx-Umbrella.hpp"
23
30
 
@@ -91,6 +98,14 @@ namespace margelo::nitro::yolo {
91
98
  auto __value = std::move(__result.value());
92
99
  return __value;
93
100
  }
101
+ inline std::vector<Detection> detect(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) override {
102
+ auto __result = _swiftPart.detect(frame);
103
+ if (__result.hasError()) [[unlikely]] {
104
+ std::rethrow_exception(__result.error());
105
+ }
106
+ auto __value = std::move(__result.value());
107
+ return __value;
108
+ }
94
109
 
95
110
  private:
96
111
  Yolo::HybridYoloSpec_cxx _swiftPart;
@@ -0,0 +1,44 @@
1
+ ///
2
+ /// BoundingBox.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Represents an instance of `BoundingBox`, backed by a C++ struct.
12
+ */
13
+ public typealias BoundingBox = margelo.nitro.yolo.BoundingBox
14
+
15
+ public extension BoundingBox {
16
+ private typealias bridge = margelo.nitro.yolo.bridge.swift
17
+
18
+ /**
19
+ * Create a new instance of `BoundingBox`.
20
+ */
21
+ init(x1: Double, y1: Double, x2: Double, y2: Double) {
22
+ self.init(x1, y1, x2, y2)
23
+ }
24
+
25
+ @inline(__always)
26
+ var x1: Double {
27
+ return self.__x1
28
+ }
29
+
30
+ @inline(__always)
31
+ var y1: Double {
32
+ return self.__y1
33
+ }
34
+
35
+ @inline(__always)
36
+ var x2: Double {
37
+ return self.__x2
38
+ }
39
+
40
+ @inline(__always)
41
+ var y2: Double {
42
+ return self.__y2
43
+ }
44
+ }
@@ -0,0 +1,39 @@
1
+ ///
2
+ /// Detection.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Represents an instance of `Detection`, backed by a C++ struct.
12
+ */
13
+ public typealias Detection = margelo.nitro.yolo.Detection
14
+
15
+ public extension Detection {
16
+ private typealias bridge = margelo.nitro.yolo.bridge.swift
17
+
18
+ /**
19
+ * Create a new instance of `Detection`.
20
+ */
21
+ init(classId: Double, score: Double, boundingBox: BoundingBox) {
22
+ self.init(classId, score, boundingBox)
23
+ }
24
+
25
+ @inline(__always)
26
+ var classId: Double {
27
+ return self.__classId
28
+ }
29
+
30
+ @inline(__always)
31
+ var score: Double {
32
+ return self.__score
33
+ }
34
+
35
+ @inline(__always)
36
+ var boundingBox: BoundingBox {
37
+ return self.__boundingBox
38
+ }
39
+ }
@@ -17,6 +17,7 @@ public protocol HybridYoloSpec_protocol: HybridObject {
17
17
  func sum(num1: Double, num2: Double) throws -> Double
18
18
  func loadModel(modelPath: String) throws -> Void
19
19
  func frameToBase64(frame: (any HybridFrameSpec)) throws -> String
20
+ func detect(frame: (any HybridFrameSpec)) throws -> [Detection]
20
21
  }
21
22
 
22
23
  public extension HybridYoloSpec_protocol {
@@ -163,4 +163,26 @@ open class HybridYoloSpec_cxx {
163
163
  return bridge.create_Result_std__string_(__exceptionPtr)
164
164
  }
165
165
  }
166
+
167
+ @inline(__always)
168
+ public final func detect(frame: bridge.std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_) -> bridge.Result_std__vector_Detection__ {
169
+ do {
170
+ let __result = try self.__implementation.detect(frame: { () -> any HybridFrameSpec in
171
+ let __unsafePointer = bridge.get_std__shared_ptr_margelo__nitro__camera__HybridFrameSpec_(frame)
172
+ let __instance = HybridFrameSpec_cxx.fromUnsafe(__unsafePointer)
173
+ return __instance.getHybridFrameSpec()
174
+ }())
175
+ let __resultCpp = { () -> bridge.std__vector_Detection_ in
176
+ var __vector = bridge.create_std__vector_Detection_(__result.count)
177
+ for __item in __result {
178
+ __vector.push_back(__item)
179
+ }
180
+ return __vector
181
+ }()
182
+ return bridge.create_Result_std__vector_Detection__(__resultCpp)
183
+ } catch (let __error) {
184
+ let __exceptionPtr = __error.toCpp()
185
+ return bridge.create_Result_std__vector_Detection__(__exceptionPtr)
186
+ }
187
+ }
166
188
  }
@@ -0,0 +1,95 @@
1
+ ///
2
+ /// BoundingBox.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+
32
+
33
+
34
+
35
+ namespace margelo::nitro::yolo {
36
+
37
+ /**
38
+ * A struct which can be represented as a JavaScript object (BoundingBox).
39
+ */
40
+ struct BoundingBox final {
41
+ public:
42
+ double x1 SWIFT_PRIVATE;
43
+ double y1 SWIFT_PRIVATE;
44
+ double x2 SWIFT_PRIVATE;
45
+ double y2 SWIFT_PRIVATE;
46
+
47
+ public:
48
+ BoundingBox() = default;
49
+ explicit BoundingBox(double x1, double y1, double x2, double y2): x1(x1), y1(y1), x2(x2), y2(y2) {}
50
+
51
+ public:
52
+ friend bool operator==(const BoundingBox& lhs, const BoundingBox& rhs) = default;
53
+ };
54
+
55
+ } // namespace margelo::nitro::yolo
56
+
57
+ namespace margelo::nitro {
58
+
59
+ // C++ BoundingBox <> JS BoundingBox (object)
60
+ template <>
61
+ struct JSIConverter<margelo::nitro::yolo::BoundingBox> final {
62
+ static inline margelo::nitro::yolo::BoundingBox fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
63
+ jsi::Object obj = arg.asObject(runtime);
64
+ return margelo::nitro::yolo::BoundingBox(
65
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x1"))),
66
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y1"))),
67
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x2"))),
68
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y2")))
69
+ );
70
+ }
71
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::yolo::BoundingBox& arg) {
72
+ jsi::Object obj(runtime);
73
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "x1"), JSIConverter<double>::toJSI(runtime, arg.x1));
74
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "y1"), JSIConverter<double>::toJSI(runtime, arg.y1));
75
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "x2"), JSIConverter<double>::toJSI(runtime, arg.x2));
76
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "y2"), JSIConverter<double>::toJSI(runtime, arg.y2));
77
+ return obj;
78
+ }
79
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
80
+ if (!value.isObject()) {
81
+ return false;
82
+ }
83
+ jsi::Object obj = value.getObject(runtime);
84
+ if (!nitro::isPlainObject(runtime, obj)) {
85
+ return false;
86
+ }
87
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x1")))) return false;
88
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y1")))) return false;
89
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "x2")))) return false;
90
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "y2")))) return false;
91
+ return true;
92
+ }
93
+ };
94
+
95
+ } // namespace margelo::nitro
@@ -0,0 +1,92 @@
1
+ ///
2
+ /// Detection.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+ // Forward declaration of `BoundingBox` to properly resolve imports.
32
+ namespace margelo::nitro::yolo { struct BoundingBox; }
33
+
34
+ #include "BoundingBox.hpp"
35
+
36
+ namespace margelo::nitro::yolo {
37
+
38
+ /**
39
+ * A struct which can be represented as a JavaScript object (Detection).
40
+ */
41
+ struct Detection final {
42
+ public:
43
+ double classId SWIFT_PRIVATE;
44
+ double score SWIFT_PRIVATE;
45
+ BoundingBox boundingBox SWIFT_PRIVATE;
46
+
47
+ public:
48
+ Detection() = default;
49
+ explicit Detection(double classId, double score, BoundingBox boundingBox): classId(classId), score(score), boundingBox(boundingBox) {}
50
+
51
+ public:
52
+ friend bool operator==(const Detection& lhs, const Detection& rhs) = default;
53
+ };
54
+
55
+ } // namespace margelo::nitro::yolo
56
+
57
+ namespace margelo::nitro {
58
+
59
+ // C++ Detection <> JS Detection (object)
60
+ template <>
61
+ struct JSIConverter<margelo::nitro::yolo::Detection> final {
62
+ static inline margelo::nitro::yolo::Detection fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
63
+ jsi::Object obj = arg.asObject(runtime);
64
+ return margelo::nitro::yolo::Detection(
65
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "classId"))),
66
+ JSIConverter<double>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "score"))),
67
+ JSIConverter<margelo::nitro::yolo::BoundingBox>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "boundingBox")))
68
+ );
69
+ }
70
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::yolo::Detection& arg) {
71
+ jsi::Object obj(runtime);
72
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "classId"), JSIConverter<double>::toJSI(runtime, arg.classId));
73
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "score"), JSIConverter<double>::toJSI(runtime, arg.score));
74
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "boundingBox"), JSIConverter<margelo::nitro::yolo::BoundingBox>::toJSI(runtime, arg.boundingBox));
75
+ return obj;
76
+ }
77
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
78
+ if (!value.isObject()) {
79
+ return false;
80
+ }
81
+ jsi::Object obj = value.getObject(runtime);
82
+ if (!nitro::isPlainObject(runtime, obj)) {
83
+ return false;
84
+ }
85
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "classId")))) return false;
86
+ if (!JSIConverter<double>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "score")))) return false;
87
+ if (!JSIConverter<margelo::nitro::yolo::BoundingBox>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "boundingBox")))) return false;
88
+ return true;
89
+ }
90
+ };
91
+
92
+ } // namespace margelo::nitro
@@ -17,6 +17,7 @@ namespace margelo::nitro::yolo {
17
17
  prototype.registerHybridMethod("sum", &HybridYoloSpec::sum);
18
18
  prototype.registerHybridMethod("loadModel", &HybridYoloSpec::loadModel);
19
19
  prototype.registerHybridMethod("frameToBase64", &HybridYoloSpec::frameToBase64);
20
+ prototype.registerHybridMethod("detect", &HybridYoloSpec::detect);
20
21
  });
21
22
  }
22
23
 
@@ -15,10 +15,14 @@
15
15
 
16
16
  // Forward declaration of `HybridFrameSpec` to properly resolve imports.
17
17
  namespace margelo::nitro::camera { class HybridFrameSpec; }
18
+ // Forward declaration of `Detection` to properly resolve imports.
19
+ namespace margelo::nitro::yolo { struct Detection; }
18
20
 
19
21
  #include <string>
20
22
  #include <memory>
21
23
  #include <VisionCamera/HybridFrameSpec.hpp>
24
+ #include "Detection.hpp"
25
+ #include <vector>
22
26
 
23
27
  namespace margelo::nitro::yolo {
24
28
 
@@ -54,6 +58,7 @@ namespace margelo::nitro::yolo {
54
58
  virtual double sum(double num1, double num2) = 0;
55
59
  virtual void loadModel(const std::string& modelPath) = 0;
56
60
  virtual std::string frameToBase64(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) = 0;
61
+ virtual std::vector<Detection> detect(const std::shared_ptr<margelo::nitro::camera::HybridFrameSpec>& frame) = 0;
57
62
 
58
63
  protected:
59
64
  // Hybrid Setup
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-yolo",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "react-native-yolo is a react native package built with Nitro",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/module/index.js",
@@ -1,8 +1,24 @@
1
1
  import type { HybridObject } from 'react-native-nitro-modules'
2
2
  import type { Frame } from 'react-native-vision-camera'
3
3
 
4
- export interface Yolo extends HybridObject<{ ios: 'swift', android: 'kotlin' }> {
4
+ export type Detection = {
5
+ classId: number
6
+ score: number
7
+ boundingBox: BoundingBox
8
+ }
9
+ export type BoundingBox = {
10
+ x1: number
11
+ y1: number
12
+ x2: number
13
+ y2: number
14
+ }
15
+
16
+ export interface Yolo extends HybridObject<{
17
+ ios: 'swift'
18
+ android: 'kotlin'
19
+ }> {
5
20
  sum(num1: number, num2: number): number
6
21
  loadModel(modelPath: string): void
7
22
  frameToBase64(frame: Frame): string
8
- }
23
+ detect(frame: Frame): Detection[]
24
+ }