Skip to content

Commit 0697329

Browse files
committed
updated code
1 parent 8d72be8 commit 0697329

16 files changed

+338
-1176
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Issue
22
<img src="issue_image.png" />
33

4+
# For Support Flutter 3v
5+
Checkout Branch v3
6+
47
## To solve this issue replace this function declaration to
58
````
69
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>,grantResults: IntArray):

android/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
buildscript {
2-
ext.kotlin_version = '1.6.10'
2+
ext.kotlin_version = '1.8.0'
33
repositories {
44
google()
55
mavenCentral()
@@ -26,6 +26,6 @@ subprojects {
2626
project.evaluationDependsOn(':app')
2727
}
2828

29-
task clean(type: Delete) {
29+
tasks.register("clean", Delete) {
3030
delete rootProject.buildDir
3131
}

install.bat

-37
This file was deleted.

issue_image.png

-126 KB
Binary file not shown.

lib/main.dart

+218-9
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,233 @@
11
import 'package:flutter/material.dart';
2-
import 'package:flutter/services.dart';
3-
import 'package:realtime_obj_detection/ui/home_view.dart';
2+
import 'package:camera/camera.dart';
3+
import 'package:flutter/widgets.dart';
4+
import 'package:tflite_v2/tflite_v2.dart';
45

56
void main() async {
67
WidgetsFlutterBinding.ensureInitialized();
7-
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
8-
runApp(MyApp());
8+
final cameras = await availableCameras();
9+
runApp(MyApp(cameras: cameras));
910
}
1011

1112
class MyApp extends StatelessWidget {
13+
final List<CameraDescription> cameras;
14+
15+
const MyApp({Key? key, required this.cameras});
16+
1217
@override
1318
Widget build(BuildContext context) {
1419
return MaterialApp(
1520
debugShowCheckedModeBanner: false,
16-
title: 'Object Detection TFLite',
17-
theme: ThemeData(
18-
primarySwatch: Colors.blue,
19-
visualDensity: VisualDensity.adaptivePlatformDensity,
21+
home: RealTimeObjectDetection(
22+
cameras: cameras,
2023
),
21-
home: HomeView(),
24+
);
25+
}
26+
}
27+
28+
class RealTimeObjectDetection extends StatefulWidget {
29+
final List<CameraDescription> cameras;
30+
31+
RealTimeObjectDetection({required this.cameras});
32+
33+
@override
34+
_RealTimeObjectDetectionState createState() =>
35+
_RealTimeObjectDetectionState();
36+
}
37+
38+
class _RealTimeObjectDetectionState extends State<RealTimeObjectDetection> {
39+
late CameraController _controller;
40+
bool isModelLoaded = false;
41+
List<dynamic>? recognitions;
42+
int imageHeight = 0;
43+
int imageWidth = 0;
44+
45+
@override
46+
void initState() {
47+
super.initState();
48+
loadModel();
49+
initializeCamera(null);
50+
}
51+
52+
@override
53+
void dispose() {
54+
_controller.dispose();
55+
super.dispose();
56+
}
57+
58+
Future<void> loadModel() async {
59+
String? res = await Tflite.loadModel(
60+
model: 'assets/detect.tflite',
61+
labels: 'assets/labelmap.txt',
62+
);
63+
setState(() {
64+
isModelLoaded = res != null;
65+
});
66+
}
67+
68+
void toggleCamera() {
69+
final lensDirection = _controller.description.lensDirection;
70+
CameraDescription newDescription;
71+
if (lensDirection == CameraLensDirection.front) {
72+
newDescription = widget.cameras.firstWhere((description) =>
73+
description.lensDirection == CameraLensDirection.back);
74+
} else {
75+
newDescription = widget.cameras.firstWhere((description) =>
76+
description.lensDirection == CameraLensDirection.front);
77+
}
78+
79+
if (newDescription != null) {
80+
initializeCamera(newDescription);
81+
} else {
82+
print('Asked camera not available');
83+
}
84+
}
85+
86+
void initializeCamera(description) async {
87+
if (description == null) {
88+
_controller = CameraController(
89+
widget.cameras[0],
90+
ResolutionPreset.high,
91+
enableAudio: false,
92+
);
93+
} else {
94+
_controller = CameraController(
95+
description,
96+
ResolutionPreset.high,
97+
enableAudio: false,
98+
);
99+
}
100+
101+
await _controller.initialize();
102+
103+
if (!mounted) {
104+
return;
105+
}
106+
_controller.startImageStream((CameraImage image) {
107+
if (isModelLoaded) {
108+
runModel(image);
109+
}
110+
});
111+
setState(() {});
112+
}
113+
114+
void runModel(CameraImage image) async {
115+
if (image.planes.isEmpty) return;
116+
117+
var recognitions = await Tflite.detectObjectOnFrame(
118+
bytesList: image.planes.map((plane) => plane.bytes).toList(),
119+
model: 'SSDMobileNet',
120+
imageHeight: image.height,
121+
imageWidth: image.width,
122+
imageMean: 127.5,
123+
imageStd: 127.5,
124+
numResultsPerClass: 1,
125+
threshold: 0.4,
126+
);
127+
128+
setState(() {
129+
this.recognitions = recognitions;
130+
// imageHeight = image.height;
131+
// imageWidth = image.width;
132+
});
133+
}
134+
135+
@override
136+
Widget build(BuildContext context) {
137+
if (!_controller.value.isInitialized) {
138+
return Container();
139+
}
140+
return Scaffold(
141+
appBar: AppBar(
142+
title: Text('Real-time Object Detection'),
143+
),
144+
body: Column(
145+
// mainAxisAlignment: MainAxisAlignment.center,
146+
147+
children: [
148+
Container(
149+
width: MediaQuery.of(context).size.width,
150+
height: MediaQuery.of(context).size.height * 0.8,
151+
child: Stack(
152+
children: [
153+
CameraPreview(_controller),
154+
if (recognitions != null)
155+
BoundingBoxes(
156+
recognitions: recognitions!,
157+
previewH: imageHeight.toDouble(),
158+
previewW: imageWidth.toDouble(),
159+
screenH: MediaQuery.of(context).size.height * 0.8,
160+
screenW: MediaQuery.of(context).size.width,
161+
),
162+
],
163+
),
164+
),
165+
Row(
166+
mainAxisAlignment: MainAxisAlignment.center,
167+
children: [
168+
IconButton(
169+
onPressed: () {
170+
toggleCamera();
171+
},
172+
icon: Icon(
173+
Icons.camera_front,
174+
size: 30,
175+
))
176+
],
177+
)
178+
],
179+
),
180+
);
181+
}
182+
}
183+
184+
class BoundingBoxes extends StatelessWidget {
185+
final List<dynamic> recognitions;
186+
final double previewH;
187+
final double previewW;
188+
final double screenH;
189+
final double screenW;
190+
191+
BoundingBoxes({
192+
required this.recognitions,
193+
required this.previewH,
194+
required this.previewW,
195+
required this.screenH,
196+
required this.screenW,
197+
});
198+
199+
@override
200+
Widget build(BuildContext context) {
201+
return Stack(
202+
children: recognitions.map((rec) {
203+
var x = rec["rect"]["x"] * screenW;
204+
var y = rec["rect"]["y"] * screenH;
205+
double w = rec["rect"]["w"] * screenW;
206+
double h = rec["rect"]["h"] * screenH;
207+
208+
return Positioned(
209+
left: x,
210+
top: y,
211+
width: w,
212+
height: h,
213+
child: Container(
214+
decoration: BoxDecoration(
215+
border: Border.all(
216+
color: Colors.red,
217+
width: 3,
218+
),
219+
),
220+
child: Text(
221+
"${rec["detectedClass"]} ${(rec["confidenceInClass"] * 100).toStringAsFixed(0)}% Width:${(w).ceil()} Heght: ${h.ceil()}",
222+
style: TextStyle(
223+
color: Colors.red,
224+
fontSize: 15,
225+
background: Paint()..color = Colors.black,
226+
),
227+
),
228+
),
229+
);
230+
}).toList(),
22231
);
23232
}
24233
}

0 commit comments

Comments
 (0)