2
2
3
3
import static java .lang .Math .min ;
4
4
5
- import android .annotation .SuppressLint ;
6
5
import android .content .Context ;
7
6
import android .content .res .AssetFileDescriptor ;
8
7
import android .content .res .AssetManager ;
9
8
import android .util .Log ;
10
9
11
- import com .vladih .computer_vision .flutter_vision .utils .FeedInputTensorHelper ;
12
-
13
- import org .opencv .core .CvType ;
14
- import org .opencv .core .Mat ;
15
10
import org .tensorflow .lite .Interpreter ;
16
11
import org .tensorflow .lite .Tensor ;
17
12
import org .tensorflow .lite .gpu .CompatibilityList ;
18
13
import org .tensorflow .lite .gpu .GpuDelegate ;
19
14
import org .tensorflow .lite .gpu .GpuDelegateFactory ;
20
15
21
16
import java .io .BufferedReader ;
22
- import java .io .File ;
23
17
import java .io .FileInputStream ;
24
18
import java .io .InputStreamReader ;
25
19
import java .lang .reflect .Array ;
34
28
import java .util .Map ;
35
29
import java .util .Vector ;
36
30
37
- import io .flutter .embedding .engine .FlutterEngine ;
38
- import io .flutter .embedding .engine .plugins .FlutterPlugin ;
39
-
40
31
public class Yolo {
41
32
protected float [][][] output ;
42
33
protected Interpreter interpreter ;
@@ -68,15 +59,15 @@ public Yolo(Context context,
68
59
this .rotation = rotation ;
69
60
}
70
61
71
- // public Vector<String> getLabels(){return this.labels;}
72
62
public Tensor getInputTensor () {
63
+ if (interpreter == null ) return null ;
73
64
return this .interpreter .getInputTensor (0 );
74
65
}
75
66
76
- @ SuppressLint ( "SuspiciousIndentation" )
67
+
77
68
public void initialize_model () throws Exception {
78
69
AssetManager asset_manager = null ;
79
- MappedByteBuffer buffer = null ;
70
+ MappedByteBuffer buffer ;
80
71
FileChannel file_channel = null ;
81
72
FileInputStream input_stream = null ;
82
73
@@ -85,73 +76,83 @@ public void initialize_model() throws Exception {
85
76
asset_manager = context .getAssets ();
86
77
AssetFileDescriptor file_descriptor = asset_manager .openFd (this .model_path );
87
78
input_stream = new FileInputStream (file_descriptor .getFileDescriptor ());
88
-
89
79
file_channel = input_stream .getChannel ();
90
80
buffer = file_channel .map (
91
- FileChannel .MapMode .READ_ONLY , file_descriptor .getStartOffset (),
81
+ FileChannel .MapMode .READ_ONLY ,
82
+ file_descriptor .getStartOffset (),
92
83
file_descriptor .getLength ()
93
84
);
94
85
file_descriptor .close ();
95
86
} else {
96
- input_stream = new FileInputStream (new File ( this .model_path ) );
87
+ input_stream = new FileInputStream (this .model_path );
97
88
file_channel = input_stream .getChannel ();
98
89
buffer = file_channel .map (FileChannel .MapMode .READ_ONLY , 0 , file_channel .size ());
99
90
}
100
91
101
92
Interpreter .Options interpreterOptions = new Interpreter .Options ();
102
- try {
103
- // Check if GPU support is available
104
- CompatibilityList compatibilityList = new CompatibilityList ();
105
- if ( use_gpu && compatibilityList . isDelegateSupportedOnThisDevice ()) {
93
+ CompatibilityList compatibilityList = new CompatibilityList ();
94
+
95
+ if ( use_gpu && compatibilityList . isDelegateSupportedOnThisDevice ()) {
96
+ try {
106
97
GpuDelegateFactory .Options delegateOptions = compatibilityList .getBestOptionsForThisDevice ();
107
98
GpuDelegate gpuDelegate = new GpuDelegate (delegateOptions .setQuantizedModelsAllowed (this .quantization ));
108
99
interpreterOptions .addDelegate (gpuDelegate );
109
- } else {
100
+ } catch (Exception e ) {
101
+ Log .e ("Yolo" , "GPU delegate failed, falling back to CPU" , e );
102
+ interpreterOptions = new Interpreter .Options ();
110
103
interpreterOptions .setNumThreads (num_threads );
111
104
}
112
- // Create the interpreter
113
- this .interpreter = new Interpreter (buffer , interpreterOptions );
114
- } catch (Exception e ) {
115
- interpreterOptions = new Interpreter .Options ();
105
+ } else {
116
106
interpreterOptions .setNumThreads (num_threads );
117
- // Create the interpreter
118
- this .interpreter = new Interpreter (buffer , interpreterOptions );
119
107
}
108
+
109
+ this .interpreter = new Interpreter (buffer , interpreterOptions );
120
110
this .interpreter .allocateTensors ();
121
111
this .labels = load_labels (asset_manager , label_path );
122
- int [] shape = interpreter .getOutputTensor (0 ).shape ();//3dimension
123
- this .output = (float [][][]) Array .newInstance (float .class , shape );
112
+ int [] shape = interpreter .getOutputTensor (0 ).shape ();
113
+ this .output = (float [][][]) Array .newInstance (float .class , shape );
124
114
} catch (Exception e ) {
125
- throw e ;
115
+ throw new Exception ( "Model initialization failed: " + e . getMessage ()) ;
126
116
} finally {
127
- if (buffer != null )
128
- buffer .clear ();
129
- if (file_channel != null && file_channel .isOpen ()) {
130
- file_channel .close ();
131
- input_stream .close ();
117
+ try {
118
+ if (file_channel != null && file_channel .isOpen ()) {
119
+ file_channel .close ();
120
+ }
121
+ if (input_stream != null ) {
122
+ input_stream .close ();
123
+ }
124
+ } catch (Exception e ) {
125
+ Log .e ("Yolo" , "Resource cleanup error" , e );
132
126
}
133
127
}
134
128
}
135
129
136
130
protected Vector <String > load_labels (AssetManager asset_manager , String label_path ) throws Exception {
131
+ if (label_path == null || label_path .isEmpty ()) {
132
+ throw new Exception ("Invalid label path" );
133
+ }
134
+
137
135
BufferedReader br = null ;
138
136
try {
139
137
if (asset_manager != null ) {
140
138
br = new BufferedReader (new InputStreamReader (asset_manager .open (label_path )));
141
139
} else {
142
- br = new BufferedReader (new InputStreamReader (new FileInputStream (new File ( label_path ) )));
140
+ br = new BufferedReader (new InputStreamReader (new FileInputStream (label_path )));
143
141
}
144
- String line ;
142
+
145
143
Vector <String > labels = new Vector <>();
144
+ String line ;
146
145
while ((line = br .readLine ()) != null ) {
147
146
labels .add (line );
148
147
}
149
148
return labels ;
150
149
} catch (Exception e ) {
151
- throw new Exception (e .getMessage ());
150
+ throw new Exception ("Label loading failed: " + e .getMessage ());
152
151
} finally {
153
- if (br != null ) {
154
- br .close ();
152
+ try {
153
+ if (br != null ) br .close ();
154
+ } catch (Exception e ) {
155
+ Log .e ("Yolo" , "Label reader close error" , e );
155
156
}
156
157
}
157
158
}
@@ -161,6 +162,10 @@ public List<Map<String, Object>> detect_task(ByteBuffer byteBuffer,
161
162
int source_width ,
162
163
float iou_threshold ,
163
164
float conf_threshold , float class_threshold ) throws Exception {
165
+ if (interpreter == null ) {
166
+ throw new Exception ("Interpreter not initialized" );
167
+ }
168
+
164
169
try {
165
170
int [] input_shape = this .interpreter .getInputTensor (0 ).shape ();
166
171
this .interpreter .run (byteBuffer , this .output );
@@ -169,7 +174,7 @@ public List<Map<String, Object>> detect_task(ByteBuffer byteBuffer,
169
174
boxes = restore_size (boxes , input_shape [1 ], input_shape [2 ], source_width , source_height );
170
175
return out (boxes , this .labels );
171
176
} catch (Exception e ) {
172
- throw e ;
177
+ throw new Exception ( "Detection failed: " + e . getMessage ()) ;
173
178
} finally {
174
179
byteBuffer .clear ();
175
180
}
@@ -185,8 +190,8 @@ protected List<float[]> filter_box(float[][][] model_outputs, float iou_threshol
185
190
int dimension = model_outputs [0 ][0 ].length ;
186
191
int rows = model_outputs [0 ].length ;
187
192
float x1 , y1 , x2 , y2 , conf ;
188
- int max_index = 0 ;
189
- float max = 0f ;
193
+ int max_index ;
194
+ float max ;
190
195
for (int i = 0 ; i < rows ; i ++) {
191
196
//convert xywh to xyxy
192
197
x1 = (model_outputs [0 ][i ][0 ] - model_outputs [0 ][i ][2 ] / 2f ) * input_width ;
@@ -256,11 +261,16 @@ protected static List<float[]> nms(List<float[]> boxes, float iou_threshold) {
256
261
}
257
262
return filteredBoxes ;
258
263
} catch (Exception e ) {
259
- Log .e ("nms" , e .getMessage ());
264
+ Log .e ("nms" , e .getMessage () != null ? e . getMessage () : "Unknown error" );
260
265
throw e ;
261
266
}
262
267
}
263
268
269
+ public boolean isInitialized () {
270
+ return interpreter != null ;
271
+ }
272
+
273
+
264
274
protected List <float []> restore_size (List <float []> nms ,
265
275
int input_width ,
266
276
int input_height ,
@@ -311,10 +321,12 @@ protected List<Map<String, Object>> out(List<float[]> yolo_result, Vector<String
311
321
312
322
public void close () {
313
323
try {
314
- if (interpreter != null )
324
+ if (interpreter != null ) {
315
325
interpreter .close ();
326
+ interpreter = null ;
327
+ }
316
328
} catch (Exception e ) {
317
- throw e ;
329
+ Log . e ( "Yolo" , "Interpreter close error" , e ) ;
318
330
}
319
331
}
320
332
}
0 commit comments