`I’m trying to make an android real-time object detection app with a custom model. I’ve added my model but I’m getting this problem when I run the code. I’m new to flutter so I couldnt solve the problem..
W/FlutterJNI(21251): Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: plugins.flutter.io/camera_android/imageStream. Response ID: 783`
dependencies:
flutter:
sdk: flutter
camera: ^0.10.6
get: ^4.6.6
permission_handler: ^11.3.1
flutter_tflite: ^1.0.1
image: ^3.2.0
build.gradle
android {
namespace "com.example.beet"
compileSdkVersion 34
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
aaptOptions {
noCompress 'tflite'
noCompress 'lite'
}
kotlinOptions {
jvmTarget = '1.8'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
(https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.beet"
minSdkVersion 26
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Scan Controller
import 'dart:typed_data';
import 'package:camera/camera.dart';
import 'package:flutter_tflite/flutter_tflite.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image/image.dart' as img;
class ScanController extends GetxController {
late CameraController cameraController;
late List<CameraDescription> cameras;
var isCameraInitialized = false.obs;
var cameraCount = 0;
var x = 0.0, y = 0.0, w = 0.0, h = 0.0;
var label = "";
@override
void onInit() {
super.onInit();
initCamera();
initTFLite();
}
@override
void dispose() {
cameraController.dispose();
super.dispose();
}
Future<void> initCamera() async {
if (await Permission.camera.request().isGranted) {
cameras = await availableCameras();
cameraController = CameraController(cameras[0], ResolutionPreset.max);
try {
await cameraController.initialize().then((_) {
isCameraInitialized(true);
cameraController.startImageStream((image) {
cameraCount++;
if (cameraCount % 10 == 0) {
cameraCount = 0;
objectDetector(image);
}
});
});
} catch (e) {
print("Camera initialization error: $e");
}
} else {
print("Camera permission denied");
}
update();
}
Future<void> initTFLite() async {
try {
await Tflite.loadModel(
model: "assets/best.tflite",
labels: "assets/label.txt",
isAsset: true,
numThreads: 1,
useGpuDelegate: false,
);
print("Model loaded successfully");
} catch (e) {
print("Error loading model: $e");
}
}
Uint8List imageToByteListFloat32(img.Image image, int inputSize) {
var convertedBytes = Float32List(1 * inputSize * inputSize * 3);
var buffer = Float32List.view(convertedBytes.buffer);
int pixelIndex = 0;
for (var i = 0; i < inputSize; i++) {
for (var j = 0; j < inputSize; j++) {
var pixel = image.getPixel(j, i);
buffer[pixelIndex++] = (img.getRed(pixel) / 127.5) - 1;
buffer[pixelIndex++] = (img.getGreen(pixel) / 127.5) - 1;
buffer[pixelIndex++] = (img.getBlue(pixel) / 127.5) - 1;
}
}
return convertedBytes.buffer.asUint8List();
}
Future<void> objectDetector(CameraImage image) async {
print("Starting object detection");
final int width = image.width;
final int height = image.height;
// Convert CameraImage to Image package format
img.Image imgImage = img.Image(width, height);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
final int uvIndex = (i ~/ 2) * (image.planes[1].bytesPerRow ~/ 2) + (j ~/ 2);
final int index = i * width + j;
final y = image.planes[0].bytes[index];
final u = image.planes[1].bytes[uvIndex];
final v = image.planes[2].bytes[uvIndex];
imgImage.setPixel(j, i, yuvToRgb(y, u, v));
}
}
// Resize the image to the size your model expects
img.Image resizedImage = img.copyResize(imgImage, width: 224, height: 224);
Uint8List input = imageToByteListFloat32(resizedImage, 224);
var detector = await Tflite.runModelOnFrame(
bytesList: [input],
imageHeight: 224,
imageWidth: 224,
imageMean: 0.0,
imageStd: 1.0,
numResults: 1,
rotation: 90,
threshold: 0.4,
);
if (detector != null && detector.isNotEmpty) {
print("Object detected: $detector");
var ourDetectedObject = detector.first;
if (ourDetectedObject['confidenceInClass'] * 100 > 45) {
label = ourDetectedObject['detectedClass'].toString();
h = ourDetectedObject['rect']['h'];
w = ourDetectedObject['rect']['w'];
x = ourDetectedObject['rect']['x'];
y = ourDetectedObject['rect']['y'];
} else {
print("Detection confidence too low");
}
} else {
print("No objects detected");
}
update();
}
int yuvToRgb(int y, int u, int v) {
int r = (y + (1.370705 * (v - 128))).toInt();
int g = (y - (0.337633 * (u - 128)) - (0.698001 * (v - 128))).toInt();
int b = (y + (1.732446 * (u - 128))).toInt();
r = r.clamp(0, 255);
g = g.clamp(0, 255);
b = b.clamp(0, 255);
return img.getColor(r, g, b);
}
}
Camera view
import 'package:beet1/controller/scan_controller.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class CameraView extends StatelessWidget {
const CameraView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: GetBuilder<ScanController>(
init: ScanController(),
builder: (controller) {
if (!controller.isCameraInitialized.value) {
return const Center(child: Text("Loading Preview"));
}
return Stack(
children: [
CameraPreview(controller.cameraController),
Positioned(
top: (controller.y * context.height).toDouble(),
right: (controller.x * context.width).toDouble(),
child: Container(
width: (controller.w * context.width).toDouble(),
height: (controller.h * context.height).toDouble(),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.green, width: 4.0),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Colors.white,
child: Text(controller.label),
),
],
),
),
),
],
);
},
),
);
}
}
I've googled the problem but I couldn't quite understand what I shoul do, I have checked https://medium.com/@gauravpaudel2013/tried-to-send-a-platform-message-to-flutter-but-flutterjni-was-detached-from-native-c-well-well-c7d9ccf0df96 https://github.com/flutter/flutter/issues/117061 these websites.
Nisa Nur Taş is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.