Skip to content

Commit b725617

Browse files
authored
Merge pull request #48 from Persie0/master
Add is_asset argument to load models/labels from storage
2 parents fcf71f3 + 7f8cb9c commit b725617

20 files changed

+170
-719
lines changed

android/build.gradle

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ buildscript {
1515

1616

1717
dependencies {
18-
19-
classpath 'com.android.tools.build:gradle:7.1.2'
20-
18+
classpath 'com.android.tools.build:gradle:8.6.0'
2119
}
2220

2321
}
@@ -30,13 +28,7 @@ rootProject.allprojects {
3028
google()
3129

3230
mavenCentral()
33-
34-
flatDir{
35-
36-
dirs project(":flutter_vision").file("libs")
37-
38-
}
39-
31+
4032
maven {
4133

4234
url 'https://jitpack.io'
@@ -60,12 +52,10 @@ apply plugin: 'com.android.library'
6052

6153

6254
android {
63-
compileSdkVersion 31
64-
65-
6655

6756
namespace 'com.vladih.computer_vision.flutter_vision'
68-
57+
58+
compileSdkVersion 36
6959

7060
compileOptions {
7161

@@ -79,7 +69,7 @@ android {
7969
defaultConfig {
8070

8171
minSdkVersion 21
82-
72+
targetSdk 36
8373
}
8474

8575
aaptOptions {
@@ -101,26 +91,11 @@ android {
10191

10292

10393
dependencies{
104-
105-
//implementation (files('libs/tesseract4android-release.aar'))
106-
107-
api(name:"tesseract4android-release", ext: "aar")
108-
10994
implementation 'com.github.vladiH:opencv-android:v1.0.0'
110-
111-
implementation 'org.tensorflow:tensorflow-lite:2.10.0'
112-
113-
implementation 'org.tensorflow:tensorflow-lite-api:2.10.0'
114-
115-
implementation 'org.tensorflow:tensorflow-lite-gpu:2.10.0'
116-
117-
implementation 'org.tensorflow:tensorflow-lite-gpu-api:2.10.0'
118-
119-
implementation 'org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.3'
120-
121-
implementation 'org.tensorflow:tensorflow-lite-support:0.4.3'
122-
123-
implementation 'org.tensorflow:tensorflow-lite-metadata:0.4.3'
124-
125-
implementation 'org.tensorflow:tensorflow-lite-select-tf-ops:2.11.0'
95+
implementation 'com.google.ai.edge.litert:litert:1.4.0'
96+
implementation 'com.google.ai.edge.litert:litert-api:1.4.0'
97+
implementation 'com.google.ai.edge.litert:litert-gpu:1.4.0'
98+
implementation 'com.google.ai.edge.litert:litert-gpu-api:1.4.0'
99+
implementation 'com.google.ai.edge.litert:litert-support:1.4.0'
100+
implementation 'com.google.ai.edge.litert:litert-metadata:1.4.0'
126101
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
#Wed Feb 22 11:31:00 CET 2023
21
distributionBase=GRADLE_USER_HOME
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
42
distributionPath=wrapper/dists
5-
zipStorePath=wrapper/dists
63
zipStoreBase=GRADLE_USER_HOME
4+
zipStorePath=wrapper/dists
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Sat Jan 25 18:51:17 CET 2025
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
5+
zipStoreBase=GRADLE_USER_HOME
6+
zipStorePath=wrapper/dists
-11.5 MB
Binary file not shown.

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/FlutterVisionPlugin.java

Lines changed: 12 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,16 @@
33
import android.content.Context;
44
import android.graphics.Bitmap;
55
import android.graphics.BitmapFactory;
6-
import android.graphics.Matrix;
76

87
import androidx.annotation.NonNull;
98

10-
import com.vladih.computer_vision.flutter_vision.models.Tesseract;
119
import com.vladih.computer_vision.flutter_vision.models.Yolo;
1210
import com.vladih.computer_vision.flutter_vision.models.Yolov8;
1311
import com.vladih.computer_vision.flutter_vision.models.Yolov5;
1412
import com.vladih.computer_vision.flutter_vision.models.Yolov8Seg;
1513
import com.vladih.computer_vision.flutter_vision.utils.utils;
1614

1715
import org.opencv.android.OpenCVLoader;
18-
import org.opencv.android.Utils;
19-
import org.opencv.core.Mat;
2016

2117
import java.nio.ByteBuffer;
2218
import java.util.ArrayList;
@@ -41,7 +37,6 @@ public class FlutterVisionPlugin implements FlutterPlugin, MethodCallHandler {
4137
private Context context;
4238
private FlutterAssets assets;
4339
private Yolo yolo_model;
44-
private Tesseract tesseract_model;
4540

4641
private ExecutorService executor;
4742

@@ -61,7 +56,6 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
6156
this.methodChannel.setMethodCallHandler(null);
6257
this.methodChannel = null;
6358
this.assets = null;
64-
close_tesseract();
6559
close_yolo();
6660
this.executor.shutdownNow();
6761
} catch (Exception e) {
@@ -84,17 +78,7 @@ private void setupChannel(Context context, FlutterAssets assets, BinaryMessenger
8478
@Override
8579
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
8680
// Handle method calls from Flutter
87-
if (call.method.equals("loadOcrModel")) {
88-
try {
89-
load_ocr_model((Map) call.arguments);
90-
} catch (Exception e) {
91-
result.error("100", "Error on load ocr components", e);
92-
}
93-
} else if (call.method.equals("ocrOnFrame")) {
94-
ocr_on_frame((Map) call.arguments, result);
95-
} else if (call.method.equals("closeOcrModel")) {
96-
close_ocr_model(result);
97-
} else if (call.method.equals("loadYoloModel")) {
81+
if (call.method.equals("loadYoloModel")) {
9882
try {
9983
load_yolo_model((Map) call.arguments);
10084
result.success("ok");
@@ -107,77 +91,26 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
10791
yolo_on_image((Map) call.arguments, result);
10892
} else if (call.method.equals("closeYoloModel")) {
10993
close_yolo_model(result);
110-
} else if (call.method.equals("loadTesseractModel")) {
111-
try {
112-
load_tesseract_model((Map) call.arguments);
113-
result.success("ok");
114-
} catch (Exception e) {
115-
result.error("100", "Error on load Tesseract model", e);
116-
}
117-
} else if (call.method.equals("tesseractOnImage")) {
118-
tesseract_on_image((Map) call.arguments, result);
119-
} else if (call.method.equals("closeTesseractModel")) {
120-
close_tesseract_model(result);
121-
} else {
94+
}else {
12295
result.notImplemented();
12396
}
12497
}
12598

126-
private void load_ocr_model(Map<String, Object> args) throws Exception {
127-
load_yolo_model(args);
128-
load_tesseract_model(args);
129-
}
130-
131-
private void ocr_on_frame(Map<String, Object> args, Result result) {
132-
try {
133-
List<byte[]> image = (ArrayList) args.get("bytesList");
134-
int image_height = (int) args.get("image_height");
135-
int image_width = (int) args.get("image_width");
136-
float iou_threshold = (float) (double) (args.get("iou_threshold"));
137-
float conf_threshold = (float) (double) (args.get("conf_threshold"));
138-
float class_threshold = (float) (double) (args.get("class_threshold"));
139-
List<Integer> class_is_text = (List<Integer>) args.get("class_is_text");
140-
Bitmap bitmap = utils.feedInputToBitmap(context.getApplicationContext(), image, image_height, image_width, 90);
141-
int[] shape = yolo_model.getInputTensor().shape();
142-
ByteBuffer byteBuffer = utils.feedInputTensor(bitmap, shape[1], shape[2], image_width, image_height, 0, 255);
143-
144-
List<Map<String, Object>> yolo_results = yolo_model.detect_task(byteBuffer, image_height, image_width, iou_threshold, conf_threshold, class_threshold);
145-
for (Map<String, Object> yolo_result : yolo_results) {
146-
float[] box = (float[]) yolo_result.get("box");
147-
if (class_is_text.contains((int) box[5])) {
148-
Bitmap crop = utils.crop_bitmap(bitmap,
149-
box[0], box[1], box[2], box[3]);
150-
//utils.getScreenshotBmp(crop, "crop");
151-
Bitmap tmp = crop.copy(crop.getConfig(), crop.isMutable());
152-
yolo_result.put("text", tesseract_model.predict_text(tmp));
153-
} else {
154-
yolo_result.put("text", "");
155-
}
156-
}
157-
result.success(yolo_results);
158-
} catch (Exception e) {
159-
result.error("100", "Ocr error", e);
160-
}
161-
}
162-
163-
private void close_ocr_model(Result result) {
164-
try {
165-
close_tesseract();
166-
close_yolo();
167-
result.success("OCR model closed succesfully");
168-
} catch (Exception e) {
169-
result.error("100", "Fail closed ocr model", e);
170-
}
171-
}
172-
17399
private void load_yolo_model(Map<String, Object> args) throws Exception {
174-
final String model = this.assets.getAssetFilePathByName(args.get("model_path").toString());
175-
final Object is_asset_obj = args.get("is_asset");
100+
String model = "";
101+
final Object is_asset_obj = args.get("is_asset");
176102
final boolean is_asset = is_asset_obj == null ? false : (boolean) is_asset_obj;
103+
String label_path = "";
104+
if(is_asset){
105+
model = this.assets.getAssetFilePathByName(args.get("model_path").toString());
106+
label_path = this.assets.getAssetFilePathByName(args.get("label_path").toString());
107+
}else{
108+
model = args.get("model_path").toString();
109+
label_path = args.get("label_path").toString();
110+
}
177111
final int num_threads = (int) args.get("num_threads");
178112
final boolean quantization = (boolean) args.get("quantization");
179113
final boolean use_gpu = (boolean) args.get("use_gpu");
180-
final String label_path = this.assets.getAssetFilePathByName(args.get("label_path").toString());
181114
final int rotation = (int) args.get("rotation");
182115
final String version = args.get("model_version").toString();
183116
switch (version) {
@@ -316,68 +249,6 @@ private void close_yolo_model(Result result) {
316249
}
317250
}
318251

319-
private void load_tesseract_model(Map<String, Object> args) throws Exception {
320-
final String tess_data = args.get("tess_data").toString();
321-
final Map<String, String> arg = (Map<String, String>) args.get("arg");
322-
final String language = args.get("language").toString();
323-
tesseract_model = new Tesseract(tess_data, arg, language);
324-
tesseract_model.initialize_model();
325-
}
326-
327-
class PredictionTask implements Runnable {
328-
private Tesseract tesseract;
329-
private Bitmap bitmap;
330-
private Result result;
331-
332-
public PredictionTask(Tesseract tesseract, Map<String, Object> args, Result result) {
333-
byte[] image = (byte[]) args.get("bytesList");
334-
this.tesseract = tesseract;
335-
this.bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
336-
this.result = result;
337-
}
338-
339-
@Override
340-
public void run() {
341-
try {
342-
Mat mat = utils.rgbBitmapToMatGray(bitmap);
343-
double angle = utils.computeSkewAngle(mat.clone());
344-
mat = utils.deskew(mat, angle);
345-
mat = utils.filterTextFromImage(mat);
346-
bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
347-
Utils.matToBitmap(mat, bitmap);
348-
// utils.getScreenshotBmp(bitmap,"TESSEREACT");
349-
result.success(tesseract.predict_text(bitmap));
350-
} catch (Exception e) {
351-
result.error("100", "Prediction text Error", e);
352-
}
353-
}
354-
}
355-
356-
private void tesseract_on_image(Map<String, Object> args, Result result) {
357-
try {
358-
PredictionTask predictionTask = new PredictionTask(tesseract_model, args, result);
359-
executor.submit(predictionTask);
360-
} catch (Exception e) {
361-
result.error("100", "Prediction Error", e);
362-
}
363-
}
364-
365-
private void close_tesseract_model(Result result) {
366-
try {
367-
close_tesseract();
368-
result.success("Tesseract model closed succesfully");
369-
} catch (Exception e) {
370-
result.error("100", "close_tesseract_model error", e);
371-
}
372-
}
373-
374-
private void close_tesseract(){
375-
if (tesseract_model != null) {
376-
tesseract_model.close();
377-
tesseract_model = null;
378-
}
379-
}
380-
381252
private void close_yolo(){
382253
if (yolo_model != null) {
383254
yolo_model.close();

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

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)