react-native-yolo 0.0.10 → 0.0.12
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.
|
@@ -32,8 +32,8 @@ public class HybridYoloModel: HybridYoloModelSpec {
|
|
|
32
32
|
|
|
33
33
|
try localInterpreter.allocateTensors()
|
|
34
34
|
|
|
35
|
-
let inputTensor = try localInterpreter.
|
|
36
|
-
let outputTensor = try localInterpreter.
|
|
35
|
+
let inputTensor = try localInterpreter.input(at: 0)
|
|
36
|
+
let outputTensor = try localInterpreter.output(at: 0)
|
|
37
37
|
|
|
38
38
|
let shape = inputTensor.shape.dimensions
|
|
39
39
|
|
|
@@ -81,7 +81,7 @@ public class HybridYoloModel: HybridYoloModelSpec {
|
|
|
81
81
|
try localInterpreter.invoke()
|
|
82
82
|
|
|
83
83
|
// Récupération des résultats du tenseur de sortie
|
|
84
|
-
let outputTensor = try localInterpreter.
|
|
84
|
+
let outputTensor = try localInterpreter.output(at: 0)
|
|
85
85
|
|
|
86
86
|
// Extraction et conversion de la structure des tenseurs [1, 300, 6] en Float
|
|
87
87
|
let nativeOutputs = outputTensor.data.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> [Float] in
|
|
@@ -104,7 +104,7 @@ public class YoloModelLoader {
|
|
|
104
104
|
*/
|
|
105
105
|
public func makeInputBuffer(interpreter: Interpreter) throws -> Data {
|
|
106
106
|
// Récupérer le premier tenseur d'entrée du modèle TFLite
|
|
107
|
-
let inputTensor = try interpreter.
|
|
107
|
+
let inputTensor = try interpreter.input(at: 0)
|
|
108
108
|
let shape = inputTensor.shape.dimensions // Généralement: [1, 640, 640, 3]
|
|
109
109
|
let dataType = inputTensor.dataType
|
|
110
110
|
|
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import NitroModules
|
|
3
3
|
import VisionCamera
|
|
4
|
+
import CoreVideo
|
|
4
5
|
|
|
5
6
|
public enum FrameJpegConverter {
|
|
6
7
|
private static let tag = "YOLO_TAG_FrameJpegConverter"
|
|
7
|
-
|
|
8
|
+
|
|
8
9
|
public static func toJpegBytes(frame: any HybridFrameSpec, quality: Int = 80) -> [UInt8] {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
10
|
+
do {
|
|
11
|
+
let nativeBuffer = try frame.getNativeBuffer()
|
|
12
|
+
|
|
13
|
+
guard let rawPointer = UnsafeRawPointer(bitPattern: UInt(nativeBuffer.pointer)) else {
|
|
14
|
+
NSLog("[%@]: ❌ Failed to get native buffer pointer", tag)
|
|
15
|
+
return []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let pixelBuffer = Unmanaged<CVPixelBuffer>
|
|
19
|
+
.fromOpaque(rawPointer)
|
|
20
|
+
.takeUnretainedValue()
|
|
21
|
+
|
|
22
|
+
let jpegBytes = Nv12JpegEncoder.encode(
|
|
23
|
+
pixelBuffer: pixelBuffer,
|
|
24
|
+
quality: quality
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if jpegBytes.isEmpty {
|
|
28
|
+
NSLog("[%@]: ❌ Failed to encode pixelBuffer to JPEG bytes", tag)
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return BitmapOrientationFixer.fix(
|
|
33
|
+
jpegBytes: jpegBytes,
|
|
34
|
+
frame: frame,
|
|
35
|
+
quality: quality
|
|
36
|
+
)
|
|
37
|
+
} catch {
|
|
38
|
+
NSLog("[%@]: ❌ Failed to convert frame to JPEG: %@", tag, "\(error)")
|
|
31
39
|
return []
|
|
32
40
|
}
|
|
33
|
-
|
|
34
|
-
// 4. Redessin de sécurité via UIGraphicsImageRenderer pour fixer définitivement les pixels
|
|
35
|
-
return BitmapOrientationFixer.fix(
|
|
36
|
-
jpegBytes: jpegBytes,
|
|
37
|
-
frame: frame,
|
|
38
|
-
quality: quality
|
|
39
|
-
)
|
|
40
41
|
}
|
|
41
|
-
}
|
|
42
|
+
}
|
|
@@ -1,58 +1,32 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import CoreImage
|
|
3
|
-
import
|
|
3
|
+
import CoreVideo
|
|
4
|
+
import ImageIO
|
|
4
5
|
|
|
5
6
|
public enum Nv12JpegEncoder {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private static let ciContext = CIContext(options: [
|
|
8
|
+
CIContextOption.useSoftwareRenderer: false
|
|
9
|
+
])
|
|
10
|
+
|
|
9
11
|
public static func encode(
|
|
10
|
-
|
|
11
|
-
width: Int,
|
|
12
|
-
height: Int,
|
|
12
|
+
pixelBuffer: CVPixelBuffer,
|
|
13
13
|
quality: Int
|
|
14
14
|
) -> [UInt8] {
|
|
15
|
-
|
|
16
|
-
// 1. Convertir la qualité (0-100 sur Android) en CGFloat (0.0-1.0 sur iOS)
|
|
17
15
|
let compressionQuality = CGFloat(max(0, min(quality, 100))) / 100.0
|
|
18
|
-
|
|
19
|
-
let
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// 3. Spécifier le format de couleur NV12 pour CoreImage (kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)
|
|
29
|
-
let imageOptions: [CIImageOption: Any] = [
|
|
30
|
-
.colorSpace: CGColorSpaceCreateDeviceRGB()
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
// On indique à CoreImage la structure exacte du NV12 (Plan 0: Y, Plan 1: UV entrelacé)
|
|
34
|
-
guard let ciImage = CIImage(
|
|
35
|
-
imageWithFormat: Int32(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
|
|
36
|
-
size: CGSize(width: width, height: height),
|
|
37
|
-
data: rawData,
|
|
38
|
-
rowBytes: width,
|
|
39
|
-
options: imageOptions
|
|
16
|
+
|
|
17
|
+
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
|
|
18
|
+
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
19
|
+
|
|
20
|
+
guard let jpegData = ciContext.jpegRepresentation(
|
|
21
|
+
of: ciImage,
|
|
22
|
+
colorSpace: colorSpace,
|
|
23
|
+
options: [
|
|
24
|
+
kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: compressionQuality
|
|
25
|
+
]
|
|
40
26
|
) else {
|
|
41
27
|
return []
|
|
42
28
|
}
|
|
43
|
-
|
|
44
|
-
// 4. Rendu de l'image GPU vers une structure d'image CoreGraphics
|
|
45
|
-
guard let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent) else {
|
|
46
|
-
return []
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 5. Conversion en UIImage puis compression matérielle en JPEG
|
|
50
|
-
let uiImage = UIImage(cgImage: cgImage)
|
|
51
|
-
guard let jpegData = uiImage.jpegData(compressionQuality: compressionQuality) else {
|
|
52
|
-
return []
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 6. Retourner le tableau d'octets natif [UInt8] requis par votre modèle
|
|
29
|
+
|
|
56
30
|
return [UInt8](jpegData)
|
|
57
31
|
}
|
|
58
|
-
}
|
|
32
|
+
}
|
|
@@ -8,7 +8,9 @@ public enum Yuv420ToNv12Converter {
|
|
|
8
8
|
public static func convert(frame: any HybridFrameSpec, width: Int, height: Int) -> [UInt8] {
|
|
9
9
|
do {
|
|
10
10
|
let nativeBuffer = try frame.getNativeBuffer()
|
|
11
|
-
guard let rawPointer = nativeBuffer.pointer else {
|
|
11
|
+
guard let rawPointer = UnsafeRawPointer(bitPattern: UInt(nativeBuffer.pointer)) else {
|
|
12
|
+
return []
|
|
13
|
+
}
|
|
12
14
|
|
|
13
15
|
let pixelBuffer = Unmanaged<CVPixelBuffer>
|
|
14
16
|
.fromOpaque(rawPointer)
|