Skip to content

Commit

Permalink
Merge pull request #27 from LeeTaeYeong00/master
Browse files Browse the repository at this point in the history
object 라벨 수정 및 tts+진동
  • Loading branch information
LeeTaeYeong00 authored May 10, 2024
2 parents 350eab9 + 1efc631 commit e907080
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 83 deletions.
3 changes: 2 additions & 1 deletion frontend/pradtice/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:label="pradtice"
android:label="EYE-U"
tools:replace="android:label"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
196 changes: 126 additions & 70 deletions frontend/pradtice/lib/ObjectRecognitionMode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<CameraDescription> cameras;
main() async {

void main() async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
runApp(
Expand All @@ -22,6 +25,7 @@ main() async {
);
}


class ObjectReco extends StatefulWidget {
const ObjectReco({Key? key}) : super(key: key);

Expand All @@ -32,6 +36,7 @@ class ObjectReco extends StatefulWidget {
class _ObjectRecoState extends State<ObjectReco> {
late FlutterVision vision;
Options option = Options.frame;

@override
void initState() {
super.initState();
Expand All @@ -48,7 +53,8 @@ class _ObjectRecoState extends State<ObjectReco> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: task(option),);
body: task(option),
);
}

Widget task(Options option) {
Expand All @@ -61,6 +67,7 @@ class _ObjectRecoState extends State<ObjectReco> {

class YoloVideo extends StatefulWidget {
final FlutterVision vision;

const YoloVideo({Key? key, required this.vision}) : super(key: key);

@override
Expand All @@ -73,24 +80,25 @@ class _YoloVideoState extends State<YoloVideo> {
CameraImage? cameraImage;
bool isLoaded = false;
bool isDetecting = false;
TTS tts = TTS(message: '');


@override
void initState() {
super.initState();
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 = [];
});
}

Expand All @@ -115,9 +123,7 @@ class _YoloVideoState extends State<YoloVideo> {
children: [
AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(
controller,
),
child: CameraPreview(controller),
),
...displayBoxesAroundRecognizedObjects(size),
Positioned(
Expand All @@ -129,26 +135,16 @@ class _YoloVideoState extends State<YoloVideo> {
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,
),
Expand All @@ -158,70 +154,131 @@ class _YoloVideoState extends State<YoloVideo> {
);
}

// YOLO 모델 로드
Future<void> loadYoloModel() async {
await widget.vision.loadYoloModel(
labels: 'assets/labels.txt',
modelPath: 'assets/yolov5n.tflite', // 모델 수정 부분
modelVersion: "yolov5",
numThreads: 2,
useGpu: true);
setState(() {
isLoaded = true;
});
}

Future<void> 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<void> 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<void> stopDetection() async {
setState(() {
isDetecting = false;
yoloResults.clear();
});
}

// 카메라 프레임에서 YOLO 객체 탐지
Future<void> 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<String> targetLabels = [
"bicycle",
"car",
"motorbike",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"person",
"chair"
];

// 필터링된 결과를 저장할 리스트
List<Map<String, dynamic>> filteredResults = [];

// 필터링된 결과를 추출
for (var obj in result) {
if (targetLabels.contains(obj['tag'])) {
filteredResults.add(obj);
}
}

// 필터링된 결과를 사용하여 작업 수행
for (var obj in filteredResults) {
double bottomY = obj['box'][1] + obj['box'][3];
if (bottomY > 730 && targetLabels.contains(obj['tag'])) {
tts.setMessage('위험');
tts.speak();
Vibration.vibrate(duration: 500);
}
print("전체 값 : $result");
print("첫 번째 물체의 바운딩 박스 하단 Y 좌표: $bottomY");
}

// 필터링된 결과를 yoloResults에 업데이트
yoloResults = filteredResults;
});
}
}

// 객체를 인식하여 박스 표시
List<Widget> displayBoxesAroundRecognizedObjects(Size screen) {
if (yoloResults.isEmpty) return [];

double factorX = screen.width / (cameraImage?.height ?? 1);
double factorY = screen.height / (cameraImage?.width ?? 1);

// 필터링할 클래스 레이블
List<String> targetLabels = [
"bicycle",
"car",
"motorbike",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"person",
"chair"
];

// 필터링된 결과를 저장할 리스트
List<Map<String, dynamic>> filteredResults = [];

// 필터링된 결과를 추출
for (var result in yoloResults) {
if (targetLabels.contains(result['tag'])) {
filteredResults.add(result);
}
}

Color colorPick = const Color.fromARGB(255, 50, 233, 30);

return yoloResults.map((result) {
return filteredResults.map((result) {
return Positioned(
left: result["box"][0] * factorX,
top: result["box"][1] * factorY,
width: (result["box"][2] - result["box"][0]) * factorX,
width: (result["box"][2] - result["box"][0]) * factorX,
height: (result["box"][3] - result["box"][1]) * factorY,
child: Container(
decoration: BoxDecoration(
Expand Down Expand Up @@ -271,4 +328,3 @@ class PolygonPainter extends CustomPainter {
return false;
}
}

2 changes: 1 addition & 1 deletion frontend/pradtice/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class _MyHomePageState extends State<MyHomePage> {
super.initState();
tts.setMessage('화면을 탭하세요');
tts.speak();
sever.getID();

}
@override
Widget build(BuildContext context) {
Expand Down
17 changes: 9 additions & 8 deletions frontend/pradtice/lib/sever.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import 'package:http/http.dart' as http; // http 사용 패키지
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:pradtice/location_permission.dart'; //json 변환 패키지
import 'GetAndroidID.dart';
import 'dart:async';

import 'GetAndroidID.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class NaviTap extends StatefulWidget {
Expand Down Expand Up @@ -80,8 +79,16 @@ class Sever {
var distance = '0';
var uuid = '';

GetID getID = GetID();

setid(){
uuid = getID.id;
print('uuid = $uuid');
}


Future<void> start_navi() async {
setid();
myLocation.getMyCurrentLocation();
Lat = myLocation.latitude;
Lon = myLocation.longitude;
Expand Down Expand Up @@ -145,12 +152,6 @@ class Sever {
}
}

getID(){
GetID getid = GetID();
uuid = getid.id;
print('uuid : '+uuid);
}

}

class testmap extends StatefulWidget {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import FlutterMacOS
import Foundation

import device_info_plus
import file_selector_macos
import flutter_tts
import geolocator_apple
import path_provider_foundation
import speech_to_text_macos

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
Expand Down
Loading

0 comments on commit e907080

Please sign in to comment.