Open
Description
Problem Description
I had used the example which is prefectly with my model. Now I have tried to feed a single image using camera to take a picture or image picker to get the image from the gallery. but somehow it's not working throwing an error. the issue is coming from here
Performing hot restart...
Restarted application in 2,217ms.
I/flutter (14663): File copied to: /data/user/0/com.ultralytics.ultralytics_yolo_example/files/assets/yolov8m_int8.tflite
I/flutter (14663): File copied to: /data/user/0/com.ultralytics.ultralytics_yolo_example/files/assets/metadata.yaml
I/System.out(14663): INPUT_SIZE:320
I/tflite (14663): Replacing 318 out of 318 node(s) with delegate (TfLiteGpuDelegateV2) node, yielding 1 partitions for the whole graph.
I/tflite (14663): Created 1 GPU delegate kernels.
I/flutter (14663): File exists
E/flutter (14663): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type '_Map<Object?, Object?>' is not a subtype of type 'Map<String, dynamic>?' in type cast
E/flutter (14663): #0 PlatformChannelUltralyticsYolo.detectImage.<anonymous closure> (package:ultralytics_yolo/ultralytics_yolo_platform_channel.dart:152:19)
E/flutter (14663): #1 _Array.forEach (dart:core-patch/array.dart:40:8)
E/flutter (14663): #2 PlatformChannelUltralyticsYolo.detectImage (package:ultralytics_yolo/ultralytics_yolo_platform_channel.dart:151:13)
E/flutter (14663): <asynchronous suspension>
E/flutter (14663): #3 _ImageDetectionScreenState._captureAndDetectImage (package:ultralytics_yolo_example/main.dart:120:31)
E/flutter (14663): <asynchronous suspension>
E/flutter (14663):
Reproducible Code
import 'package:flutter/material.dart';
import 'dart:io' as io;
import 'package:image_picker/image_picker.dart';
import 'package:ultralytics_yolo/ultralytics_yolo.dart';
import 'package:ultralytics_yolo/yolo_model.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ImageDetectionScreen(),
);
}
}
class ImageDetectionScreen extends StatefulWidget {
@override
_ImageDetectionScreenState createState() => _ImageDetectionScreenState();
}
class _ImageDetectionScreenState extends State<ImageDetectionScreen> {
late ObjectDetector detector;
List<DetectedObject?>? _detectedObjects;
final ImagePicker _picker = ImagePicker();
String? _imagePath;
@override
void initState() {
super.initState();
_initializeDetector();
}
Future<void> _initializeDetector() async {
final modelPath = await _copy('assets/yolov8m_int8.tflite');
final metadataPath = await _copy('assets/metadata.yaml');
final model = LocalYoloModel(
id: 'custom_model',
modelPath: modelPath,
task: Task.detect,
format: Format.tflite,
metadataPath: metadataPath);
detector = ObjectDetector(model: model);
await detector.loadModel();
}
Future<bool> _checkPermissions() async {
List<Permission> permissions = [];
var cameraStatus = await Permission.camera.status;
if (!cameraStatus.isGranted) permissions.add(Permission.camera);
var storageStatus = await Permission.storage.status;
if (!storageStatus.isGranted) permissions.add(Permission.storage);
if (permissions.isEmpty) {
return true;
} else {
try {
Map<Permission, PermissionStatus> statuses =
await permissions.request();
return statuses[Permission.camera] == PermissionStatus.granted &&
statuses[Permission.storage] == PermissionStatus.granted;
} on Exception catch (_) {
return false;
}
}
}
Future<String> _copy(String assetPath) async {
try {
final directory = await getApplicationSupportDirectory();
final path = join(directory.path, assetPath);
await io.Directory(dirname(path)).create(recursive: true);
final file = io.File(path);
if (!await file.exists()) {
final byteData = await rootBundle.load(assetPath);
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
}
print('File copied to: $path');
return file.path;
} catch (e) {
print('Error copying file: $e');
rethrow;
}
}
Future<void> _captureAndDetectImage(ImageSource source) async {
bool permissionsGranted = await _checkPermissions();
if (!permissionsGranted) {
ScaffoldMessenger.of(this.context).showSnackBar(
SnackBar(content: Text('Permissions not granted')),
);
return;
}
final pickedFile = await _picker.pickImage(source: source);
if (pickedFile != null) {
setState(() {
_imagePath = pickedFile.path;
});
// check if the file exists or not
if (!await File(pickedFile.path).exists()) {
print('File does not exist');
return;
} else {
print('File exists');
}
final detectedObjects = await detector.detect(imagePath: pickedFile.path);
print('Raw detection output: $detectedObjects');
if (detectedObjects == null || detectedObjects.isEmpty) {
print('No objects detected or empty response');
setState(() {
_detectedObjects = [];
});
return;
}
setState(() {
_detectedObjects = detectedObjects;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('YOLO Image Detection'),
),
body: Column(
children: [
if (_imagePath != null) Image.file(File(_imagePath!)),
if (_detectedObjects != null)
Expanded(
child: ListView.builder(
itemCount: _detectedObjects!.length,
itemBuilder: (context, index) {
final detectedObject = _detectedObjects![index];
if (detectedObject == null) return Container();
return ListTile(
title: Text('Label: ${detectedObject.label}'),
subtitle: Text(
'Confidence: ${(detectedObject.confidence * 100).toStringAsFixed(2)}%'),
);
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => _captureAndDetectImage(ImageSource.camera),
child: Text('Capture Image'),
),
SizedBox(width: 20),
ElevatedButton(
onPressed: () => _captureAndDetectImage(ImageSource.gallery),
child: Text('Import Image'),
),
],
),
],
),
);
}
}