diff --git a/frontend/pradtice/android/app/src/main/AndroidManifest.xml b/frontend/pradtice/android/app/src/main/AndroidManifest.xml
index ca97cf0edb..637dc812e0 100644
--- a/frontend/pradtice/android/app/src/main/AndroidManifest.xml
+++ b/frontend/pradtice/android/app/src/main/AndroidManifest.xml
@@ -10,8 +10,9 @@
+
diff --git a/frontend/pradtice/android/gradle/wrapper/gradle-wrapper.properties b/frontend/pradtice/android/gradle/wrapper/gradle-wrapper.properties
index e1ca574ef0..b9b69fee5f 100644
--- a/frontend/pradtice/android/gradle/wrapper/gradle-wrapper.properties
+++ b/frontend/pradtice/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
+distributionUrl=dist/gradle-7.6.3-all.zip
diff --git a/frontend/pradtice/lib/ObjectRecognitionMode.dart b/frontend/pradtice/lib/ObjectRecognitionMode.dart
index ece069e6dc..ce26605913 100644
--- a/frontend/pradtice/lib/ObjectRecognitionMode.dart
+++ b/frontend/pradtice/lib/ObjectRecognitionMode.dart
@@ -8,11 +8,14 @@ import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'dart:async';
import 'package:flutter_vision/flutter_vision.dart';
import 'package:image_picker/image_picker.dart';
+import 'TextToSpeech.dart';
+import 'package:vibration/vibration.dart';
enum Options { none, imagev5, imagev8, imagev8seg, frame }
late List cameras;
-main() async {
+
+void main() async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
runApp(
@@ -22,6 +25,7 @@ main() async {
);
}
+
class ObjectReco extends StatefulWidget {
const ObjectReco({Key? key}) : super(key: key);
@@ -32,6 +36,7 @@ class ObjectReco extends StatefulWidget {
class _ObjectRecoState extends State {
late FlutterVision vision;
Options option = Options.frame;
+
@override
void initState() {
super.initState();
@@ -48,7 +53,8 @@ class _ObjectRecoState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
- body: task(option),);
+ body: task(option),
+ );
}
Widget task(Options option) {
@@ -61,6 +67,7 @@ class _ObjectRecoState extends State {
class YoloVideo extends StatefulWidget {
final FlutterVision vision;
+
const YoloVideo({Key? key, required this.vision}) : super(key: key);
@override
@@ -73,6 +80,8 @@ class _YoloVideoState extends State {
CameraImage? cameraImage;
bool isLoaded = false;
bool isDetecting = false;
+ TTS tts = TTS(message: '');
+
@override
void initState() {
@@ -80,17 +89,16 @@ class _YoloVideoState extends State {
init();
}
- init() async {
+ // 카메라 초기화
+ void init() async {
cameras = await availableCameras();
controller = CameraController(cameras[0], ResolutionPreset.medium);
- controller.initialize().then((value) {
- loadYoloModel().then((value) {
- setState(() {
- isLoaded = true;
- isDetecting = false;
- yoloResults = [];
- });
- });
+ await controller.initialize();
+ await loadYoloModel();
+ setState(() {
+ isLoaded = true;
+ isDetecting = false;
+ yoloResults = [];
});
}
@@ -115,9 +123,7 @@ class _YoloVideoState extends State {
children: [
AspectRatio(
aspectRatio: controller.value.aspectRatio,
- child: CameraPreview(
- controller,
- ),
+ child: CameraPreview(controller),
),
...displayBoxesAroundRecognizedObjects(size),
Positioned(
@@ -129,26 +135,16 @@ class _YoloVideoState extends State {
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
- width: 5, color: Colors.white, style: BorderStyle.solid),
- ),
- child: isDetecting
- ? IconButton(
- onPressed: () async {
- stopDetection();
- },
- icon: const Icon(
- Icons.stop,
- color: Colors.red,
- ),
- iconSize: 50,
- )
- : IconButton(
- onPressed: () async {
- await startDetection();
- },
- icon: const Icon(
- Icons.play_arrow,
+ width: 5,
color: Colors.white,
+ style: BorderStyle.solid,
+ ),
+ ),
+ child: IconButton(
+ onPressed: isDetecting ? stopDetection : startDetection,
+ icon: Icon(
+ isDetecting ? Icons.stop : Icons.play_arrow,
+ color: isDetecting ? Colors.red : Colors.white,
),
iconSize: 50,
),
@@ -158,51 +154,33 @@ class _YoloVideoState extends State {
);
}
+ // YOLO 모델 로드
Future loadYoloModel() async {
await widget.vision.loadYoloModel(
- labels: 'assets/labels.txt',
- modelPath: 'assets/yolov5n.tflite', // 모델 수정 부분
- modelVersion: "yolov5",
- numThreads: 2,
- useGpu: true);
- setState(() {
- isLoaded = true;
- });
- }
-
- Future yoloOnFrame(CameraImage cameraImage) async {
- final result = await widget.vision.yoloOnFrame(
- bytesList: cameraImage.planes.map((plane) => plane.bytes).toList(),
- imageHeight: cameraImage.height,
- imageWidth: cameraImage.width,
- iouThreshold: 0.4,
- confThreshold: 0.4,
- classThreshold: 0.5);
-
- if (result.isNotEmpty) {
- setState(() {
- //코드 수정부분
- print("결과 보여줄게 잘: $result");
- yoloResults = result;
- });
- }
+ labels: 'assets/labels.txt',
+ modelPath: 'assets/yolov5n.tflite',
+ modelVersion: "yolov5",
+ numThreads: 2,
+ useGpu: true,
+ );
}
+ // 객체 탐지 시작
Future startDetection() async {
setState(() {
isDetecting = true;
});
- if (controller.value.isStreamingImages) {
- return;
+ if (!controller.value.isStreamingImages) {
+ await controller.startImageStream((image) {
+ if (isDetecting) {
+ cameraImage = image;
+ yoloOnFrame(image);
+ }
+ });
}
- await controller.startImageStream((image) async {
- if (isDetecting) {
- cameraImage = image;
- yoloOnFrame(image);
- }
- });
}
+ // 객체 탐지 중지
Future stopDetection() async {
setState(() {
isDetecting = false;
@@ -210,18 +188,97 @@ class _YoloVideoState extends State {
});
}
+ // 카메라 프레임에서 YOLO 객체 탐지
+ Future yoloOnFrame(CameraImage cameraImage) async {
+ final result = await widget.vision.yoloOnFrame(
+ bytesList: cameraImage.planes.map((plane) => plane.bytes).toList(),
+ imageHeight: cameraImage.height,
+ imageWidth: cameraImage.width,
+ iouThreshold: 0.4,
+ confThreshold: 0.4,
+ classThreshold: 0.5,
+ );
+
+ if (result.isNotEmpty) {
+ setState(() {
+ // 필터링할 클래스 레이블
+ List targetLabels = [
+ "bicycle",
+ "car",
+ "motorbike",
+ "traffic light",
+ "fire hydrant",
+ "stop sign",
+ "parking meter",
+ "person",
+ "chair"
+ ];
+
+ // 필터링된 결과를 저장할 리스트
+ List