TIF_E41201615/lib/main.dart

212 lines
5.2 KiB
Dart

import 'dart:io';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_vision/flutter_vision.dart';
import 'package:image_picker/image_picker.dart';
enum Options { none, imagev8 }
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MaterialApp(
home: MyApp(),
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late FlutterVision vision;
Options option = Options.none;
@override
void initState() {
super.initState();
vision = FlutterVision();
}
@override
void dispose() async {
super.dispose();
await vision.closeYoloModel();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: task(option),
);
}
Widget task(Options option) {
return YoloImageV8(vision: vision);
}
}
class YoloImageV8 extends StatefulWidget {
final FlutterVision vision;
const YoloImageV8({Key? key, required this.vision}) : super(key: key);
@override
State<YoloImageV8> createState() => _YoloImageV8State();
}
class _YoloImageV8State extends State<YoloImageV8> {
late List<Map<String, dynamic>> yoloResults;
File? imageFile;
int imageHeight = 1;
int imageWidth = 1;
bool isLoaded = false;
@override
void initState() {
super.initState();
loadYoloModel().then((value) {
setState(() {
yoloResults = [];
isLoaded = true;
});
});
}
@override
void dispose() async {
super.dispose();
}
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
if (!isLoaded) {
return const Scaffold(
body: Center(
child: Text("Model not loaded, waiting for it"),
),
);
}
return Scaffold(
appBar: AppBar(
title: const Text("Yolo V8"),
),
body: Column(
children: [
Expanded(child: imageFile != null ? Image.file(imageFile!) : const SizedBox()),
Stack(
fit: StackFit.expand,
children: [
Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: pickImage,
child: const Text("ambil gmbr serah"),
),
// ElevatedButton(
// onPressed: yoloOnImage,
// child: const Text("Ya test"),
// )
],
),
),
],
),
...displayBoxesAroundRecognizedObjects(size),
],
),
);
}
Future<void> loadYoloModel() async {
await widget.vision.loadYoloModel(
labels: 'assets/labels.txt',
modelPath: 'assets/yolov8m_float16.tflite',
modelVersion: "yolov8",
quantization: false,
numThreads: 2,
useGpu: true,
);
setState(() {
isLoaded = true;
});
}
Future<void> pickImage() async {
final ImagePicker picker = ImagePicker();
final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
if (photo != null) {
setState(() {
imageFile = File(photo.path);
yoloOnImage();
});
}
}
yoloOnImage() async {
yoloResults.clear();
Uint8List byte = await imageFile!.readAsBytes();
final image = await decodeImageFromList(byte);
imageHeight = image.height;
imageWidth = image.width;
final result = await widget.vision.yoloOnImage(
bytesList: byte,
imageHeight: image.height,
imageWidth: image.width,
iouThreshold: 0.8,
confThreshold: 0.2,
classThreshold: 0.3,
);
if (result.isNotEmpty) {
setState(() {
yoloResults = result;
});
}
}
List<Widget> displayBoxesAroundRecognizedObjects(Size screen) {
if (yoloResults.isEmpty) return [];
double factorX = screen.width / (imageWidth);
double imgRatio = imageWidth / imageHeight;
double newWidth = imageWidth * factorX;
double newHeight = newWidth / imgRatio;
double factorY = newHeight / (imageHeight);
double pady = (screen.height - newHeight) / 2;
Color colorPick = const Color.fromARGB(255, 50, 233, 30);
return yoloResults.map((result) {
return Positioned(
left: result["box"][0] * factorX,
top: result["box"][1] * factorY + pady,
width: (result["box"][2] - result["box"][0]) * factorX,
height: (result["box"][3] - result["box"][1]) * factorY,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
border: Border.all(color: Colors.pink, width: 2.0),
),
child: Text(
"${result['tag']} ${(result['box'][4] * 100).toStringAsFixed(0)}%",
style: TextStyle(
background: Paint()..color = colorPick,
color: Colors.white,
fontSize: 12.0,
),
),
),
);
}).toList();
}
}