Skip to content

Commit ef1fef8

Browse files
author
Persie
committed
Merge remote-tracking branch 'origin/master'
# Conflicts: # android/src/main/java/com/vladih/computer_vision/flutter_vision/FlutterVisionPlugin.java
2 parents d1b2d07 + ec46495 commit ef1fef8

File tree

13 files changed

+151
-471
lines changed

13 files changed

+151
-471
lines changed

android/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rootProject.allprojects {
2323
name 'ossrh-snapshot'
2424
url 'https://oss.sonatype.org/content/repositories/snapshots'
2525
}
26+
2627
}
2728
}
2829

@@ -39,6 +40,7 @@ android {
3940

4041
defaultConfig {
4142
minSdkVersion 21
43+
targetSdk 35
4244
}
4345
aaptOptions {
4446
noCompress 'tflite'
@@ -48,6 +50,7 @@ android {
4850
buildFeatures{
4951
mlModelBinding true
5052
}
53+
5154
}
5255
dependencies{
5356
implementation 'com.github.vladiH:opencv-android:v1.0.0'
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Wed Feb 22 11:31:00 CET 2023
1+
#Sat Jan 25 18:51:17 CET 2025
22
distributionBase=GRADLE_USER_HOME
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
43
distributionPath=wrapper/dists
5-
zipStorePath=wrapper/dists
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
65
zipStoreBase=GRADLE_USER_HOME
6+
zipStorePath=wrapper/dists

android/src/main/AndroidManifest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2-
package="com.vladih.computer_vision.flutter_vision">
1+
<manifest package="com.vladih.computer_vision.flutter_vision">
32
<!--enable this for storing bitmap-->
43
<!--<application android:requestLegacyExternalStorage="true">
54
</application>-->

android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolo.java

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,18 @@
22

33
import static java.lang.Math.min;
44

5-
import android.annotation.SuppressLint;
65
import android.content.Context;
76
import android.content.res.AssetFileDescriptor;
87
import android.content.res.AssetManager;
98
import android.util.Log;
109

11-
import com.vladih.computer_vision.flutter_vision.utils.FeedInputTensorHelper;
12-
13-
import org.opencv.core.CvType;
14-
import org.opencv.core.Mat;
1510
import org.tensorflow.lite.Interpreter;
1611
import org.tensorflow.lite.Tensor;
1712
import org.tensorflow.lite.gpu.CompatibilityList;
1813
import org.tensorflow.lite.gpu.GpuDelegate;
1914
import org.tensorflow.lite.gpu.GpuDelegateFactory;
2015

2116
import java.io.BufferedReader;
22-
import java.io.File;
2317
import java.io.FileInputStream;
2418
import java.io.InputStreamReader;
2519
import java.lang.reflect.Array;
@@ -34,9 +28,6 @@
3428
import java.util.Map;
3529
import java.util.Vector;
3630

37-
import io.flutter.embedding.engine.FlutterEngine;
38-
import io.flutter.embedding.engine.plugins.FlutterPlugin;
39-
4031
public class Yolo {
4132
protected float[][][] output;
4233
protected Interpreter interpreter;
@@ -68,15 +59,15 @@ public Yolo(Context context,
6859
this.rotation = rotation;
6960
}
7061

71-
// public Vector<String> getLabels(){return this.labels;}
7262
public Tensor getInputTensor() {
63+
if (interpreter == null) return null;
7364
return this.interpreter.getInputTensor(0);
7465
}
7566

76-
@SuppressLint("SuspiciousIndentation")
67+
7768
public void initialize_model() throws Exception {
7869
AssetManager asset_manager = null;
79-
MappedByteBuffer buffer = null;
70+
MappedByteBuffer buffer;
8071
FileChannel file_channel = null;
8172
FileInputStream input_stream = null;
8273

@@ -85,73 +76,83 @@ public void initialize_model() throws Exception {
8576
asset_manager = context.getAssets();
8677
AssetFileDescriptor file_descriptor = asset_manager.openFd(this.model_path);
8778
input_stream = new FileInputStream(file_descriptor.getFileDescriptor());
88-
8979
file_channel = input_stream.getChannel();
9080
buffer = file_channel.map(
91-
FileChannel.MapMode.READ_ONLY, file_descriptor.getStartOffset(),
81+
FileChannel.MapMode.READ_ONLY,
82+
file_descriptor.getStartOffset(),
9283
file_descriptor.getLength()
9384
);
9485
file_descriptor.close();
9586
} else {
96-
input_stream = new FileInputStream(new File(this.model_path));
87+
input_stream = new FileInputStream(this.model_path);
9788
file_channel = input_stream.getChannel();
9889
buffer = file_channel.map(FileChannel.MapMode.READ_ONLY, 0, file_channel.size());
9990
}
10091

10192
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 {
10697
GpuDelegateFactory.Options delegateOptions = compatibilityList.getBestOptionsForThisDevice();
10798
GpuDelegate gpuDelegate = new GpuDelegate(delegateOptions.setQuantizedModelsAllowed(this.quantization));
10899
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();
110103
interpreterOptions.setNumThreads(num_threads);
111104
}
112-
// Create the interpreter
113-
this.interpreter = new Interpreter(buffer, interpreterOptions);
114-
} catch (Exception e) {
115-
interpreterOptions = new Interpreter.Options();
105+
} else {
116106
interpreterOptions.setNumThreads(num_threads);
117-
// Create the interpreter
118-
this.interpreter = new Interpreter(buffer, interpreterOptions);
119107
}
108+
109+
this.interpreter = new Interpreter(buffer, interpreterOptions);
120110
this.interpreter.allocateTensors();
121111
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);
124114
} catch (Exception e) {
125-
throw e;
115+
throw new Exception("Model initialization failed: " + e.getMessage());
126116
} 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);
132126
}
133127
}
134128
}
135129

136130
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+
137135
BufferedReader br = null;
138136
try {
139137
if (asset_manager != null) {
140138
br = new BufferedReader(new InputStreamReader(asset_manager.open(label_path)));
141139
} else {
142-
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(label_path))));
140+
br = new BufferedReader(new InputStreamReader(new FileInputStream(label_path)));
143141
}
144-
String line;
142+
145143
Vector<String> labels = new Vector<>();
144+
String line;
146145
while ((line = br.readLine()) != null) {
147146
labels.add(line);
148147
}
149148
return labels;
150149
} catch (Exception e) {
151-
throw new Exception(e.getMessage());
150+
throw new Exception("Label loading failed: " + e.getMessage());
152151
} 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);
155156
}
156157
}
157158
}
@@ -161,6 +162,10 @@ public List<Map<String, Object>> detect_task(ByteBuffer byteBuffer,
161162
int source_width,
162163
float iou_threshold,
163164
float conf_threshold, float class_threshold) throws Exception {
165+
if (interpreter == null) {
166+
throw new Exception("Interpreter not initialized");
167+
}
168+
164169
try {
165170
int[] input_shape = this.interpreter.getInputTensor(0).shape();
166171
this.interpreter.run(byteBuffer, this.output);
@@ -169,7 +174,7 @@ public List<Map<String, Object>> detect_task(ByteBuffer byteBuffer,
169174
boxes = restore_size(boxes, input_shape[1], input_shape[2], source_width, source_height);
170175
return out(boxes, this.labels);
171176
} catch (Exception e) {
172-
throw e;
177+
throw new Exception("Detection failed: " + e.getMessage());
173178
} finally {
174179
byteBuffer.clear();
175180
}
@@ -185,8 +190,8 @@ protected List<float[]> filter_box(float[][][] model_outputs, float iou_threshol
185190
int dimension = model_outputs[0][0].length;
186191
int rows = model_outputs[0].length;
187192
float x1, y1, x2, y2, conf;
188-
int max_index = 0;
189-
float max = 0f;
193+
int max_index;
194+
float max;
190195
for (int i = 0; i < rows; i++) {
191196
//convert xywh to xyxy
192197
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) {
256261
}
257262
return filteredBoxes;
258263
} catch (Exception e) {
259-
Log.e("nms", e.getMessage());
264+
Log.e("nms", e.getMessage() != null ? e.getMessage() : "Unknown error");
260265
throw e;
261266
}
262267
}
263268

269+
public boolean isInitialized() {
270+
return interpreter != null;
271+
}
272+
273+
264274
protected List<float[]> restore_size(List<float[]> nms,
265275
int input_width,
266276
int input_height,
@@ -311,10 +321,12 @@ protected List<Map<String, Object>> out(List<float[]> yolo_result, Vector<String
311321

312322
public void close() {
313323
try {
314-
if (interpreter != null)
324+
if (interpreter != null) {
315325
interpreter.close();
326+
interpreter = null;
327+
}
316328
} catch (Exception e) {
317-
throw e;
329+
Log.e("Yolo", "Interpreter close error", e);
318330
}
319331
}
320332
}

android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov5.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
package com.vladih.computer_vision.flutter_vision.models;
22

3-
import static java.lang.Math.min;
4-
53
import android.content.Context;
6-
import android.content.res.AssetFileDescriptor;
7-
import android.content.res.AssetManager;
8-
import android.util.Log;
9-
10-
import org.tensorflow.lite.Interpreter;
11-
import org.tensorflow.lite.gpu.CompatibilityList;
12-
import org.tensorflow.lite.gpu.GpuDelegate;
13-
14-
import java.io.File;
15-
import java.io.FileInputStream;
16-
import java.nio.MappedByteBuffer;
17-
import java.nio.channels.FileChannel;
18-
import java.util.ArrayList;
19-
import java.util.Collections;
20-
import java.util.Comparator;
21-
import java.util.List;
224

235
public class Yolov5 extends Yolo{
246
public Yolov5(Context context,

android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8.java

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,14 @@
11
package com.vladih.computer_vision.flutter_vision.models;
22

3-
import static java.lang.Math.min;
4-
53
import android.content.Context;
6-
import android.content.res.AssetFileDescriptor;
7-
import android.content.res.AssetManager;
8-
import android.graphics.Bitmap;
9-
import android.graphics.Color;
10-
import android.util.Log;
11-
12-
import com.vladih.computer_vision.flutter_vision.utils.utils;
13-
14-
import org.opencv.core.Core;
15-
import org.opencv.core.CvType;
16-
import org.opencv.core.Mat;
17-
import org.opencv.core.MatOfPoint;
18-
import org.opencv.core.Point;
19-
import org.opencv.imgproc.Imgproc;
20-
import org.tensorflow.lite.Interpreter;
21-
import org.tensorflow.lite.gpu.CompatibilityList;
22-
import org.tensorflow.lite.gpu.GpuDelegate;
23-
import org.tensorflow.lite.schema.Buffer;
24-
import org.tensorflow.lite.schema.ReshapeOptions;
25-
import org.tensorflow.lite.support.image.ImageProcessor;
264

27-
import java.io.File;
28-
import java.io.FileInputStream;
29-
import java.lang.reflect.Array;
305
import java.nio.ByteBuffer;
31-
import java.nio.MappedByteBuffer;
32-
import java.nio.channels.FileChannel;
336
import java.util.ArrayList;
347
import java.util.Collections;
358
import java.util.Comparator;
369
import java.util.HashMap;
3710
import java.util.List;
3811
import java.util.Map;
39-
import java.util.UUID;
4012
import java.util.Vector;
4113

4214
public class Yolov8 extends Yolo {

android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8Seg.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,24 @@
33
import static java.lang.Math.min;
44

55
import android.content.Context;
6-
import android.content.res.AssetFileDescriptor;
7-
import android.content.res.AssetManager;
86
import android.graphics.Bitmap;
97
import android.graphics.Color;
10-
import android.util.Log;
118

129
import com.vladih.computer_vision.flutter_vision.utils.utils;
1310

14-
import org.opencv.core.Core;
15-
import org.opencv.core.CvType;
1611
import org.opencv.core.Mat;
1712
import org.opencv.core.MatOfPoint;
1813
import org.opencv.core.Point;
1914
import org.opencv.imgproc.Imgproc;
20-
import org.tensorflow.lite.Interpreter;
21-
import org.tensorflow.lite.gpu.CompatibilityList;
22-
import org.tensorflow.lite.gpu.GpuDelegate;
23-
import org.tensorflow.lite.schema.Buffer;
24-
import org.tensorflow.lite.schema.ReshapeOptions;
25-
import org.tensorflow.lite.support.image.ImageProcessor;
2615

27-
import java.io.File;
28-
import java.io.FileInputStream;
2916
import java.lang.reflect.Array;
3017
import java.nio.ByteBuffer;
31-
import java.nio.MappedByteBuffer;
32-
import java.nio.channels.FileChannel;
3318
import java.util.ArrayList;
3419
import java.util.Collections;
3520
import java.util.Comparator;
3621
import java.util.HashMap;
3722
import java.util.List;
3823
import java.util.Map;
39-
import java.util.UUID;
4024
import java.util.Vector;
4125

4226
//https://dev.to/andreygermanov/how-to-implement-instance-segmentation-using-yolov8-neural-network-3if9

0 commit comments

Comments
 (0)