diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000..fcda34f0d6
Binary files /dev/null and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..af827079f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+# 백엔드
+.idea
+
diff --git a/README.md b/README.md
index b0c42847c6..8d9430b04c 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,310 @@
-# Welcome to GitHub
+### [EYE-U](https://kookmin-sw.github.io/capstone-2024-23/) 객체탐지를 활용한 시각장애인용 보행 보조 앱
+
+
+
+## 📌 프로젝트 개요 | Project Abstract
+**“혹시 흰 지팡이나 안내견에 의지하여 길을 걷는 시각장애인을 본 적 있나요?"**
+기존의 시각장애인을 위한 길 안내는 주로 점자판이나 안내견과 같은 수단을 사용해왔습니다.
+하지만 이러한 방법들은 여러 제약과 불편한 점이 있습니다.
+이 문제를 극복하기 위해 저희 EYE-U는 시각 장애가 있는 분들을 위한 내비게이션 앱을 개발하고자 합니다.
+본 프로젝트는 시각장애인 또는 저시력자분들을 주요 대상으로 하여, 그들이 일상 생활에서 겪는 보행의 불편함과 위험을 줄여주는 보행 보조 앱입니다.
+저희 앱은 실시간 음성 길 안내, 장애물 탐지, 위험물 알림 기능을 통해 이용자가 보다 안전하고 편리한 서비스를 경험할 수 있도록 도와줍니다.
+
+
+
+**“Have you ever seen a visually impaired person walking down the street relying on a white cane or guide dog?"**
+
+Existing route guidance for the visually impaired has mainly used means such as Braille boards or guide dogs. However, these methods have several limitations and inconveniences. To overcome this problem, we at EYE-U want to develop a navigation app for people with visual impairments.
+
+This project is a walking assistance app targeting people who are visually impaired or have low vision and reduces the discomfort and risk of walking they experience in their daily lives. Our app helps users experience a safer and more convenient service through real-time voice directions, obstacle detection, and dangerous goods notification functions.
+
+
+
+
+## 📘 주요 기능 | Key Features
+- 탐지 모드
+ - 장애물 및 위험물 탐지, 진동 경고
+- 보행 모드
+ - 실시간 내비게이션 길 음성 안내 + 위험물 탐지
+
+
+## 💡 EYE-U POINT
+- UI/UX
+ - 타겟 맞춤형 UI/UX
+
+- 보행자 친화 길안내
+ - 목적지 출입구 및 보행로를 우선
+
+- voice-all-in-one
+ - 불필요한 서비스 과정 제거
+ - VOICE만을 이용해서 모든 기능 이용 가능
+
+- 위험 물체 감지
+ - 실시간 위험물 감지 및 진동 경고
+
+
+
+
+## 📁 서비스 프로세스 | Sevice Process
+
+
+
+
+
+## 🎞 소개 영상 | Introduction video
+[](https://www.youtube.com/watch?v=sgO9tWCrPbo)
+
+
+
+## 🎞 시연 영상 | Demonstration video
+[](https://www.youtube.com/watch?v=FsVF8S9SSMI)
+
+
+
+
+
+
+## 🧑🏻💻 팀 소개 | Introduction of team members
+| **김호준** | **박성원** | **윤미나** | **이태영** | **정회창** |
+|:--------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:|
+| [ @hojuni9999](https://github.com/hojuni9999) | [ @XungHi](https://github.com/XungHi) | [ @yoon-mina](https://github.com/yoon-mina) | [ @LeeTaeYeong00](https://github.com/LeeTaeYeong00) | [ @picetea44](https://github.com/picetea44) |
+|****5206|****5207|****5209|****5211|****5212|
+|AI |Front-end|Back-end|Front-end|Back-end|
+
+
+
+
+
+## ⤴ 배포 | Distribution
+
+배포
+
+
+~~~
+- 어플리케이션 APK
+1. Android Studio - build
+
+2. 해당 위치에 설치된 APK 파일을 배포한다.
+capstone-2024-23\frontend\practice\build\app\outputs\flutter-apk
+
+~~~
+
+
+
+
+
+## 🔎 실행 방법 | Execution method
+
+
+실행 방법
+
+
+~~~
+1. git clone
+$ git clone https://github.com/kookmin-sw/capstone-2024-23.git
+
+2. Android Studio - build
+
+3. 해당 위치에 설치된 APK 파일 실행한다.
+capstone-2024-23\frontend\practice\build\app\outputs\flutter-apk
+~~~
+
+
+
+
+
+
+## ⚙ 환경 설정 | Configuration Settings
+
+
+서버 실행 환경 설정
+
+
+
+리눅스(우분투) 기준
+1. JAVA 설치
+
+~~~
+# 1.apt update
+$ sudo apt-get update
+
+# 2. java21 설치
+$ sudo apt-get install openjdk-21-jdk
-캡스톤 팀 생성을 축하합니다.
+# 3. 설치 후 버젼 확인
+$ java -version
+~~~
-## 팀소개 및 페이지를 꾸며주세요.
+2. 환경변수 설정
+
+~~~
+# 환경변수 확인 (아무것도 안떠야 정상)
+$ echo $JAVA_HOME
-- 프로젝트 소개
- - 프로젝트 설치방법 및 데모, 사용방법, 프리뷰등을 readme.md에 작성.
- - Api나 사용방법등 내용이 많을경우 wiki에 꾸미고 링크 추가.
+# Java 절대 경로 확인
+$ which java
+$ readlink -f "which java에서 나온 경로 기입"
+# 절대 경로 shift + ctrl + c로 복사해두기
-- 팀페이지 꾸미기
- - 프로젝트 소개 및 팀원 소개
- - index.md 예시보고 수정.
+# 환경변수 설정 진입 (초기화 방지)
+$ vi /etc/profile
-- GitHub Pages 리파지토리 Settings > Options > GitHub Pages
- - Source를 marster branch
- - Theme Chooser에서 태마선택
- - 수정후 팀페이지 확인하여 점검.
+# 파일 최하단에 아래 문구 삽입
+#JAVA_HOME에 아까 복사한 절대 경로 삽입
+export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
+export PATH=$PATH:$JAVA_HOME/bin
+export CLASSPATH=$JAVA_HOME/jre/lib
-**팀페이지 주소** -> https://kookmin-sw.github.io/ '{{자신의 리파지토리 아이디}}'
+# 환경변수 재확인 (경로가 떠야 정상)
+$ echo $JAVA_HOME
+~~~
-**예시)** 2023년 0조 https://kookmin-sw.github.io/capstone-2023-00/
+3. MySQL 설치 (원격 접속 설정 포함)
+
+~~~
+# mysql 설치
+$ apt-get install mysql-server
+# mysql 설치 확인
+$ mysql --version
-## 내용에 아래와 같은 내용들을 추가하세요.
+# mysql 실행(택1)
+$ mysql -u root -p # root 사용자 접근시
+$ mysql -u yoon -p # 특정 계정으로 접근시 ex) yoon 계정 사용
-### 1. 프로잭트 소개
+# mysql root 비밀번호 설정 (설치 후 반드시 설정)
+# 1. mysql 설정 들어가기
+mysql> use mysql
-프로젝트
+# 2. root 비밀번호 설정
+mysql> alter user "root"@"localhost" identified with mysql_native_password by "암호";
-### 2. 소개 영상
+# 3. 저장하기
+mysql> FLUSH PRIVILEGES;
-프로젝트 소개하는 영상을 추가하세요
+# 사용자 계정 생성하기
+# 1. mysql 설정 들어가기
+mysql> use mysql
-### 3. 팀 소개
+# 2. 외부 접근을 허용하는 사용자 추가하기(원격으로 mysql접근가능)
+create user '계정명'@'%' identified by '0000';
-팀을 소개하세요.
+# 3. 권한 부여해주기
+grant all privileges on *.* to '계정명'@'%';
+
+# 4. 저장하기
+mysql> FLUSH PRIVILEGES;
+
+# 외부 접속 허용하기
+# 1. 최고 권한 부여
+$ sudo su
+
+# 2. 경로 이동하기
+$ cd/etc/mysql/mysql.conf.d
+
+# 3. 편집기 실행
+$ vi mysqld.cnf
+
+# 4. bind-address 수정하기 (i 눌러 수정모드 진입, 수정 후 ESC 누르고 :wq 를 통해 저장 후 종료)
+bind-address = 0.0.0.0
+
+# 5. 서버 재시작
+service mysql restart
+~~~
+
+4. git clone
+
+~~~
+$ git clone https://github.com/kookmin-sw/capstone-2024-23.git
+~~~
+
+5. Build & Upload
+
+~~~
+1. Intellij bootJar 이용하여 빌드
+2. FileZilla 업로드
+호스트에 자신이 만든 EC2 IP 주소 입력하고, 키 파일에 EC2 생성시 받은 PEM 키 넣어주기
+~~~
+
+6. 서버 실행
+
+~~~
+ssh -i ~/capstone2024Key.pem ubuntu@EC2 IP 주소
+
+nohup java -jar 자바파일이름.jar &
+
+#prod 버젼으로 실행
+nohup java -jar -Dspring.profiles.active=prod 자바파일이름.jar &
+
+#config 별도 폴더 말고 외부의 application.properties 사용하기
+java -Dspring.config.location=classpath:/application.properties -jar yourapp.jar
+~~~
+
+
+
+
+클라이언트 실행 환경설정
+
+
+1. 안드로이드스튜디오 Download (sdk 29 이상)
+2. 플러터 3.19 버전 Download
+3. git clone
+$ git clone https://github.com/kookmin-sw/capstone-2024-23.git
+4. frontend/pradtice/pubspec.yaml -> flutter_vision-master 경로 설정 (본인 경로)
+
+~~~
+ path: /Users/yoon/StudioProjects/capstone-2024-23/frontend/flutter_vision-master
+~~~
+
+5. pubspec.yaml -> Pub.get Download
+
+
+
+
+
+
+안드로이드 실행 환경설정
+
+
+1. usb 휴대폰 연결
+2. 설정 -> 화면 7번 터치 -> 개발자모드 실행
+3. 앱 실행
+
+
+
+
+
+## 🗂 문서 | Document
+
+
+ 중간발표 자료
+
+ |
+
+ 최종발표 자료
+
+ |
+
사용자 매뉴얼
+
+ |
+
포스터
+
+
-팀원정보 및 담당이나 사진 및 SNS를 이용하여 소개하세요.
-
-### 4. 사용법
-
-소스코드제출시 설치법이나 사용법을 작성하세요.
-
-### 5. 기타
-
-추가적인 내용은 자유롭게 작성하세요.
-
-
-## Markdown을 사용하여 내용꾸미기
-
-Markdown은 작문을 스타일링하기위한 가볍고 사용하기 쉬운 구문입니다. 여기에는 다음을위한 규칙이 포함됩니다.
-
-```markdown
-Syntax highlighted code block
-
-# Header 1
-## Header 2
-### Header 3
-
-- Bulleted
-- List
-
-1. Numbered
-2. List
-
-**Bold** and _Italic_ and `Code` text
-
-[Link](url) and 
-```
-
-자세한 내용은 [GitHub Flavored Markdown](https://guides.github.com/features/mastering-markdown/).
-
-### Support or Contact
-
-readme 파일 생성에 추가적인 도움이 필요하면 [도움말](https://help.github.com/articles/about-readmes/) 이나 [contact support](https://github.com/contact) 을 이용하세요.
diff --git a/ai/.DS_Store b/ai/.DS_Store
new file mode 100644
index 0000000000..f0ab30677c
Binary files /dev/null and b/ai/.DS_Store differ
diff --git a/ai/Yolo/testIMG1.png b/ai/Yolo/testIMG1.png
new file mode 100644
index 0000000000..ed54e75b14
Binary files /dev/null and b/ai/Yolo/testIMG1.png differ
diff --git a/ai/Yolo/testIMG2.png b/ai/Yolo/testIMG2.png
new file mode 100644
index 0000000000..8025d6d2de
Binary files /dev/null and b/ai/Yolo/testIMG2.png differ
diff --git a/ai/Yolo/yoloTrain.ipynb b/ai/Yolo/yoloTrain.ipynb
new file mode 100644
index 0000000000..579e23914c
--- /dev/null
+++ b/ai/Yolo/yoloTrain.ipynb
@@ -0,0 +1 @@
+{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"gpuType":"T4","authorship_tag":"ABX9TyPlyeNcB6A7f/4cBDI2HaHc"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"accelerator":"GPU"},"cells":[{"cell_type":"code","source":["from google.colab import drive\n","drive.mount('/content/drive')"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"iAFJTAg6wvZu","executionInfo":{"status":"ok","timestamp":1706683023072,"user_tz":-540,"elapsed":22776,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"fc2d62e4-bfab-458f-e918-ac6d028b7cd4"},"execution_count":1,"outputs":[{"output_type":"stream","name":"stdout","text":["Mounted at /content/drive\n"]}]},{"cell_type":"code","source":[" !git clone https://github.com/ultralytics/yolov5"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"eprCi99sESw8","executionInfo":{"status":"ok","timestamp":1706683028036,"user_tz":-540,"elapsed":3242,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"b4caa5c0-859c-4279-813f-277c8eb075ec"},"execution_count":2,"outputs":[{"output_type":"stream","name":"stdout","text":["Cloning into 'yolov5'...\n","remote: Enumerating objects: 16403, done.\u001b[K\n","remote: Counting objects: 100% (297/297), done.\u001b[K\n","remote: Compressing objects: 100% (220/220), done.\u001b[K\n","remote: Total 16403 (delta 154), reused 162 (delta 77), pack-reused 16106\u001b[K\n","Receiving objects: 100% (16403/16403), 15.15 MiB | 15.99 MiB/s, done.\n","Resolving deltas: 100% (11187/11187), done.\n"]}]},{"cell_type":"code","source":["%cd yolov5\n","!pip install -r requirements.txt # install dependencies"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":1000},"id":"ayhfVEg7EniC","executionInfo":{"status":"ok","timestamp":1706683038834,"user_tz":-540,"elapsed":9348,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"62787129-8e64-4e38-88db-8fb0a8ab339e"},"execution_count":3,"outputs":[{"output_type":"stream","name":"stdout","text":["/content/yolov5\n","Collecting gitpython>=3.1.30 (from -r requirements.txt (line 5))\n"," Downloading GitPython-3.1.41-py3-none-any.whl (196 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m196.4/196.4 kB\u001b[0m \u001b[31m4.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: matplotlib>=3.3 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 6)) (3.7.1)\n","Requirement already satisfied: numpy>=1.23.5 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 7)) (1.23.5)\n","Requirement already satisfied: opencv-python>=4.1.1 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 8)) (4.8.0.76)\n","Collecting Pillow>=10.0.1 (from -r requirements.txt (line 9))\n"," Downloading pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl (4.5 MB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m4.5/4.5 MB\u001b[0m \u001b[31m86.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: psutil in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 10)) (5.9.5)\n","Requirement already satisfied: PyYAML>=5.3.1 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 11)) (6.0.1)\n","Requirement already satisfied: requests>=2.23.0 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 12)) (2.31.0)\n","Requirement already satisfied: scipy>=1.4.1 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 13)) (1.11.4)\n","Collecting thop>=0.1.1 (from -r requirements.txt (line 14))\n"," Downloading thop-0.1.1.post2209072238-py3-none-any.whl (15 kB)\n","Requirement already satisfied: torch>=1.8.0 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 15)) (2.1.0+cu121)\n","Requirement already satisfied: torchvision>=0.9.0 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 16)) (0.16.0+cu121)\n","Requirement already satisfied: tqdm>=4.64.0 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 17)) (4.66.1)\n","Collecting ultralytics>=8.0.232 (from -r requirements.txt (line 18))\n"," Downloading ultralytics-8.1.8-py3-none-any.whl (709 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m709.4/709.4 kB\u001b[0m \u001b[31m64.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: pandas>=1.1.4 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 27)) (1.5.3)\n","Requirement already satisfied: seaborn>=0.11.0 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 28)) (0.13.1)\n","Requirement already satisfied: setuptools>=65.5.1 in /usr/local/lib/python3.10/dist-packages (from -r requirements.txt (line 42)) (67.7.2)\n","Collecting gitdb<5,>=4.0.1 (from gitpython>=3.1.30->-r requirements.txt (line 5))\n"," Downloading gitdb-4.0.11-py3-none-any.whl (62 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m62.7/62.7 kB\u001b[0m \u001b[31m8.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (1.2.0)\n","Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (0.12.1)\n","Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (4.47.2)\n","Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (1.4.5)\n","Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (23.2)\n","Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (3.1.1)\n","Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (2.8.2)\n","Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (3.3.2)\n","Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (3.6)\n","Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (2.0.7)\n","Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (2023.11.17)\n","Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (3.13.1)\n","Requirement already satisfied: typing-extensions in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (4.5.0)\n","Requirement already satisfied: sympy in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (1.12)\n","Requirement already satisfied: networkx in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (3.2.1)\n","Requirement already satisfied: jinja2 in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (3.1.3)\n","Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (2023.6.0)\n","Requirement already satisfied: triton==2.1.0 in /usr/local/lib/python3.10/dist-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (2.1.0)\n","Requirement already satisfied: py-cpuinfo in /usr/local/lib/python3.10/dist-packages (from ultralytics>=8.0.232->-r requirements.txt (line 18)) (9.0.0)\n","Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas>=1.1.4->-r requirements.txt (line 27)) (2023.3.post1)\n","Collecting smmap<6,>=3.0.1 (from gitdb<5,>=4.0.1->gitpython>=3.1.30->-r requirements.txt (line 5))\n"," Downloading smmap-5.0.1-py3-none-any.whl (24 kB)\n","Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib>=3.3->-r requirements.txt (line 6)) (1.16.0)\n","Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.10/dist-packages (from jinja2->torch>=1.8.0->-r requirements.txt (line 15)) (2.1.4)\n","Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.10/dist-packages (from sympy->torch>=1.8.0->-r requirements.txt (line 15)) (1.3.0)\n","Installing collected packages: smmap, Pillow, gitdb, thop, gitpython, ultralytics\n"," Attempting uninstall: Pillow\n"," Found existing installation: Pillow 9.4.0\n"," Uninstalling Pillow-9.4.0:\n"," Successfully uninstalled Pillow-9.4.0\n","\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n","imageio 2.31.6 requires pillow<10.1.0,>=8.3.2, but you have pillow 10.2.0 which is incompatible.\u001b[0m\u001b[31m\n","\u001b[0mSuccessfully installed Pillow-10.2.0 gitdb-4.0.11 gitpython-3.1.41 smmap-5.0.1 thop-0.1.1.post2209072238 ultralytics-8.1.8\n"]},{"output_type":"display_data","data":{"application/vnd.colab-display-data+json":{"pip_warning":{"packages":["PIL"]}}},"metadata":{}}]},{"cell_type":"code","source":["!pip install roboflow\n","\n","from roboflow import Roboflow\n","rf = Roboflow(api_key=\"ScrNlmSgFQq1hQrLe8G6\")\n","project = rf.workspace(\"pedestrianobstacle\").project(\"pedestrianobstacledetection\")\n","dataset = project.version(1).download(\"yolov5\")\n"],"metadata":{"id":"JlGD_35DE1kK","colab":{"base_uri":"https://localhost:8080/","height":1000},"executionInfo":{"status":"ok","timestamp":1706683101644,"user_tz":-540,"elapsed":59915,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"ea20eff9-5522-4a1c-a89e-458d34ecd2bf"},"execution_count":4,"outputs":[{"output_type":"stream","name":"stdout","text":["Collecting roboflow\n"," Downloading roboflow-1.1.17-py3-none-any.whl (70 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m70.0/70.0 kB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hCollecting certifi==2023.7.22 (from roboflow)\n"," Downloading certifi-2023.7.22-py3-none-any.whl (158 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m158.3/158.3 kB\u001b[0m \u001b[31m8.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hCollecting chardet==4.0.0 (from roboflow)\n"," Downloading chardet-4.0.0-py2.py3-none-any.whl (178 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m178.7/178.7 kB\u001b[0m \u001b[31m24.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hCollecting cycler==0.10.0 (from roboflow)\n"," Downloading cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)\n","Collecting idna==2.10 (from roboflow)\n"," Downloading idna-2.10-py2.py3-none-any.whl (58 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.8/58.8 kB\u001b[0m \u001b[31m8.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.10/dist-packages (from roboflow) (1.4.5)\n","Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (from roboflow) (3.7.1)\n","Requirement already satisfied: numpy>=1.18.5 in /usr/local/lib/python3.10/dist-packages (from roboflow) (1.23.5)\n","Collecting opencv-python-headless==4.8.0.74 (from roboflow)\n"," Downloading opencv_python_headless-4.8.0.74-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (49.1 MB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m49.1/49.1 MB\u001b[0m \u001b[31m12.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: Pillow>=7.1.2 in /usr/local/lib/python3.10/dist-packages (from roboflow) (10.2.0)\n","Requirement already satisfied: python-dateutil in /usr/local/lib/python3.10/dist-packages (from roboflow) (2.8.2)\n","Collecting python-dotenv (from roboflow)\n"," Downloading python_dotenv-1.0.1-py3-none-any.whl (19 kB)\n","Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from roboflow) (2.31.0)\n","Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from roboflow) (1.16.0)\n","Collecting supervision (from roboflow)\n"," Downloading supervision-0.18.0-py3-none-any.whl (86 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m86.7/86.7 kB\u001b[0m \u001b[31m12.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hRequirement already satisfied: urllib3>=1.26.6 in /usr/local/lib/python3.10/dist-packages (from roboflow) (2.0.7)\n","Requirement already satisfied: tqdm>=4.41.0 in /usr/local/lib/python3.10/dist-packages (from roboflow) (4.66.1)\n","Requirement already satisfied: PyYAML>=5.3.1 in /usr/local/lib/python3.10/dist-packages (from roboflow) (6.0.1)\n","Collecting requests-toolbelt (from roboflow)\n"," Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl (54 kB)\n","\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.5/54.5 kB\u001b[0m \u001b[31m8.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n","\u001b[?25hCollecting python-magic (from roboflow)\n"," Downloading python_magic-0.4.27-py2.py3-none-any.whl (13 kB)\n","Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->roboflow) (1.2.0)\n","Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->roboflow) (4.47.2)\n","Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->roboflow) (23.2)\n","Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->roboflow) (3.1.1)\n","Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->roboflow) (3.3.2)\n","Requirement already satisfied: defusedxml<0.8.0,>=0.7.1 in /usr/local/lib/python3.10/dist-packages (from supervision->roboflow) (0.7.1)\n","Requirement already satisfied: scipy<2.0.0,>=1.10.0 in /usr/local/lib/python3.10/dist-packages (from supervision->roboflow) (1.11.4)\n","Installing collected packages: python-magic, python-dotenv, opencv-python-headless, idna, cycler, chardet, certifi, supervision, requests-toolbelt, roboflow\n"," Attempting uninstall: opencv-python-headless\n"," Found existing installation: opencv-python-headless 4.9.0.80\n"," Uninstalling opencv-python-headless-4.9.0.80:\n"," Successfully uninstalled opencv-python-headless-4.9.0.80\n"," Attempting uninstall: idna\n"," Found existing installation: idna 3.6\n"," Uninstalling idna-3.6:\n"," Successfully uninstalled idna-3.6\n"," Attempting uninstall: cycler\n"," Found existing installation: cycler 0.12.1\n"," Uninstalling cycler-0.12.1:\n"," Successfully uninstalled cycler-0.12.1\n"," Attempting uninstall: chardet\n"," Found existing installation: chardet 5.2.0\n"," Uninstalling chardet-5.2.0:\n"," Successfully uninstalled chardet-5.2.0\n"," Attempting uninstall: certifi\n"," Found existing installation: certifi 2023.11.17\n"," Uninstalling certifi-2023.11.17:\n"," Successfully uninstalled certifi-2023.11.17\n","\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n","lida 0.0.10 requires fastapi, which is not installed.\n","lida 0.0.10 requires kaleido, which is not installed.\n","lida 0.0.10 requires python-multipart, which is not installed.\n","lida 0.0.10 requires uvicorn, which is not installed.\u001b[0m\u001b[31m\n","\u001b[0mSuccessfully installed certifi-2023.7.22 chardet-4.0.0 cycler-0.10.0 idna-2.10 opencv-python-headless-4.8.0.74 python-dotenv-1.0.1 python-magic-0.4.27 requests-toolbelt-1.0.0 roboflow-1.1.17 supervision-0.18.0\n"]},{"output_type":"display_data","data":{"application/vnd.colab-display-data+json":{"pip_warning":{"packages":["certifi","cycler"]}}},"metadata":{}},{"output_type":"stream","name":"stdout","text":["loading Roboflow workspace...\n","loading Roboflow project...\n"]},{"output_type":"stream","name":"stderr","text":["Downloading Dataset Version Zip in PedestrianObstacleDetection-1 to yolov5pytorch:: 100%|██████████| 704267/704267 [00:37<00:00, 18567.50it/s]"]},{"output_type":"stream","name":"stdout","text":["\n"]},{"output_type":"stream","name":"stderr","text":["\n","Extracting Dataset Version Zip to PedestrianObstacleDetection-1 in yolov5pytorch:: 100%|██████████| 15884/15884 [00:03<00:00, 4354.64it/s]\n"]}]},{"cell_type":"code","source":["from glob import glob"],"metadata":{"id":"7xcCDdg9PIJN","executionInfo":{"status":"ok","timestamp":1706683123693,"user_tz":-540,"elapsed":514,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}}},"execution_count":5,"outputs":[]},{"cell_type":"code","source":["img_list = glob('/content/yolov5/PedestrianObstacleDetection-1/train/images/*.jpg') # 트레인 이미지 경로\n","val_img_list = glob('/content/yolov5/PedestrianObstacleDetection-1/test/images/*.jpg') # 테스트 이미지 경로"],"metadata":{"id":"8TTJR2a6PcEU","executionInfo":{"status":"ok","timestamp":1706683181395,"user_tz":-540,"elapsed":10,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}}},"execution_count":6,"outputs":[]},{"cell_type":"code","source":["with open('/content/yolov5/train.txt', 'w') as f:\n"," f.write('\\n'.join(img_list) + '\\n')\n","\n","\n","with open('/content/yolov5/test.txt', 'w') as f:\n"," f.write('\\n'.join(val_img_list) + '\\n')"],"metadata":{"id":"Z53TP1X4PqMz","executionInfo":{"status":"ok","timestamp":1706683243518,"user_tz":-540,"elapsed":6,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}}},"execution_count":8,"outputs":[]},{"cell_type":"code","source":["!python train.py --img 416 --batch 16 --epochs 50 --data /content/yolov5/PedestrianObstacleDetection-1/data.yaml --weights yolov5x.pt --name result_jetbot --cfg ./models/yolov5x.yaml"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"jCKbKgeNP15y","executionInfo":{"status":"ok","timestamp":1706698614319,"user_tz":-540,"elapsed":15158357,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"d88b6382-2958-45dd-e296-4e7e3aad0522"},"execution_count":10,"outputs":[{"output_type":"stream","name":"stdout","text":["2024-01-31 06:44:21.865733: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n","2024-01-31 06:44:21.865781: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n","2024-01-31 06:44:21.867036: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n","\u001b[34m\u001b[1mtrain: \u001b[0mweights=yolov5x.pt, cfg=./models/yolov5x.yaml, data=/content/yolov5/PedestrianObstacleDetection-1/data.yaml, hyp=data/hyps/hyp.scratch-low.yaml, epochs=50, batch_size=16, imgsz=416, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, noplots=False, evolve=None, evolve_population=data/hyps, resume_evolve=None, bucket=, cache=None, image_weights=False, device=, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=8, project=runs/train, name=result_jetbot, exist_ok=False, quad=False, cos_lr=False, label_smoothing=0.0, patience=100, freeze=[0], save_period=-1, seed=0, local_rank=-1, entity=None, upload_dataset=False, bbox_interval=-1, artifact_alias=latest, ndjson_console=False, ndjson_file=False\n","\u001b[34m\u001b[1mgithub: \u001b[0mup to date with https://github.com/ultralytics/yolov5 ✅\n","YOLOv5 🚀 v7.0-282-g9cdbd1de Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n","\n","\u001b[34m\u001b[1mhyperparameters: \u001b[0mlr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0\n","\u001b[34m\u001b[1mComet: \u001b[0mrun 'pip install comet_ml' to automatically track and visualize YOLOv5 🚀 runs in Comet\n","\u001b[34m\u001b[1mTensorBoard: \u001b[0mStart with 'tensorboard --logdir runs/train', view at http://localhost:6006/\n","Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf...\n","100% 755k/755k [00:00<00:00, 123MB/s]\n","Downloading https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5x.pt to yolov5x.pt...\n","100% 166M/166M [00:00<00:00, 219MB/s]\n","\n","Overriding model.yaml nc=80 with nc=22\n","\n"," from n params module arguments \n"," 0 -1 1 8800 models.common.Conv [3, 80, 6, 2, 2] \n"," 1 -1 1 115520 models.common.Conv [80, 160, 3, 2] \n"," 2 -1 4 309120 models.common.C3 [160, 160, 4] \n"," 3 -1 1 461440 models.common.Conv [160, 320, 3, 2] \n"," 4 -1 8 2259200 models.common.C3 [320, 320, 8] \n"," 5 -1 1 1844480 models.common.Conv [320, 640, 3, 2] \n"," 6 -1 12 13125120 models.common.C3 [640, 640, 12] \n"," 7 -1 1 7375360 models.common.Conv [640, 1280, 3, 2] \n"," 8 -1 4 19676160 models.common.C3 [1280, 1280, 4] \n"," 9 -1 1 4099840 models.common.SPPF [1280, 1280, 5] \n"," 10 -1 1 820480 models.common.Conv [1280, 640, 1, 1] \n"," 11 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] \n"," 12 [-1, 6] 1 0 models.common.Concat [1] \n"," 13 -1 4 5332480 models.common.C3 [1280, 640, 4, False] \n"," 14 -1 1 205440 models.common.Conv [640, 320, 1, 1] \n"," 15 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest'] \n"," 16 [-1, 4] 1 0 models.common.Concat [1] \n"," 17 -1 4 1335040 models.common.C3 [640, 320, 4, False] \n"," 18 -1 1 922240 models.common.Conv [320, 320, 3, 2] \n"," 19 [-1, 14] 1 0 models.common.Concat [1] \n"," 20 -1 4 4922880 models.common.C3 [640, 640, 4, False] \n"," 21 -1 1 3687680 models.common.Conv [640, 640, 3, 2] \n"," 22 [-1, 10] 1 0 models.common.Concat [1] \n"," 23 -1 4 19676160 models.common.C3 [1280, 1280, 4, False] \n"," 24 [17, 20, 23] 1 181683 models.yolo.Detect [22, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [320, 640, 1280]]\n","YOLOv5x summary: 445 layers, 86359123 parameters, 86359123 gradients, 205.1 GFLOPs\n","\n","Transferred 738/745 items from yolov5x.pt\n","\u001b[34m\u001b[1mAMP: \u001b[0mchecks passed ✅\n","\u001b[34m\u001b[1moptimizer:\u001b[0m SGD(lr=0.01) with parameter groups 123 weight(decay=0.0), 126 weight(decay=0.0005), 126 bias\n","\u001b[34m\u001b[1malbumentations: \u001b[0mBlur(p=0.01, blur_limit=(3, 7)), MedianBlur(p=0.01, blur_limit=(3, 7)), ToGray(p=0.01), CLAHE(p=0.01, clip_limit=(1, 4.0), tile_grid_size=(8, 8))\n","\u001b[34m\u001b[1mtrain: \u001b[0mScanning /content/yolov5/train... 6947 images, 8 backgrounds, 0 corrupt: 100% 6947/6947 [00:03<00:00, 1783.59it/s]\n","\u001b[34m\u001b[1mtrain: \u001b[0mNew cache created: /content/yolov5/train.cache\n","\u001b[34m\u001b[1mval: \u001b[0mScanning /content/yolov5/PedestrianObstacleDetection-1/valid/labels... 650 images, 0 backgrounds, 0 corrupt: 100% 650/650 [00:01<00:00, 400.30it/s]\n","\u001b[34m\u001b[1mval: \u001b[0mNew cache created: /content/yolov5/PedestrianObstacleDetection-1/valid/labels.cache\n","\n","\u001b[34m\u001b[1mAutoAnchor: \u001b[0m3.98 anchors/target, 0.993 Best Possible Recall (BPR). Current anchors are a good fit to dataset ✅\n","Plotting labels to runs/train/result_jetbot/labels.jpg... \n","Image sizes 416 train, 416 val\n","Using 2 dataloader workers\n","Logging results to \u001b[1mruns/train/result_jetbot\u001b[0m\n","Starting training for 50 epochs...\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 0/49 7.04G 0.06824 0.02331 0.0614 8 416: 100% 435/435 [04:49<00:00, 1.50it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.39it/s]\n"," all 650 992 0.615 0.338 0.348 0.181\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 1/49 7.94G 0.05019 0.01804 0.03145 7 416: 100% 435/435 [04:45<00:00, 1.52it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.54it/s]\n"," all 650 992 0.563 0.595 0.61 0.313\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 2/49 7.94G 0.04766 0.01643 0.02103 9 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.45it/s]\n"," all 650 992 0.552 0.633 0.625 0.31\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 3/49 7.94G 0.04502 0.01698 0.01966 5 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.618 0.657 0.672 0.385\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 4/49 7.94G 0.04285 0.01719 0.01778 14 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.38it/s]\n"," all 650 992 0.627 0.699 0.695 0.413\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 5/49 7.94G 0.04114 0.01644 0.01515 9 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.702 0.692 0.699 0.408\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 6/49 7.94G 0.04006 0.01606 0.01415 13 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.33it/s]\n"," all 650 992 0.588 0.697 0.707 0.421\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 7/49 7.94G 0.0387 0.01577 0.01294 10 416: 100% 435/435 [04:41<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.646 0.737 0.718 0.437\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 8/49 7.94G 0.03741 0.01568 0.01231 12 416: 100% 435/435 [04:39<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.48it/s]\n"," all 650 992 0.745 0.76 0.77 0.475\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 9/49 7.94G 0.03635 0.01522 0.01148 10 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.50it/s]\n"," all 650 992 0.745 0.777 0.799 0.491\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 10/49 7.94G 0.03527 0.01482 0.01092 10 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.725 0.771 0.771 0.488\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 11/49 7.94G 0.03503 0.01456 0.009927 7 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.757 0.779 0.807 0.498\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 12/49 7.94G 0.03386 0.01426 0.009769 7 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.728 0.785 0.796 0.492\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 13/49 7.94G 0.03322 0.01399 0.008836 6 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.50it/s]\n"," all 650 992 0.711 0.81 0.808 0.524\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 14/49 7.94G 0.03256 0.01384 0.008151 10 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:16<00:00, 1.27it/s]\n"," all 650 992 0.772 0.803 0.821 0.517\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 15/49 7.94G 0.03159 0.01346 0.008174 12 416: 100% 435/435 [04:39<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.49it/s]\n"," all 650 992 0.753 0.833 0.826 0.54\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 16/49 7.94G 0.0311 0.01331 0.007897 9 416: 100% 435/435 [04:41<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.35it/s]\n"," all 650 992 0.749 0.854 0.84 0.562\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 17/49 7.94G 0.03076 0.01306 0.007258 6 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.40it/s]\n"," all 650 992 0.762 0.834 0.809 0.531\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 18/49 7.94G 0.02984 0.01271 0.006808 11 416: 100% 435/435 [04:55<00:00, 1.47it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.48it/s]\n"," all 650 992 0.773 0.834 0.835 0.55\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 19/49 7.94G 0.02901 0.0126 0.006493 7 416: 100% 435/435 [04:50<00:00, 1.50it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.784 0.821 0.83 0.568\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 20/49 7.94G 0.02846 0.01245 0.006481 5 416: 100% 435/435 [04:49<00:00, 1.50it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.52it/s]\n"," all 650 992 0.782 0.826 0.828 0.559\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 21/49 7.94G 0.0283 0.01239 0.006301 13 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.46it/s]\n"," all 650 992 0.775 0.829 0.834 0.567\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 22/49 7.94G 0.02794 0.01208 0.005892 11 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.32it/s]\n"," all 650 992 0.791 0.838 0.825 0.561\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 23/49 7.94G 0.02718 0.01198 0.005579 8 416: 100% 435/435 [04:41<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.50it/s]\n"," all 650 992 0.796 0.854 0.838 0.571\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 24/49 7.94G 0.02648 0.01173 0.005379 10 416: 100% 435/435 [04:41<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.47it/s]\n"," all 650 992 0.801 0.843 0.839 0.588\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 25/49 7.94G 0.02647 0.01148 0.005111 6 416: 100% 435/435 [04:45<00:00, 1.52it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.801 0.845 0.839 0.584\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 26/49 7.94G 0.02564 0.01145 0.005002 5 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.792 0.847 0.838 0.587\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 27/49 7.94G 0.02529 0.01118 0.004875 12 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.809 0.833 0.838 0.587\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 28/49 7.94G 0.02495 0.01111 0.004655 6 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.796 0.842 0.842 0.598\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 29/49 7.94G 0.02422 0.01074 0.004205 9 416: 100% 435/435 [04:35<00:00, 1.58it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.47it/s]\n"," all 650 992 0.805 0.82 0.843 0.592\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 30/49 7.94G 0.02365 0.01071 0.0041 16 416: 100% 435/435 [04:34<00:00, 1.59it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.52it/s]\n"," all 650 992 0.782 0.853 0.84 0.597\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 31/49 7.94G 0.02325 0.01048 0.004035 4 416: 100% 435/435 [04:34<00:00, 1.59it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.34it/s]\n"," all 650 992 0.796 0.851 0.838 0.588\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 32/49 7.94G 0.02307 0.01036 0.003888 12 416: 100% 435/435 [04:39<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.52it/s]\n"," all 650 992 0.782 0.835 0.846 0.608\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 33/49 7.94G 0.02227 0.00989 0.003709 5 416: 100% 435/435 [04:39<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.55it/s]\n"," all 650 992 0.774 0.864 0.84 0.605\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 34/49 7.94G 0.02208 0.00998 0.003492 7 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.52it/s]\n"," all 650 992 0.782 0.864 0.837 0.6\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 35/49 7.94G 0.02145 0.009874 0.003341 7 416: 100% 435/435 [04:40<00:00, 1.55it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.806 0.835 0.844 0.602\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 36/49 7.94G 0.02103 0.009554 0.003448 9 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.50it/s]\n"," all 650 992 0.803 0.847 0.846 0.606\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 37/49 7.94G 0.02048 0.009486 0.003152 8 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.784 0.867 0.843 0.599\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 38/49 7.94G 0.0202 0.009362 0.003061 8 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.54it/s]\n"," all 650 992 0.798 0.85 0.84 0.6\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 39/49 7.94G 0.01993 0.009138 0.002942 9 416: 100% 435/435 [04:41<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.51it/s]\n"," all 650 992 0.799 0.837 0.845 0.608\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 40/49 7.94G 0.01938 0.009116 0.00281 7 416: 100% 435/435 [04:35<00:00, 1.58it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.52it/s]\n"," all 650 992 0.793 0.844 0.838 0.606\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 41/49 7.94G 0.01886 0.009073 0.002685 9 416: 100% 435/435 [04:38<00:00, 1.56it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.55it/s]\n"," all 650 992 0.799 0.836 0.838 0.604\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 42/49 7.94G 0.01844 0.00864 0.002538 12 416: 100% 435/435 [04:36<00:00, 1.58it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:14<00:00, 1.49it/s]\n"," all 650 992 0.804 0.836 0.84 0.606\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 43/49 7.94G 0.018 0.008675 0.002357 4 416: 100% 435/435 [04:37<00:00, 1.57it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.56it/s]\n"," all 650 992 0.794 0.845 0.838 0.608\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 44/49 7.94G 0.01788 0.00845 0.002339 9 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.53it/s]\n"," all 650 992 0.823 0.799 0.836 0.606\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 45/49 7.94G 0.01735 0.008235 0.002327 5 416: 100% 435/435 [04:32<00:00, 1.60it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.55it/s]\n"," all 650 992 0.794 0.841 0.833 0.603\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 46/49 7.94G 0.01714 0.008277 0.00223 10 416: 100% 435/435 [04:32<00:00, 1.60it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.60it/s]\n"," all 650 992 0.786 0.844 0.84 0.609\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 47/49 7.94G 0.01653 0.008295 0.002178 7 416: 100% 435/435 [04:30<00:00, 1.61it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.57it/s]\n"," all 650 992 0.837 0.786 0.841 0.613\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 48/49 7.94G 0.01617 0.008067 0.002103 10 416: 100% 435/435 [04:33<00:00, 1.59it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.38it/s]\n"," all 650 992 0.829 0.798 0.845 0.616\n","\n"," Epoch GPU_mem box_loss obj_loss cls_loss Instances Size\n"," 49/49 7.94G 0.01572 0.007886 0.001944 7 416: 100% 435/435 [04:42<00:00, 1.54it/s]\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:13<00:00, 1.59it/s]\n"," all 650 992 0.791 0.843 0.84 0.618\n","\n","50 epochs completed in 4.191 hours.\n","Optimizer stripped from runs/train/result_jetbot/weights/last.pt, 173.3MB\n","Optimizer stripped from runs/train/result_jetbot/weights/best.pt, 173.3MB\n","\n","Validating runs/train/result_jetbot/weights/best.pt...\n","Fusing layers... \n","YOLOv5x summary: 322 layers, 86314723 parameters, 0 gradients, 204.2 GFLOPs\n"," Class Images Instances P R mAP50 mAP50-95: 100% 21/21 [00:15<00:00, 1.38it/s]\n"," all 650 992 0.791 0.843 0.84 0.618\n"," bad road 650 59 0.811 0.898 0.884 0.589\n"," car 650 104 0.859 0.875 0.905 0.698\n"," chair 650 24 0.965 0.833 0.891 0.696\n"," door 650 9 0.911 1 0.995 0.961\n"," drain 650 29 1 0.982 0.995 0.687\n"," fence 650 21 0.836 0.952 0.957 0.827\n"," garbage bin 650 11 0.789 1 0.995 0.833\n"," gate barrier 650 16 1 0.916 0.995 0.702\n"," left turn 650 19 0.248 0.416 0.336 0.225\n"," motorcycle 650 75 0.627 0.64 0.643 0.394\n"," obstacle 650 101 0.854 0.754 0.791 0.529\n"," pedestrian 650 13 0.627 0.846 0.743 0.499\n"," plant pot 650 43 0.941 0.953 0.961 0.595\n"," pole 650 66 0.672 0.682 0.701 0.472\n"," pothole 650 68 0.977 0.956 0.968 0.608\n"," puddle 650 59 0.696 0.78 0.796 0.508\n"," right turn 650 27 0.537 0.644 0.553 0.313\n"," roadblock 650 27 0.625 0.815 0.77 0.519\n"," stair 650 35 0.976 1 0.995 0.885\n"," street vendor 650 25 0.749 0.8 0.801 0.75\n"," tree 650 57 0.881 0.877 0.899 0.67\n"," zebra cross 650 104 0.823 0.923 0.909 0.63\n","Results saved to \u001b[1mruns/train/result_jetbot\u001b[0m\n"]}]},{"cell_type":"code","source":["!python /content/yolov5/detect.py --weights /content/yolov5/runs/train/result_jetbot/weights/best.pt --source /content/drive/MyDrive/vdo.mp4 # video"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"VSy0TXSTQg5i","executionInfo":{"status":"ok","timestamp":1706700538590,"user_tz":-540,"elapsed":38278,"user":{"displayName":"김호준(학부생-소프트웨어전공)","userId":"06251474112980864102"}},"outputId":"753051a1-db22-439f-cfb7-98529845ddb2"},"execution_count":21,"outputs":[{"output_type":"stream","name":"stdout","text":["\u001b[34m\u001b[1mdetect: \u001b[0mweights=['/content/yolov5/runs/train/result_jetbot/weights/best.pt'], source=/content/drive/MyDrive/vdo.mp4, data=data/coco128.yaml, imgsz=[640, 640], conf_thres=0.25, iou_thres=0.45, max_det=1000, device=, view_img=False, save_txt=False, save_csv=False, save_conf=False, save_crop=False, nosave=False, classes=None, agnostic_nms=False, augment=False, visualize=False, update=False, project=runs/detect, name=exp, exist_ok=False, line_thickness=3, hide_labels=False, hide_conf=False, half=False, dnn=False, vid_stride=1\n","YOLOv5 🚀 v7.0-282-g9cdbd1de Python-3.10.12 torch-2.1.0+cu121 CUDA:0 (Tesla T4, 15102MiB)\n","\n","Fusing layers... \n","YOLOv5x summary: 322 layers, 86314723 parameters, 0 gradients, 204.2 GFLOPs\n","video 1/1 (1/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 65.7ms\n","video 1/1 (2/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 41.0ms\n","video 1/1 (3/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 41.1ms\n","video 1/1 (4/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 34.7ms\n","video 1/1 (5/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 31.7ms\n","video 1/1 (6/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 31.7ms\n","video 1/1 (7/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 31.7ms\n","video 1/1 (8/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 32.7ms\n","video 1/1 (9/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 32.4ms\n","video 1/1 (10/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.7ms\n","video 1/1 (11/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (12/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (13/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (14/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (15/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 31.2ms\n","video 1/1 (16/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 29.8ms\n","video 1/1 (17/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 29.5ms\n","video 1/1 (18/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 28.7ms\n","video 1/1 (19/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (20/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (21/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (22/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 29.5ms\n","video 1/1 (23/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (24/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (25/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (26/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (27/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (28/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (29/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (30/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (31/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (32/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (33/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (34/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (35/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (36/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (37/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.2ms\n","video 1/1 (38/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (39/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (40/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (41/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (42/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (43/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (44/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (45/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (46/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (47/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (48/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (49/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (50/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (51/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (52/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (53/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (54/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (55/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.6ms\n","video 1/1 (56/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (57/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (58/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (59/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (60/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.6ms\n","video 1/1 (61/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (62/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (63/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (64/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (65/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (66/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (67/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (68/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (69/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (70/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (71/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (72/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (73/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.9ms\n","video 1/1 (74/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (75/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (76/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (77/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (78/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (79/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (80/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (81/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.1ms\n","video 1/1 (82/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.6ms\n","video 1/1 (83/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.1ms\n","video 1/1 (84/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (85/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.3ms\n","video 1/1 (86/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (87/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 31.2ms\n","video 1/1 (88/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.0ms\n","video 1/1 (89/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.3ms\n","video 1/1 (90/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.0ms\n","video 1/1 (91/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.9ms\n","video 1/1 (92/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.4ms\n","video 1/1 (93/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.1ms\n","video 1/1 (94/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.5ms\n","video 1/1 (95/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.9ms\n","video 1/1 (96/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.8ms\n","video 1/1 (97/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.7ms\n","video 1/1 (98/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.0ms\n","video 1/1 (99/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.8ms\n","video 1/1 (100/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.9ms\n","video 1/1 (101/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.1ms\n","video 1/1 (102/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.8ms\n","video 1/1 (103/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.3ms\n","video 1/1 (104/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.3ms\n","video 1/1 (105/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 30.7ms\n","video 1/1 (106/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 obstacle, 29.6ms\n","video 1/1 (107/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.8ms\n","video 1/1 (108/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 stair, 29.8ms\n","video 1/1 (109/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (110/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (111/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (112/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (113/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 obstacle, 30.1ms\n","video 1/1 (114/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (115/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 obstacle, 30.8ms\n","video 1/1 (116/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (117/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (118/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (119/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (120/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (121/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (122/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (123/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (124/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (125/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (126/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (127/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (128/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (129/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (130/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (131/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (132/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (133/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (134/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (135/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (136/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (137/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (138/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (139/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (140/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (141/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (142/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.8ms\n","video 1/1 (143/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (144/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (145/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (146/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.5ms\n","video 1/1 (147/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (148/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (149/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (150/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (151/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (152/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (153/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (154/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (155/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (156/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (157/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (158/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (159/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (160/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (161/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (162/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (163/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (164/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (165/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (166/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (167/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (168/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (169/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (170/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (171/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (172/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (173/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (174/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 32.5ms\n","video 1/1 (175/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 33.8ms\n","video 1/1 (176/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (177/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (178/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (179/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 28.6ms\n","video 1/1 (180/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 27.7ms\n","video 1/1 (181/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.1ms\n","video 1/1 (182/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (183/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (184/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (185/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (186/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (187/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (188/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (189/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (190/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (191/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (192/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (193/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (194/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (195/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (196/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (197/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (198/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (199/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (200/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.1ms\n","video 1/1 (201/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 pothole, 28.8ms\n","video 1/1 (202/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (203/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.1ms\n","video 1/1 (204/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (205/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (206/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (207/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.3ms\n","video 1/1 (208/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 1 door, 27.8ms\n","video 1/1 (209/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 28.4ms\n","video 1/1 (210/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (211/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.0ms\n","video 1/1 (212/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (213/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.5ms\n","video 1/1 (214/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 pothole, 28.4ms\n","video 1/1 (215/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.3ms\n","video 1/1 (216/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 pothole, 29.2ms\n","video 1/1 (217/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.5ms\n","video 1/1 (218/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.5ms\n","video 1/1 (219/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.2ms\n","video 1/1 (220/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 29.7ms\n","video 1/1 (221/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 pothole, 28.0ms\n","video 1/1 (222/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 29.0ms\n","video 1/1 (223/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.7ms\n","video 1/1 (224/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 car, 1 door, 1 pothole, 28.7ms\n","video 1/1 (225/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 29.2ms\n","video 1/1 (226/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.6ms\n","video 1/1 (227/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 28.0ms\n","video 1/1 (228/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 29.0ms\n","video 1/1 (229/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 1 pothole, 29.0ms\n","video 1/1 (230/595) /content/drive/MyDrive/vdo.mp4: 640x384 2 doors, 28.3ms\n","video 1/1 (231/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 28.0ms\n","video 1/1 (232/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 28.1ms\n","video 1/1 (233/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 27.8ms\n","video 1/1 (234/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 27.7ms\n","video 1/1 (235/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 27.8ms\n","video 1/1 (236/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.4ms\n","video 1/1 (237/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.1ms\n","video 1/1 (238/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.9ms\n","video 1/1 (239/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.3ms\n","video 1/1 (240/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.3ms\n","video 1/1 (241/595) /content/drive/MyDrive/vdo.mp4: 640x384 2 doors, 29.5ms\n","video 1/1 (242/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.1ms\n","video 1/1 (243/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 31.0ms\n","video 1/1 (244/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.8ms\n","video 1/1 (245/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 street vendor, 30.2ms\n","video 1/1 (246/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.6ms\n","video 1/1 (247/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 31.2ms\n","video 1/1 (248/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.3ms\n","video 1/1 (249/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 29.8ms\n","video 1/1 (250/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (251/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (252/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (253/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (254/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (255/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (256/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (257/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 door, 30.4ms\n","video 1/1 (258/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.9ms\n","video 1/1 (259/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (260/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (261/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (262/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (263/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (264/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (265/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (266/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (267/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (268/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (269/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.0ms\n","video 1/1 (270/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (271/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (272/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (273/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (274/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (275/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (276/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (277/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (278/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (279/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (280/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (281/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (282/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (283/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 30.2ms\n","video 1/1 (284/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 31.0ms\n","video 1/1 (285/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 30.2ms\n","video 1/1 (286/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 29.9ms\n","video 1/1 (287/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 30.1ms\n","video 1/1 (288/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 30.7ms\n","video 1/1 (289/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 30.2ms\n","video 1/1 (290/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 29.7ms\n","video 1/1 (291/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (292/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (293/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.3ms\n","video 1/1 (294/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (295/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (296/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (297/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (298/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.3ms\n","video 1/1 (299/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (300/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (301/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (302/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (303/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (304/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (305/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (306/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (307/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (308/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (309/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (310/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (311/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (312/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (313/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (314/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.9ms\n","video 1/1 (315/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (316/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (317/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (318/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.5ms\n","video 1/1 (319/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (320/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (321/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (322/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (323/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.0ms\n","video 1/1 (324/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (325/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (326/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (327/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (328/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (329/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (330/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (331/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (332/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (333/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (334/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (335/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (336/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (337/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.6ms\n","video 1/1 (338/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (339/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (340/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (341/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (342/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.3ms\n","video 1/1 (343/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (344/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (345/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (346/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (347/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (348/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.5ms\n","video 1/1 (349/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (350/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (351/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (352/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (353/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (354/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.2ms\n","video 1/1 (355/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (356/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (357/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (358/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (359/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.7ms\n","video 1/1 (360/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.2ms\n","video 1/1 (361/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (362/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (363/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (364/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (365/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.7ms\n","video 1/1 (366/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (367/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (368/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.2ms\n","video 1/1 (369/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (370/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (371/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (372/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (373/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (374/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (375/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (376/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.6ms\n","video 1/1 (377/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (378/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (379/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (380/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (381/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (382/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.7ms\n","video 1/1 (383/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (384/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (385/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (386/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (387/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.0ms\n","video 1/1 (388/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (389/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (390/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (391/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (392/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (393/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.8ms\n","video 1/1 (394/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (395/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (396/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (397/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (398/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (399/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (400/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (401/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (402/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.6ms\n","video 1/1 (403/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (404/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (405/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (406/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (407/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.7ms\n","video 1/1 (408/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (409/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (410/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (411/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (412/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (413/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (414/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (415/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (416/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (417/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.6ms\n","video 1/1 (418/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (419/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (420/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (421/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.1ms\n","video 1/1 (422/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (423/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (424/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (425/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","video 1/1 (426/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.3ms\n","video 1/1 (427/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (428/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (429/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (430/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.8ms\n","video 1/1 (431/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.0ms\n","video 1/1 (432/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.4ms\n","video 1/1 (433/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (434/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (435/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (436/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (437/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.0ms\n","video 1/1 (438/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (439/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (440/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.2ms\n","video 1/1 (441/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.5ms\n","video 1/1 (442/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (443/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (444/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (445/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (446/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (447/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (448/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.5ms\n","video 1/1 (449/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (450/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (451/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (452/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (453/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (454/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (455/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (456/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (457/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (458/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (459/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (460/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (461/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (462/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (463/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.3ms\n","video 1/1 (464/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 36.1ms\n","video 1/1 (465/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (466/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (467/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (468/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (469/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (470/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (471/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (472/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (473/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (474/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (475/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (476/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (477/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (478/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.9ms\n","video 1/1 (479/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 27.8ms\n","video 1/1 (480/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (481/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (482/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (483/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (484/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (485/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (486/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (487/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (488/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (489/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (490/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (491/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (492/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (493/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.5ms\n","video 1/1 (494/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (495/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (496/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (497/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (498/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (499/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (500/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (501/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (502/595) /content/drive/MyDrive/vdo.mp4: 640x384 1 garbage bin, 28.5ms\n","video 1/1 (503/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.3ms\n","video 1/1 (504/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.1ms\n","video 1/1 (505/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (506/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.0ms\n","video 1/1 (507/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 33.3ms\n","video 1/1 (508/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (509/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (510/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.0ms\n","video 1/1 (511/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (512/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (513/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (514/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (515/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (516/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.4ms\n","video 1/1 (517/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (518/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (519/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (520/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (521/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (522/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (523/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (524/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.5ms\n","video 1/1 (525/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (526/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (527/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.1ms\n","video 1/1 (528/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (529/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 32.2ms\n","video 1/1 (530/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (531/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.0ms\n","video 1/1 (532/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.3ms\n","video 1/1 (533/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (534/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (535/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (536/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.9ms\n","video 1/1 (537/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.7ms\n","video 1/1 (538/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.4ms\n","video 1/1 (539/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (540/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (541/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (542/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (543/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (544/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (545/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (546/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (547/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (548/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (549/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.3ms\n","video 1/1 (550/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (551/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (552/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (553/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (554/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.1ms\n","video 1/1 (555/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (556/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (557/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (558/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.6ms\n","video 1/1 (559/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.5ms\n","video 1/1 (560/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.2ms\n","video 1/1 (561/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (562/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.7ms\n","video 1/1 (563/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (564/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.5ms\n","video 1/1 (565/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (566/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (567/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.2ms\n","video 1/1 (568/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.5ms\n","video 1/1 (569/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (570/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.3ms\n","video 1/1 (571/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.7ms\n","video 1/1 (572/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (573/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (574/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.4ms\n","video 1/1 (575/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.5ms\n","video 1/1 (576/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (577/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (578/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.2ms\n","video 1/1 (579/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (580/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.8ms\n","video 1/1 (581/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (582/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (583/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.9ms\n","video 1/1 (584/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.3ms\n","video 1/1 (585/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.1ms\n","video 1/1 (586/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.6ms\n","video 1/1 (587/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.5ms\n","video 1/1 (588/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.3ms\n","video 1/1 (589/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.0ms\n","video 1/1 (590/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 28.9ms\n","video 1/1 (591/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (592/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.2ms\n","video 1/1 (593/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 29.8ms\n","video 1/1 (594/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 30.6ms\n","video 1/1 (595/595) /content/drive/MyDrive/vdo.mp4: 640x384 (no detections), 31.3ms\n","Speed: 0.5ms pre-process, 30.2ms inference, 1.3ms NMS per image at shape (1, 3, 640, 640)\n","Results saved to \u001b[1mruns/detect/exp6\u001b[0m\n"]}]}]}
\ No newline at end of file
diff --git a/ai/depth_estimation_research/.DS_Store b/ai/depth_estimation_research/.DS_Store
new file mode 100644
index 0000000000..5008ddfcf5
Binary files /dev/null and b/ai/depth_estimation_research/.DS_Store differ
diff --git a/ai/depth_estimation_research/Real-time-depth-estimation.pdf b/ai/depth_estimation_research/Real-time-depth-estimation.pdf
new file mode 100644
index 0000000000..d9ecbd4969
Binary files /dev/null and b/ai/depth_estimation_research/Real-time-depth-estimation.pdf differ
diff --git a/backend/capstone2024/.gitignore b/backend/capstone2024/.gitignore
new file mode 100644
index 0000000000..878b3e71f2
--- /dev/null
+++ b/backend/capstone2024/.gitignore
@@ -0,0 +1,38 @@
+HELP.md
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+/src/main/resources/config/application.properties
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
diff --git a/backend/capstone2024/build.gradle b/backend/capstone2024/build.gradle
new file mode 100644
index 0000000000..a2cc7ceeeb
--- /dev/null
+++ b/backend/capstone2024/build.gradle
@@ -0,0 +1,41 @@
+plugins {
+ id 'java'
+ id 'org.springframework.boot' version '3.2.3'
+ id 'io.spring.dependency-management' version '1.1.4'
+}
+
+group = 'com.example'
+version = '0.0.1-SNAPSHOT'
+
+java {
+ sourceCompatibility = '21'
+}
+
+configurations {
+ compileOnly {
+ extendsFrom annotationProcessor
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ compileOnly 'org.projectlombok:lombok'
+ annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
+ annotationProcessor 'org.projectlombok:lombok'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+ implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+ implementation 'mysql:mysql-connector-java:8.0.28'
+ implementation 'com.h2database:h2'
+}
+
+tasks.named('test') {
+ useJUnitPlatform()
+}
+
+bootJar {
+ archiveFileName = 'capstone24.jar'
+}
diff --git a/backend/capstone2024/gradle/wrapper/gradle-wrapper.jar b/backend/capstone2024/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..d64cd49177
Binary files /dev/null and b/backend/capstone2024/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/backend/capstone2024/gradle/wrapper/gradle-wrapper.properties b/backend/capstone2024/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..1af9e0930b
--- /dev/null
+++ b/backend/capstone2024/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/backend/capstone2024/gradlew b/backend/capstone2024/gradlew
new file mode 100644
index 0000000000..1aa94a4269
--- /dev/null
+++ b/backend/capstone2024/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/backend/capstone2024/gradlew.bat b/backend/capstone2024/gradlew.bat
new file mode 100644
index 0000000000..93e3f59f13
--- /dev/null
+++ b/backend/capstone2024/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/backend/capstone2024/settings.gradle b/backend/capstone2024/settings.gradle
new file mode 100644
index 0000000000..79b4187da1
--- /dev/null
+++ b/backend/capstone2024/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'capstone'
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/CapstoneApplication.java b/backend/capstone2024/src/main/java/com/example/capstone/CapstoneApplication.java
new file mode 100644
index 0000000000..ea6d21dc63
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/CapstoneApplication.java
@@ -0,0 +1,14 @@
+package com.example.capstone;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CapstoneApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(CapstoneApplication.class, args);
+ }
+
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/controller/GeoCoding.java b/backend/capstone2024/src/main/java/com/example/capstone/api/controller/GeoCoding.java
new file mode 100644
index 0000000000..aeb32aae58
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/controller/GeoCoding.java
@@ -0,0 +1,105 @@
+package com.example.capstone.api.controller;
+
+import com.example.capstone.api.dto.*;
+import com.example.capstone.api.service.GeoCodingService;
+import com.example.capstone.api.service.PedestrianService;
+import com.example.capstone.api.service.PoiService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+public class GeoCoding {
+
+ private final GeoCodingService geoCodingService;
+ private final PedestrianService pedestrianService;
+ private final PoiService poiService;
+ @GetMapping("/address-to-coord")
+ public Coordinate testGPS(@RequestParam("address") String address){
+ Coordinate coordinate;
+ coordinate = geoCodingService.requestGeoCoding(address).getCoordinateInfo().getCoordinate().get(0);
+ return coordinate;
+ }
+
+ @GetMapping("/find-way")
+ public Properties checkPede(@RequestParam("startLat") String startLat
+ , @RequestParam("startLon") String startLon
+ , @RequestParam(value = "endAddress") String endAddress) throws Exception {
+ System.out.println("startLat = " + startLat);
+ System.out.println("startLon = " + startLon);
+ System.out.println("endAddress = " + endAddress);
+ Properties properties = new Properties();
+ TmapPedestrianResponseDto tmapPedestrianResponseDto = pedestrianService.requestPedestrian(startLat, startLon, endAddress);
+ properties.setTotalDistance(tmapPedestrianResponseDto.getFeatures().getFirst().getProperties().getTotalDistance());
+ properties.setTotalTime(tmapPedestrianResponseDto.getFeatures().getFirst().getProperties().getTotalTime());
+ return properties;
+ }
+
+ @GetMapping("/start-navi")
+ public Properties confirmPede(@RequestParam("startLat") String startLat
+ , @RequestParam("startLon") String startLon
+ , @RequestParam("endAddress") String endAddress
+ ,@RequestParam("uuid") String uuid) throws Exception {
+ System.out.println("startLat = " + startLat);
+ System.out.println("startLon = " + startLon);
+ System.out.println("endAddress = " + endAddress);
+ System.out.println("uuid = " + uuid);
+ TmapPedestrianResponseDto tmapPedestrianResponseDto = pedestrianService.startPedestrianNavi(startLat, startLon, endAddress, uuid);
+ Properties properties = new Properties();
+ properties.setPointIndex(1);
+ properties.setDescription("경로 안내를 시작 합니다."+tmapPedestrianResponseDto.getFeatures().getFirst().getProperties().getDescription());
+ return properties;
+ }
+
+ @GetMapping("/poi")
+ public Poi poiTest(@RequestParam("address") String address){
+ Poi testBody;
+ testBody = poiService.requestPoi(address).getSearchPoiInfo().getPois().getPoi().get(0);
+ return testBody;
+ }
+
+ @GetMapping("/current-location")
+ public DistanceInfo currentLocation(@RequestParam("curLat") String curLat,
+ @RequestParam("curLon") String curLon,
+ @RequestParam("uuid") String uuid,
+ @RequestParam("pointIndex") int pointIndex,
+ @RequestParam("cnt") int cnt,@RequestParam("distance") int distance){
+ System.out.println("-----------------current--------------");
+ System.out.println("curLat = " + curLat);
+ System.out.println("curLon = " + curLon);
+ System.out.println("uuid = " + uuid);
+ System.out.println("pointIndex = " + pointIndex);
+ System.out.println("cnt = " + cnt);
+
+
+ return pedestrianService.currentLocationCheck(curLat, curLon, uuid, pointIndex,cnt,distance);
+ }
+
+ @GetMapping("/direction")
+ public DirectionInfo direction(@RequestParam("curLat") String curLat,
+ @RequestParam("curLon") String curLon,
+ @RequestParam("uuid") String uuid,
+ @RequestParam("pointIndex") int pointIndex,
+ @RequestParam("curDir") String curDir){
+ System.out.println("-----------------direction--------------");
+ System.out.println("curLat = " + curLat);
+ System.out.println("curLon = " + curLon);
+ System.out.println("uuid = " + uuid);
+ System.out.println("pointIndex = " + pointIndex);
+ System.out.println("curDir = " + curDir);
+
+ return pedestrianService.directionCheck(curLat, curLon, uuid, pointIndex,curDir);
+ }
+
+
+ @GetMapping("/cancel-navi")
+ public String cancelNavi(@RequestParam("uuid") String uuid){
+ pedestrianService.cancelNavi(uuid);
+
+ return uuid + " 관련 모든 경로 삭제 완료";
+ }
+
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Coordinate.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Coordinate.java
new file mode 100644
index 0000000000..315238aa09
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Coordinate.java
@@ -0,0 +1,13 @@
+package com.example.capstone.api.dto;
+
+import lombok.Data;
+
+@Data
+public class Coordinate {
+ //위도
+ private String newLat;
+ //경도
+ private String newLon;
+
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/CoordinateInfo.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/CoordinateInfo.java
new file mode 100644
index 0000000000..a6c30e7d56
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/CoordinateInfo.java
@@ -0,0 +1,15 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CoordinateInfo {
+
+ private String totalCount;
+
+ @JsonProperty("coordinate")
+ private List
coordinate;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DirectionInfo.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DirectionInfo.java
new file mode 100644
index 0000000000..440b78cdbe
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DirectionInfo.java
@@ -0,0 +1,8 @@
+package com.example.capstone.api.dto;
+
+import lombok.Data;
+
+@Data
+public class DirectionInfo {
+ private String dirMsg;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceInfo.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceInfo.java
new file mode 100644
index 0000000000..f9ca889287
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceInfo.java
@@ -0,0 +1,22 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class DistanceInfo {
+ @JsonProperty("distance")
+ private String distance;
+
+ private int pointIndex;
+
+ private String description;
+
+ private String lat;
+ private String lon;
+
+ private String dir;
+
+ private int cnt;
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceResponseDTO.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceResponseDTO.java
new file mode 100644
index 0000000000..035bf9033a
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/DistanceResponseDTO.java
@@ -0,0 +1,8 @@
+package com.example.capstone.api.dto;
+
+import lombok.Data;
+
+@Data
+public class DistanceResponseDTO {
+ private DistanceInfo distanceInfo;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Feature.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Feature.java
new file mode 100644
index 0000000000..0607f7671e
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Feature.java
@@ -0,0 +1,24 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class Feature {
+ @JsonProperty("type")
+ private String type;
+
+ /*
+ geometry.coordinate -> 노드별 위도, 경도
+ */
+ @JsonProperty("geometry")
+ private Geometry
+ geometry;
+
+ /*
+ properties.pointIndex -> 목적지까지 순차적인 노드 번호
+ */
+ @JsonProperty("properties")
+ private Properties properties;
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Geometry.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Geometry.java
new file mode 100644
index 0000000000..e2cd827714
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Geometry.java
@@ -0,0 +1,18 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+public class Geometry {
+ @JsonProperty("type")
+ private String type;
+
+ @JsonProperty("coordinates")
+ private Object coordinates;
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Poi.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Poi.java
new file mode 100644
index 0000000000..0447a51563
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Poi.java
@@ -0,0 +1,12 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class Poi {
+ @JsonProperty("frontLat")
+ private String frontLat;
+ @JsonProperty("frontLon")
+ private String frontLon;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Pois.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Pois.java
new file mode 100644
index 0000000000..a59170f04c
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Pois.java
@@ -0,0 +1,10 @@
+package com.example.capstone.api.dto;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class Pois {
+ private List poi;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Properties.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Properties.java
new file mode 100644
index 0000000000..5e0a1fe535
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/Properties.java
@@ -0,0 +1,13 @@
+package com.example.capstone.api.dto;
+
+import lombok.Data;
+
+@Data
+public class Properties {
+ private Integer totalDistance;
+ private Integer totalTime;
+ private Integer index;
+ private Integer pointIndex;
+ private String name;
+ private String description;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/SearchPoiInfo.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/SearchPoiInfo.java
new file mode 100644
index 0000000000..a3f8ca02c3
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/SearchPoiInfo.java
@@ -0,0 +1,13 @@
+package com.example.capstone.api.dto;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SearchPoiInfo {
+ private int totalCount;
+ @JsonProperty("pois")
+ private Pois pois;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapGeoCodingResponseDto.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapGeoCodingResponseDto.java
new file mode 100644
index 0000000000..a42a2dc956
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapGeoCodingResponseDto.java
@@ -0,0 +1,15 @@
+package com.example.capstone.api.dto;
+
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+@Setter
+@ToString
+public class TmapGeoCodingResponseDto {
+
+ private CoordinateInfo coordinateInfo;
+
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPedestrianResponseDto.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPedestrianResponseDto.java
new file mode 100644
index 0000000000..22fec9f4a1
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPedestrianResponseDto.java
@@ -0,0 +1,62 @@
+package com.example.capstone.api.dto;
+
+import com.example.capstone.api.model.Route;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+@Setter
+@ToString
+public class TmapPedestrianResponseDto {
+ @JsonProperty("type")
+ private String type;
+ @JsonProperty("features")
+ private List features;
+
+ public TmapPedestrianResponseDto filteredPoint() {
+ final List features = new ArrayList<>();
+ for (Feature feature : this.features) {
+ if (feature.getGeometry().getType().equalsIgnoreCase("point")) {
+ features.add(feature);
+ }
+ }
+ return new TmapPedestrianResponseDto(
+ this.type,
+ features
+ );
+ }
+
+ public List toEntities() {
+ TmapPedestrianResponseDto tmapPedestrianResponseDto = filteredPoint();
+ List features = tmapPedestrianResponseDto.features;
+
+ List routes = new ArrayList<>();
+
+ for (Feature feature : features) {
+ Properties properties = feature.getProperties();
+ List coordinates = (List) feature.getGeometry().getCoordinates();
+ Route route = new Route();
+
+ String lon = String.valueOf(coordinates.getFirst());
+ route.setLon(lon);
+
+ String lat = String.valueOf(coordinates.getLast());
+ route.setLat(lat);
+
+ Long pointIndex = Long.valueOf(properties.getPointIndex());
+ route.setPointIndex(pointIndex);
+
+ String description = properties.getDescription();
+ route.setDescription(description);
+
+ routes.add(route);
+ }
+ return routes;
+ }
+}
+
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPoiResponseDto.java b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPoiResponseDto.java
new file mode 100644
index 0000000000..104fccfb9e
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/dto/TmapPoiResponseDto.java
@@ -0,0 +1,12 @@
+package com.example.capstone.api.dto;
+
+import lombok.*;
+
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+@Setter
+@ToString
+public class TmapPoiResponseDto {
+ private SearchPoiInfo searchPoiInfo;
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/model/Route.java b/backend/capstone2024/src/main/java/com/example/capstone/api/model/Route.java
new file mode 100644
index 0000000000..3807a4380f
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/model/Route.java
@@ -0,0 +1,31 @@
+package com.example.capstone.api.model;
+
+import com.example.capstone.member.model.Member;
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.sql.SQLTransactionRollbackException;
+
+@Getter
+@Setter
+@Entity
+@NoArgsConstructor
+public class Route {
+
+ @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ private Long pointIndex;
+
+ private String lat;
+
+ private String lon;
+
+ private String description;
+
+ @ManyToOne
+ @JoinColumn(name = "member_uuid")
+ private Member member;
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/repository/RouteRepository.java b/backend/capstone2024/src/main/java/com/example/capstone/api/repository/RouteRepository.java
new file mode 100644
index 0000000000..efb4636780
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/repository/RouteRepository.java
@@ -0,0 +1,22 @@
+package com.example.capstone.api.repository;
+
+import com.example.capstone.api.model.Route;
+import com.example.capstone.member.model.Member;
+import org.springframework.data.domain.Example;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.FluentQuery;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+
+public interface RouteRepository extends JpaRepository {
+
+ List findByMemberUuid(final String uuid);
+ List findByMember(final Member member);
+ @Transactional(rollbackFor = Exception.class)
+ void deleteAllByMemberUuid(String uuid);
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/service/GeoCodingService.java b/backend/capstone2024/src/main/java/com/example/capstone/api/service/GeoCodingService.java
new file mode 100644
index 0000000000..a3fa4e07fd
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/service/GeoCodingService.java
@@ -0,0 +1,37 @@
+package com.example.capstone.api.service;
+
+import com.example.capstone.api.dto.TmapGeoCodingResponseDto;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+
+@Service
+@RequiredArgsConstructor
+public class GeoCodingService {
+
+ private final RestTemplate restTemplate;
+ private final UriBuilderService uriBuilderService;
+ private static final String APPKEY = "qnMdq4E5hK6Jiying7vO84rBBYBMqE0L8JibODZN";
+
+ public TmapGeoCodingResponseDto requestGeoCoding(String address) {
+ if (ObjectUtils.isEmpty(address)) return null;
+
+ URI uri = uriBuilderService.buildUriGeoCodingByAddress(address);
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("appKey", APPKEY);
+
+ HttpEntity httpEntity = new HttpEntity<>(headers);
+
+ //api 호출
+ TmapGeoCodingResponseDto body = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, TmapGeoCodingResponseDto.class).getBody();
+ return body;
+
+ }
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/service/PedestrianService.java b/backend/capstone2024/src/main/java/com/example/capstone/api/service/PedestrianService.java
new file mode 100644
index 0000000000..8b51f3e161
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/service/PedestrianService.java
@@ -0,0 +1,289 @@
+package com.example.capstone.api.service;
+
+import com.example.capstone.api.dto.*;
+import com.example.capstone.api.model.Route;
+import com.example.capstone.api.repository.RouteRepository;
+import com.example.capstone.member.model.Member;
+import com.example.capstone.member.repository.MemberRepository;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+
+@Service
+@RequiredArgsConstructor
+public class PedestrianService {
+ private final RestTemplate restTemplate;
+ private final UriBuilderService uriBuilderService;
+ private final PoiService poiService;
+ private final ObjectMapper objectMapper;
+ private final RouteRepository routeRepository;
+ private final MemberRepository memberRepository;
+
+ private static final String APPKEY = "qnMdq4E5hK6Jiying7vO84rBBYBMqE0L8JibODZN";
+
+ public TmapPedestrianResponseDto requestPedestrian(String startLat, String startLon, String endAddress) throws Exception {
+
+ if (ObjectUtils.isEmpty(startLat) || ObjectUtils.isEmpty(startLon) || ObjectUtils.isEmpty(endAddress))
+ return null;
+ //lon 경도 X
+ //lat 위도 Y
+ TmapPoiResponseDto tmapPoiResponseDto = poiService.requestPoi(endAddress);
+
+ String endLat = tmapPoiResponseDto.getSearchPoiInfo().getPois().getPoi().getFirst().getFrontLat();
+ String endLon = tmapPoiResponseDto.getSearchPoiInfo().getPois().getPoi().getFirst().getFrontLon();
+
+
+ System.out.println("변환 완료");
+ System.out.println("startLat = " + startLat);
+ System.out.println("startLon = " + startLon);
+ System.out.println("endLat = " + endLat);
+ System.out.println("endLon = " + endLon);
+ URI uri = uriBuilderService.buildUriPedestrianByCoord();
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("appKey", APPKEY);
+
+ Map requestBody = new HashMap<>();
+ requestBody.put("startX", startLon);
+ requestBody.put("startY", startLat);
+ requestBody.put("endX", endLon);
+ requestBody.put("endY", endLat);
+ requestBody.put("reqCoordType", "WGS84GEO");
+ requestBody.put("startName", "출발지");
+ requestBody.put("endName", endAddress);
+ HttpEntity> entity = new HttpEntity<>(requestBody, headers);
+//
+ String jsonBody = objectMapper.writeValueAsString(requestBody);
+ // 콘솔에 출력
+ System.out.println("Request JSON Body: " + jsonBody);
+
+ //api 호출
+
+ // API 호출 및 응답 받기 (String 형태로)
+ String rawResponse = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class).getBody();
+
+ // 불법 문자 전처리 (예제: Null 문자 제거)
+ String cleanedResponse = rawResponse.replace("\u0000", "");
+
+ // 전처리된 응답을 DTO로 변환
+ TmapPedestrianResponseDto responseDto = objectMapper.readValue(
+ cleanedResponse, TmapPedestrianResponseDto.class
+ );
+
+
+
+
+ return responseDto;
+ }
+
+
+ public TmapPedestrianResponseDto startPedestrianNavi(String startLat, String startLon, String endAddress, String uuid) throws Exception {
+ if (ObjectUtils.isEmpty(startLat) || ObjectUtils.isEmpty(startLon) || ObjectUtils.isEmpty(endAddress) || ObjectUtils.isEmpty(uuid))
+ return null;
+ //lon 경도 X
+ //lat 위도 Y
+ TmapPoiResponseDto tmapPoiResponseDto = poiService.requestPoi(endAddress);
+
+ String endLat = tmapPoiResponseDto.getSearchPoiInfo().getPois().getPoi().getFirst().getFrontLat();
+ String endLon = tmapPoiResponseDto.getSearchPoiInfo().getPois().getPoi().getFirst().getFrontLon();
+
+
+ System.out.println("변환 완료");
+ System.out.println("startLat = " + startLat);
+ System.out.println("startLon = " + startLon);
+ System.out.println("endLat = " + endLat);
+ System.out.println("endLon = " + endLon);
+ URI uri = uriBuilderService.buildUriPedestrianByCoord();
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("appKey", APPKEY);
+
+ Map requestBody = new HashMap<>();
+ requestBody.put("startX", startLon);
+ requestBody.put("startY", startLat);
+ requestBody.put("endX", endLon);
+ requestBody.put("endY", endLat);
+ requestBody.put("reqCoordType", "WGS84GEO");
+ requestBody.put("startName", "출발지");
+ requestBody.put("endName", endAddress);
+ HttpEntity> entity = new HttpEntity<>(requestBody, headers);
+//
+ // 콘솔에 출력
+ String jsonBody = objectMapper.writeValueAsString(requestBody);
+ System.out.println("Request JSON Body: " + jsonBody);
+
+
+ // API 호출 및 응답 받기 (String 형태로)
+ String rawResponse = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class).getBody();
+
+ // 불법 문자 전처리 (예제: Null 문자 제거)
+ String cleanedResponse = rawResponse.replace("\u0000", "");
+
+ // 전처리된 응답을 DTO로 변환
+ TmapPedestrianResponseDto responseDto = objectMapper.readValue(cleanedResponse, TmapPedestrianResponseDto.class)
+ .filteredPoint();
+ System.out.println();
+ List entities = responseDto.toEntities();
+
+ Member member = memberRepository.findByUuid(uuid).getFirst();
+ for (Route e : entities) {
+ e.setMember(member);
+ }
+ routeRepository.saveAll(entities);
+ return responseDto;
+ }
+
+ public DistanceInfo currentLocationCheck(String curLat, String curLon,
+ String uuid, int pointIndex, int cnt, int distance){
+
+ List path = routeRepository.findByMemberUuid(uuid);
+ String nextLon = path.get(pointIndex).getLon();
+ String nextLat = path.get(pointIndex).getLat();
+
+
+
+
+ URI uri = uriBuilderService.buildUriDistanceInfo(curLon, curLat, nextLon, nextLat);
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("appKey", APPKEY);
+
+ HttpEntity httpEntity = new HttpEntity<>(headers);
+
+ //api 호출
+ DistanceResponseDTO body = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, DistanceResponseDTO.class).getBody();
+
+ DistanceInfo info = new DistanceInfo();
+ int dist = Integer.parseInt(body.getDistanceInfo().getDistance());
+ if (dist > distance)
+ cnt++;
+
+
+
+ if (dist <= 5){
+ info.setDistance(String.valueOf(dist));
+ info.setPointIndex(pointIndex+1);
+ info.setCnt(cnt);
+ info.setLat(nextLat);
+ info.setLon(nextLon);
+ if(pointIndex == path.size()-1){
+ info.setDescription("도착");
+ System.out.println("dist = " + dist);
+ System.out.println("path 최대 인덱스 = " + (path.size()-1));
+ }
+ else {
+ info.setDescription(path.get(pointIndex).getDescription());
+ System.out.println("dist = " + dist);
+ System.out.println("path 최대 인덱스 = " + (path.size()-1));
+ }
+
+ return info;
+ }
+ else {
+ info.setDistance(String.valueOf(dist));
+ info.setPointIndex(pointIndex);
+ if (cnt >= 4) {
+ info.setDescription("재탐색");
+ info.setCnt(0);
+ }
+ else {
+ info.setCnt(cnt);
+ info.setDescription("이동중");
+ }
+ info.setLat(nextLat);
+ info.setLon(nextLon);
+
+ System.out.println("dist = " + dist);
+ System.out.println("path 최대 인덱스 = " + (path.size()-1));
+ return info;
+ }
+
+ }
+ public DirectionInfo directionCheck(String curLat, String curLon,
+ String uuid, int pointIndex, String curDir){
+
+ List path = routeRepository.findByMemberUuid(uuid);
+ String nextLon = path.get(pointIndex).getLon();
+ String nextLat = path.get(pointIndex).getLat();
+ //방향 계산
+
+ double startLatDouble = Double.parseDouble(curLat);
+ double startLonDouble = Double.parseDouble(curLon);
+ double endLatDouble = Double.parseDouble(nextLat);
+ double endLonDouble = Double.parseDouble(nextLon);
+
+ double lat1 = Math.toRadians(startLatDouble);
+ double lon1 = Math.toRadians(startLonDouble);
+ double lat2 = Math.toRadians(endLatDouble);
+ double lon2 = Math.toRadians(endLonDouble);
+
+ double dLon = lon2 - lon1;
+
+ double x = Math.cos(lat2) * Math.sin(dLon);
+ double y = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
+
+ double initialBearing = Math.atan2(x, y);
+
+ // Convert bearing from radians to degrees
+ initialBearing = Math.toDegrees(initialBearing);
+ initialBearing = (initialBearing + 360) % 360;
+
+ // Convert to 45 degree compass directions
+ String[] compassDirections = {"N", "E", "S", "W"};
+ int index = (int) Math.round(initialBearing / 90) % 4;
+
+ String targetDir = compassDirections[index];
+
+ int currentIndex = -1;
+ int targetIndex = -1;
+ String dirMsg;
+
+ for (int i = 0; i < compassDirections.length; i++) {
+ if (compassDirections[i].equals(curDir)) {
+ currentIndex = i;
+ }
+ if (compassDirections[i].equals(targetDir)) {
+ targetIndex = i;
+ }
+ }
+ if (currentIndex == -1 || targetIndex == -1) {
+ dirMsg = "방위 계산 오류";
+ }
+
+
+ int difference = targetIndex - currentIndex;
+ if (difference < 0) {
+ difference += 4;
+ }
+
+ if (difference == 0) {
+ dirMsg = "해당 방향으로 진행하세요";
+ } else if (difference == 1) {
+ dirMsg = "오른쪽으로 몸을 돌리세요";
+ } else if (difference == 2) {
+ dirMsg = "뒤로 돌리세요";
+ } else {
+ dirMsg = "왼쪽으로 몸을 돌리세요";
+ }
+ DirectionInfo dirInfo = new DirectionInfo();
+ dirInfo.setDirMsg(dirMsg);
+ return dirInfo;
+ }
+ public void cancelNavi(String uuid){
+ routeRepository.deleteAllByMemberUuid(uuid);
+ System.out.println("uuid = " + uuid + "삭제 중");
+ }
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/service/PoiService.java b/backend/capstone2024/src/main/java/com/example/capstone/api/service/PoiService.java
new file mode 100644
index 0000000000..4d977e25a8
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/service/PoiService.java
@@ -0,0 +1,40 @@
+package com.example.capstone.api.service;
+
+import com.example.capstone.api.dto.TmapGeoCodingResponseDto;
+import com.example.capstone.api.dto.TmapPoiResponseDto;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+
+@Service
+@RequiredArgsConstructor
+public class PoiService {
+
+ private final RestTemplate restTemplate;
+ private final UriBuilderService uriBuilderService;
+
+ private static final String APPKEY = "qnMdq4E5hK6Jiying7vO84rBBYBMqE0L8JibODZN";
+
+ public TmapPoiResponseDto requestPoi(String address) {
+ if (ObjectUtils.isEmpty(address)) return null;
+
+ URI uri = uriBuilderService.buildUriPoiByCoord(address);
+
+ HttpHeaders headers = new HttpHeaders();
+ headers.set("appKey", APPKEY);
+
+ HttpEntity httpEntity = new HttpEntity<>(headers);
+
+ //api 호출
+
+ TmapPoiResponseDto body2 = restTemplate.exchange(uri, HttpMethod.GET, httpEntity, TmapPoiResponseDto.class).getBody();
+ return body2;
+ }
+
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/api/service/UriBuilderService.java b/backend/capstone2024/src/main/java/com/example/capstone/api/service/UriBuilderService.java
new file mode 100644
index 0000000000..31329c00b3
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/api/service/UriBuilderService.java
@@ -0,0 +1,64 @@
+package com.example.capstone.api.service;
+
+import org.springframework.stereotype.Service;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.net.URI;
+
+@Service
+public class UriBuilderService {
+
+ //좌표 변환
+ private static final String TMAP_GEO_CODING_URL = "https://apis.openapi.sk.com/tmap/geo/fullAddrGeo";
+ //보행자 경로 검색
+ private static final String TMAP_PEDESTRIAN_URL = "https://apis.openapi.sk.com/tmap/routes/pedestrian";
+ //POI 검색
+ private static final String TMAP_POI_URL = "https://apis.openapi.sk.com/tmap/pois";
+ // 두 좌표 간 직선 거리 계산
+ private static final String TMAP_DISTANCE = "https://apis.openapi.sk.com/tmap/routes/distance";
+
+ public URI buildUriGeoCodingByAddress(String address) {
+ UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(TMAP_GEO_CODING_URL);
+ uriBuilder.queryParam("coordType", "WGS84GEO");
+ uriBuilder.queryParam("fullAddr", address);
+ uriBuilder.queryParam("addressFlag", "F00");
+
+ URI uri = uriBuilder.build().encode().toUri();
+ System.out.println("uri = " + uri);
+ return uri;
+ }
+
+ //출발지 좌표값, 목적지 좌표값, 출발지 도착지 지명 필요
+ public URI buildUriPedestrianByCoord() {
+ UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(TMAP_PEDESTRIAN_URL);
+ uriBuilder.queryParam("version", "1");
+ URI uri = uriBuilder.build().encode().toUri();
+ System.out.println("pede uri = " + uri);
+ return uri;
+ }
+
+ public URI buildUriPoiByCoord(String address) {
+ UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(TMAP_POI_URL)
+ .queryParam("version", "1")
+ .queryParam("searchKeyword", address)
+ .queryParam("resCoordType", "WGS84GEO")
+ .queryParam("reqCoordType", "WGS84GEO");
+ URI uri = uriBuilder.build().encode().toUri();
+ System.out.println("uri = " + uri);
+ return uri;
+ }
+
+ public URI buildUriDistanceInfo(String startX, String startY, String endX, String endY){
+ UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(TMAP_DISTANCE)
+ .queryParam("version","1")
+ .queryParam("startX",startX)
+ .queryParam("startY",startY)
+ .queryParam("endX",endX)
+ .queryParam("endY",endY);
+ URI uri = uriComponentsBuilder.build().encode().toUri();
+ System.out.println("uri = " + uri);
+ return uri;
+
+
+ }
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/config/RestTemplateConfig.java b/backend/capstone2024/src/main/java/com/example/capstone/config/RestTemplateConfig.java
new file mode 100644
index 0000000000..2fe9c1e124
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/config/RestTemplateConfig.java
@@ -0,0 +1,14 @@
+package com.example.capstone.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate(){
+ return new RestTemplate();
+ }
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/controller/MemberController.java b/backend/capstone2024/src/main/java/com/example/capstone/member/controller/MemberController.java
new file mode 100644
index 0000000000..3d8426a641
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/controller/MemberController.java
@@ -0,0 +1,84 @@
+package com.example.capstone.member.controller;
+
+import com.example.capstone.member.dto.FavoriteRequest;
+import com.example.capstone.member.dto.FavoriteResponse;
+import com.example.capstone.member.dto.MemberCheckResponse;
+import com.example.capstone.member.model.Favorite;
+import com.example.capstone.member.model.Member;
+import com.example.capstone.member.repository.FavoriteRepository;
+import com.example.capstone.member.repository.MemberRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import java.sql.Timestamp;
+import java.util.List;
+
+@RestController
+public class MemberController {
+
+ @Autowired
+ private MemberRepository memberRepository;
+
+ @Autowired
+ private FavoriteRepository favoriteRepository;
+
+ @GetMapping("/checkMember")
+ public ResponseEntity checkMember(@RequestParam String uuid) {
+ System.out.println("UUID: " + uuid);
+
+ List memberList = memberRepository.findByUuid(uuid);
+ if (!memberList.isEmpty()) {
+ Member member = memberList.getFirst();
+ System.out.println(member.toString());
+
+ List favoriteList = favoriteRepository.findByMemberUuid(uuid);
+ if (!favoriteList.isEmpty()) {
+ System.out.println(favoriteList.toString());
+ MemberCheckResponse response = new MemberCheckResponse(member, favoriteList);
+ return ResponseEntity.ok(response);
+ } else {
+ System.out.println("즐겨찾기 X");
+ MemberCheckResponse response = new MemberCheckResponse(member, null);
+ return ResponseEntity.ok(response);
+ }
+ } else {
+ Member newMember = new Member(uuid, new Timestamp(System.currentTimeMillis()));
+ memberRepository.save(newMember);
+ System.out.println("member 추가");
+
+ MemberCheckResponse response = new MemberCheckResponse(newMember, null);
+ System.out.println("즐겨찾기 X");
+ return ResponseEntity.ok(response);
+ }
+ }
+ @PostMapping("/addFavorite")
+ public ResponseEntity addFavorite(
+ @RequestBody FavoriteRequest favoriteRequest
+ ) {
+ System.out.println("UUID : " + favoriteRequest.getMemberUuid());
+ System.out.println("즐겨찾기명 : " + favoriteRequest.getFavoriteName());
+ System.out.println("도착지명 : " + favoriteRequest.getDestinationName());
+ System.out.println("도착지좌표 : " + favoriteRequest.getDestinationCoordinates());
+
+ List memberList = memberRepository.findByUuid(favoriteRequest.getMemberUuid());
+ if (memberList.isEmpty()) {
+ System.out.println("member X");
+ return ResponseEntity.badRequest().body(new FavoriteResponse(null));
+ }
+
+ Member member = memberList.getFirst();
+
+ Favorite newFavorite = new Favorite();
+ newFavorite.setMemberUuid(favoriteRequest.getMemberUuid());
+ newFavorite.setFavoriteName(favoriteRequest.getFavoriteName());
+ newFavorite.setDestinationName(favoriteRequest.getDestinationName());
+ newFavorite.setDestinationCoordinates(favoriteRequest.getDestinationCoordinates());
+ newFavorite.setCreatedAt(new Timestamp(System.currentTimeMillis()));
+
+ favoriteRepository.save(newFavorite);
+ System.out.println("즐겨찾기 추가");
+
+ FavoriteResponse response = new FavoriteResponse(newFavorite);
+ return ResponseEntity.ok(response);
+ }
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteRequest.java b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteRequest.java
new file mode 100644
index 0000000000..dce0dd0cbb
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteRequest.java
@@ -0,0 +1,11 @@
+package com.example.capstone.member.dto;
+
+import lombok.Data;
+
+@Data
+public class FavoriteRequest {
+ private String memberUuid;
+ private String favoriteName;
+ private String destinationName;
+ private String destinationCoordinates;
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteResponse.java b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteResponse.java
new file mode 100644
index 0000000000..0a07b9a1cd
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/FavoriteResponse.java
@@ -0,0 +1,13 @@
+package com.example.capstone.member.dto;
+
+import com.example.capstone.member.model.Favorite;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FavoriteResponse {
+ private Favorite favorite;
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/dto/MemberCheckResponse.java b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/MemberCheckResponse.java
new file mode 100644
index 0000000000..321bc32b1e
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/dto/MemberCheckResponse.java
@@ -0,0 +1,18 @@
+package com.example.capstone.member.dto;
+
+import com.example.capstone.member.model.Member;
+import com.example.capstone.member.model.Favorite;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import java.util.List;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class MemberCheckResponse {
+ private Member member;
+ private List favorites;
+}
\ No newline at end of file
diff --git "a/backend/capstone2024/src/main/java/com/example/capstone/member/member\353\212\224\354\227\254\352\270\260\354\227\220.txt" "b/backend/capstone2024/src/main/java/com/example/capstone/member/member\353\212\224\354\227\254\352\270\260\354\227\220.txt"
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/model/Favorite.java b/backend/capstone2024/src/main/java/com/example/capstone/member/model/Favorite.java
new file mode 100644
index 0000000000..e896cf51ff
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/model/Favorite.java
@@ -0,0 +1,41 @@
+package com.example.capstone.member.model;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.sql.Timestamp;
+
+@Setter
+@Getter
+@Entity
+public class Favorite {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ private String memberUuid;
+ private String favoriteName;
+ private String destinationName;
+ private String destinationCoordinates;
+ private Timestamp createdAt;
+
+ public Favorite() {
+
+ }
+
+ @Override
+ public String toString() {
+ return "Favorite{" +
+ "id=" + id +
+ ", memberUuid='" + memberUuid + '\'' +
+ ", favoriteName='" + favoriteName + '\'' +
+ ", destinationName='" + destinationName + '\'' +
+ ", destinationCoordinates='" + destinationCoordinates + '\'' +
+ ", createdAt=" + createdAt +
+ '}';
+ }
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/model/Member.java b/backend/capstone2024/src/main/java/com/example/capstone/member/model/Member.java
new file mode 100644
index 0000000000..641fc82bb3
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/model/Member.java
@@ -0,0 +1,36 @@
+package com.example.capstone.member.model;
+
+import java.sql.Timestamp;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+@Entity
+public class Member {
+
+ @Id
+ private String uuid;
+
+ @Column(name = "created_at")
+ private Timestamp createdAt;
+
+ public Member() {
+ }
+
+ public Member(String uuid, Timestamp createdAt) {
+ this.uuid = uuid;
+ this.createdAt = createdAt;
+ }
+
+ @Override
+ public String toString() {
+ return "Member{" +
+ ", uuid='" + uuid + '\'' +
+ ", createdAt=" + createdAt +
+ '}';
+ }
+
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/repository/FavoriteRepository.java b/backend/capstone2024/src/main/java/com/example/capstone/member/repository/FavoriteRepository.java
new file mode 100644
index 0000000000..595ca5ead7
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/repository/FavoriteRepository.java
@@ -0,0 +1,9 @@
+package com.example.capstone.member.repository;
+
+import com.example.capstone.member.model.Favorite;
+import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
+
+public interface FavoriteRepository extends JpaRepository {
+ List findByMemberUuid(String memberUuid);
+}
diff --git a/backend/capstone2024/src/main/java/com/example/capstone/member/repository/MemberRepository.java b/backend/capstone2024/src/main/java/com/example/capstone/member/repository/MemberRepository.java
new file mode 100644
index 0000000000..48f79bb6bd
--- /dev/null
+++ b/backend/capstone2024/src/main/java/com/example/capstone/member/repository/MemberRepository.java
@@ -0,0 +1,9 @@
+package com.example.capstone.member.repository;
+
+import com.example.capstone.member.model.Member;
+import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
+
+public interface MemberRepository extends JpaRepository {
+ List findByUuid(String uuid);
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/main/resources/application.properties b/backend/capstone2024/src/main/resources/application.properties
new file mode 100644
index 0000000000..3db13ee0c2
--- /dev/null
+++ b/backend/capstone2024/src/main/resources/application.properties
@@ -0,0 +1,9 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/capstone?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&serverTimezone=UTC
+spring.datasource.username=yoon
+spring.datasource.password=yoon1234!
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.format_sql=false
+spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
+spring.jpa.hibernate.ddl-auto=update
diff --git a/backend/capstone2024/src/test/java/com/example/capstone/CapstoneApplicationTests.java b/backend/capstone2024/src/test/java/com/example/capstone/CapstoneApplicationTests.java
new file mode 100644
index 0000000000..586b4782b2
--- /dev/null
+++ b/backend/capstone2024/src/test/java/com/example/capstone/CapstoneApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.capstone;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+//@SpringBootTest
+class CapstoneApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/backend/capstone2024/src/test/java/com/example/capstone/api/dto/TmapPedestrianResponseDtoTest.java b/backend/capstone2024/src/test/java/com/example/capstone/api/dto/TmapPedestrianResponseDtoTest.java
new file mode 100644
index 0000000000..8d817336af
--- /dev/null
+++ b/backend/capstone2024/src/test/java/com/example/capstone/api/dto/TmapPedestrianResponseDtoTest.java
@@ -0,0 +1,30 @@
+package com.example.capstone.api.dto;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class TmapPedestrianResponseDtoTest {
+
+ @Test
+ @DisplayName("filteredPoint()를 호출하면 geometryType이 Point인 객체만 반환된다.")
+ void test01() {
+ Feature point1 = new Feature();
+ point1.setGeometry(new Geometry("Point", null));
+ Feature point2 = new Feature();
+ point2.setGeometry(new Geometry("LineString", null));
+ Feature point3 = new Feature();
+ point3.setGeometry(new Geometry("아무 의미도 없는 값", null));
+ Feature point4 = new Feature();
+ point4.setGeometry(new Geometry("point", null));
+ List points = List.of(point1, point2, point3, point4);
+
+ TmapPedestrianResponseDto temp = new TmapPedestrianResponseDto("temp", points);
+ TmapPedestrianResponseDto result = temp.filteredPoint();
+ Assertions.assertThat(result.getFeatures()).hasSize(2);
+ }
+}
\ No newline at end of file
diff --git a/backend/capstone2024/src/test/java/com/example/capstone/api/repository/RouteRepositoryTest.java b/backend/capstone2024/src/test/java/com/example/capstone/api/repository/RouteRepositoryTest.java
new file mode 100644
index 0000000000..6e34460ff4
--- /dev/null
+++ b/backend/capstone2024/src/test/java/com/example/capstone/api/repository/RouteRepositoryTest.java
@@ -0,0 +1,60 @@
+package com.example.capstone.api.repository;
+
+import com.example.capstone.api.model.Route;
+import com.example.capstone.member.model.Member;
+import com.example.capstone.member.repository.MemberRepository;
+import jakarta.persistence.EntityManager;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.data.cassandra.DataCassandraTest;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+
+import javax.swing.text.html.parser.Entity;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@DataJpaTest
+class RouteRepositoryTest {
+
+ @Autowired
+ private MemberRepository memberRepository;
+
+ @Autowired
+ private RouteRepository routeRepository;
+
+ @Autowired
+ private EntityManager em;
+
+ @Test
+ void assert_notNull() {
+ assertNotNull(memberRepository);
+ assertNotNull(routeRepository);
+ }
+
+ @Test
+ void assert_findByMemberUuid() {
+ Member member = new Member();
+ member.setUuid("정회창");
+ memberRepository.save(member);
+ Route route = new Route();
+ route.setMember(member);
+ route.setPointIndex(68L);
+ routeRepository.save(route);
+ em.flush();
+ em.clear();
+ System.out.println("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
+ List byMemberUuid = routeRepository.findByMemberUuid(
+ member.getUuid()
+ );
+ em.flush();
+ em.clear();
+ System.out.println("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
+ routeRepository.findByMember(member);
+
+ System.out.println();
+ }
+}
\ No newline at end of file
diff --git a/backend/testtest.txt b/backend/testtest.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git "a/docs/EYE-U \341\204\206\341\205\242\341\204\202\341\205\262\341\204\213\341\205\245\341\206\257.pdf" "b/docs/EYE-U \341\204\206\341\205\242\341\204\202\341\205\262\341\204\213\341\205\245\341\206\257.pdf"
new file mode 100644
index 0000000000..306e2f63fd
Binary files /dev/null and "b/docs/EYE-U \341\204\206\341\205\242\341\204\202\341\205\262\341\204\213\341\205\245\341\206\257.pdf" differ
diff --git "a/docs/EYE-U \353\247\244\353\211\264\354\226\274.pdf" "b/docs/EYE-U \353\247\244\353\211\264\354\226\274.pdf"
new file mode 100644
index 0000000000..306e2f63fd
Binary files /dev/null and "b/docs/EYE-U \353\247\244\353\211\264\354\226\274.pdf" differ
diff --git "a/docs/\341\204\211\341\205\256\341\204\222\341\205\242\341\206\274\341\204\200\341\205\247\341\206\257\341\204\200\341\205\252\341\204\207\341\205\251\341\204\200\341\205\251\341\204\211\341\205\245-\341\204\200\341\205\242\341\206\250\341\204\216\341\205\246\341\204\220\341\205\241\341\206\267\341\204\214\341\205\265\341\204\205\341\205\263\341\206\257 \341\204\222\341\205\252\341\206\257\341\204\213\341\205\255\341\206\274\341\204\222\341\205\241\341\206\253 \341\204\211\341\205\265\341\204\200\341\205\241\341\206\250\341\204\214\341\205\241\341\206\274\341\204\213\341\205\242\341\204\213\341\205\265\341\206\253\341\204\213\341\205\255\341\206\274 \341\204\207\341\205\251\341\204\222\341\205\242\341\206\274 \341\204\207\341\205\251\341\204\214\341\205\251 \341\204\213\341\205\242\341\206\270.pdf" "b/docs/\341\204\211\341\205\256\341\204\222\341\205\242\341\206\274\341\204\200\341\205\247\341\206\257\341\204\200\341\205\252\341\204\207\341\205\251\341\204\200\341\205\251\341\204\211\341\205\245-\341\204\200\341\205\242\341\206\250\341\204\216\341\205\246\341\204\220\341\205\241\341\206\267\341\204\214\341\205\265\341\204\205\341\205\263\341\206\257 \341\204\222\341\205\252\341\206\257\341\204\213\341\205\255\341\206\274\341\204\222\341\205\241\341\206\253 \341\204\211\341\205\265\341\204\200\341\205\241\341\206\250\341\204\214\341\205\241\341\206\274\341\204\213\341\205\242\341\204\213\341\205\265\341\206\253\341\204\213\341\205\255\341\206\274 \341\204\207\341\205\251\341\204\222\341\205\242\341\206\274 \341\204\207\341\205\251\341\204\214\341\205\251 \341\204\213\341\205\242\341\206\270.pdf"
new file mode 100644
index 0000000000..82d1c2f704
Binary files /dev/null and "b/docs/\341\204\211\341\205\256\341\204\222\341\205\242\341\206\274\341\204\200\341\205\247\341\206\257\341\204\200\341\205\252\341\204\207\341\205\251\341\204\200\341\205\251\341\204\211\341\205\245-\341\204\200\341\205\242\341\206\250\341\204\216\341\205\246\341\204\220\341\205\241\341\206\267\341\204\214\341\205\265\341\204\205\341\205\263\341\206\257 \341\204\222\341\205\252\341\206\257\341\204\213\341\205\255\341\206\274\341\204\222\341\205\241\341\206\253 \341\204\211\341\205\265\341\204\200\341\205\241\341\206\250\341\204\214\341\205\241\341\206\274\341\204\213\341\205\242\341\204\213\341\205\265\341\206\253\341\204\213\341\205\255\341\206\274 \341\204\207\341\205\251\341\204\222\341\205\242\341\206\274 \341\204\207\341\205\251\341\204\214\341\205\251 \341\204\213\341\205\242\341\206\270.pdf" differ
diff --git "a/docs/\354\210\230\355\226\211\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234-\352\260\235\354\262\264\355\203\220\354\247\200\353\245\274 \355\231\234\354\232\251\355\225\234 \354\213\234\352\260\201\354\236\245\354\225\240\354\235\270\354\232\251 \353\263\264\355\226\211 \353\263\264\354\241\260 \354\225\261.pdf" "b/docs/\354\210\230\355\226\211\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234-\352\260\235\354\262\264\355\203\220\354\247\200\353\245\274 \355\231\234\354\232\251\355\225\234 \354\213\234\352\260\201\354\236\245\354\225\240\354\235\270\354\232\251 \353\263\264\355\226\211 \353\263\264\354\241\260 \354\225\261.pdf"
new file mode 100644
index 0000000000..82d1c2f704
Binary files /dev/null and "b/docs/\354\210\230\355\226\211\352\262\260\352\263\274\353\263\264\352\263\240\354\204\234-\352\260\235\354\262\264\355\203\220\354\247\200\353\245\274 \355\231\234\354\232\251\355\225\234 \354\213\234\352\260\201\354\236\245\354\225\240\354\235\270\354\232\251 \353\263\264\355\226\211 \353\263\264\354\241\260 \354\225\261.pdf" differ
diff --git a/frontend/.DS_Store b/frontend/.DS_Store
new file mode 100644
index 0000000000..15517fad3e
Binary files /dev/null and b/frontend/.DS_Store differ
diff --git a/frontend/flutter_vision-master/.gitignore b/frontend/flutter_vision-master/.gitignore
new file mode 100644
index 0000000000..253e1941e4
--- /dev/null
+++ b/frontend/flutter_vision-master/.gitignore
@@ -0,0 +1,30 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+.packages
+build/
+.fvm
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/.metadata b/frontend/flutter_vision-master/.metadata
new file mode 100644
index 0000000000..a23172b921
--- /dev/null
+++ b/frontend/flutter_vision-master/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 7e9793dee1b85a243edd0e06cb1658e98b077561
+ channel: stable
+
+project_type: plugin
diff --git a/frontend/flutter_vision-master/CHANGELOG.md b/frontend/flutter_vision-master/CHANGELOG.md
new file mode 100644
index 0000000000..9a72ec5991
--- /dev/null
+++ b/frontend/flutter_vision-master/CHANGELOG.md
@@ -0,0 +1,31 @@
+## 1.1.4
+* Resolved the YoloV8 output bug and made updates to the latest version. Please find the latest release on the Ultralytics YOLOv8 0.181 GitHub repository
+## 1.1.3
+* Release of segmentation feature via YOLOv8.
+* Updated example code.
+* Updated README.
+## 1.1.2
+* GPU delegation error has been fixed.
+* Coordinate representation of the box in documentation was fixed.
+* Switching between models now are supported.
+* Added quantization option for more efficient models at the cost of some precision.
+## 1.1.1
+* Bounding box error has been fixed.
+* Confidence scores for Yolov8 has been fixed.
+## 1.1.0
+* loadOcrModel, ocrOnFrame, and closeOcrModel have been removed. Instead, Yolo and Tesseract operate independently of each other.
+* Models no longer returns responseHandler as output. Instead, it returns a List>.
+* The Tesseract model has been updated to version 5.0.0, resulting in improved accuracy.
+* New methods have been added: loadYoloModel, yoloOnFrame, yoloOnImage, closeYoloModel, loadTesseractModel, tesseractOnImage, and closeTesseractModel.
+* Support is now available for both Yolov5 and Yolov8.
+* Resource management has been improved, and all models now operate in the background.
+
+## 1.0.0
+* Methods for Yolov5 now is available `(loadYoloModel, yoloOnFrame, closeYoloModel)`.
+* Yolov5 and OCR model now is independent one to each other.
+
+## 0.0.2
+* `best` parameter has been removed
+
+## 0.0.1
+* Initial release.
diff --git a/frontend/flutter_vision-master/LICENSE b/frontend/flutter_vision-master/LICENSE
new file mode 100644
index 0000000000..8783b2f2d1
--- /dev/null
+++ b/frontend/flutter_vision-master/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Yuri Vladimir Huallpa Vargas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/README.md b/frontend/flutter_vision-master/README.md
new file mode 100644
index 0000000000..c7b86e1b31
--- /dev/null
+++ b/frontend/flutter_vision-master/README.md
@@ -0,0 +1,192 @@
+# flutter_vision
+
+A Flutter plugin for managing [Yolov5, Yolov8](https://github.com/ultralytics/ultralytics) and [Tesseract v5](https://tesseract-ocr.github.io/tessdoc/) accessing with TensorFlow Lite 2.x. Support object detection, segmentation and OCR on Android. iOS not updated, working in progress.
+
+# Installation
+Add flutter_vision as a dependency in your pubspec.yaml file.
+
+## Android
+In `android/app/build.gradle`, add the following setting in android block.
+
+```gradle
+ android{
+ aaptOptions {
+ noCompress 'tflite'
+ noCompress 'lite'
+ }
+ }
+```
+## iOS
+Comming soon ...
+
+# Usage
+## For YoloV5 and YoloV8 MODEL
+1. Create a `assets` folder and place your labels file and model file in it. In `pubspec.yaml` add:
+
+```
+ assets:
+ - assets/labels.txt
+ - assets/yolovx.tflite
+```
+
+2. Import the library:
+
+```dart
+import 'package:flutter_vision/flutter_vision.dart';
+```
+
+3. Initialized the flutter_vision library:
+
+```dart
+ FlutterVision vision = FlutterVision();
+```
+
+4. Load the model and labels:
+`modelVersion`: yolov5 or yolov8 or yolov8seg
+```dart
+await vision.loadYoloModel(
+ labels: 'assets/labelss.txt',
+ modelPath: 'assets/yolov5n.tflite',
+ modelVersion: "yolov5",
+ quantization: false,
+ numThreads: 1,
+ useGpu: false);
+```
+### For camera live feed
+5. Make your first detection:
+`confThreshold` work with yolov5 other case it is omited.
+> _Make use of [camera plugin](https://pub.dev/packages/camera)_
+
+```dart
+final result = await 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);
+```
+
+### For static image
+5. Make your first detection or segmentation:
+
+```dart
+final result = await vision.yoloOnImage(
+ bytesList: byte,
+ imageHeight: image.height,
+ imageWidth: image.width,
+ iouThreshold: 0.8,
+ confThreshold: 0.4,
+ classThreshold: 0.7);
+```
+
+6. Release resources:
+
+```dart
+await vision.closeYoloModel();
+```
+## For Tesseract 5.0.0 MODEL
+1. Create an `assets` folder, then create a `tessdata` directory and `tessdata_config.json` file and place them into it.
+Download trained data for tesseract from [here](https://github.com/tesseract-ocr/tessdata) and place it into tessdata directory. Then, modifie tessdata_config.json as follow.
+```json
+{
+ "files": [
+ "spa.traineddata"
+ ]
+}
+```
+
+2. In `pubspec.yaml` add:
+```
+assets:
+ - assets/
+ - assets/tessdata/
+```
+3. Import the library:
+
+```dart
+import 'package:flutter_vision/flutter_vision.dart';
+```
+
+4. Initialized the flutter_vision library:
+
+```dart
+ FlutterVision vision = FlutterVision();
+```
+
+5. Load the model:
+
+```dart
+await vision.loadTesseractModel(
+ args: {
+ 'psm': '11',
+ 'oem': '1',
+ 'preserve_interword_spaces': '1',
+ },
+ language: 'spa',
+ );
+```
+
+### For static image
+6. Get Text from static image:
+
+```dart
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ final result = await vision.tesseractOnImage(bytesList: (await photo.readAsBytes()));
+ }
+```
+
+7. Release resources:
+
+```dart
+await vision.closeTesseractModel();
+```
+# About results
+## For Yolo v5 or v8 in detection task
+result is a `List>` where Map have the following keys:
+
+ ``` dart
+ Map:{
+ "box": [x1:left, y1:top, x2:right, y2:bottom, class_confidence]
+ "tag": String: detected class
+ }
+```
+
+## For YoloV8 in segmentation task
+result is a `List>` where Map have the following keys:
+
+ ``` dart
+ Map:{
+ "box": [x1:left, y1:top, x2:right, y2:bottom, class_confidence]
+ "tag": String: detected class
+ "polygons": List>: [{x:coordx, y:coordy}]
+ }
+```
+
+## For Tesseract
+result is a `List>` where Map have the following keys:
+
+```dart
+ Map:{
+ "text": String
+ "word_conf": List:int
+ "mean_conf": int}
+```
+
+# Example
+
+
+
+
+
+
+# Contact
+
+For flutter_vision bug reports and feature requests please visit [GitHub Issues](https://github.com/vladiH/flutter_vision/issues)
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/analysis_options.yaml b/frontend/flutter_vision-master/analysis_options.yaml
new file mode 100644
index 0000000000..a5744c1cfb
--- /dev/null
+++ b/frontend/flutter_vision-master/analysis_options.yaml
@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/frontend/flutter_vision-master/android/.gitignore b/frontend/flutter_vision-master/android/.gitignore
new file mode 100644
index 0000000000..c6cbe562a4
--- /dev/null
+++ b/frontend/flutter_vision-master/android/.gitignore
@@ -0,0 +1,8 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/frontend/flutter_vision-master/android/build.gradle b/frontend/flutter_vision-master/android/build.gradle
new file mode 100644
index 0000000000..4e9e193b73
--- /dev/null
+++ b/frontend/flutter_vision-master/android/build.gradle
@@ -0,0 +1,66 @@
+group 'com.vladih.computer_vision.flutter_vision'
+version '1.0'
+
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ }
+}
+
+rootProject.allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ flatDir{
+ dirs project(":flutter_vision").file("libs")
+ }
+ maven {
+ url 'https://jitpack.io'
+ }
+ maven{
+ name 'ossrh-snapshot'
+ url 'https://oss.sonatype.org/content/repositories/snapshots'
+ }
+ }
+}
+
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 31
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ defaultConfig {
+ minSdkVersion 21
+ }
+ aaptOptions {
+ noCompress 'tflite'
+ noCompress 'lite'
+ }
+
+ buildFeatures{
+ mlModelBinding true
+ }
+}
+dependencies{
+ //implementation (files('libs/tesseract4android-release.aar'))
+ api(name:"tesseract4android-release", ext: "aar")
+ implementation 'com.github.vladiH:opencv-android:v1.0.0'
+ implementation 'org.tensorflow:tensorflow-lite:2.10.0'
+ implementation 'org.tensorflow:tensorflow-lite-api:2.10.0'
+ implementation 'org.tensorflow:tensorflow-lite-gpu:2.10.0'
+ implementation 'org.tensorflow:tensorflow-lite-gpu-api:2.10.0'
+ implementation 'org.tensorflow:tensorflow-lite-gpu-delegate-plugin:0.4.3'
+ implementation 'org.tensorflow:tensorflow-lite-support:0.4.3'
+ implementation 'org.tensorflow:tensorflow-lite-metadata:0.4.3'
+ implementation 'org.tensorflow:tensorflow-lite-select-tf-ops:2.11.0'
+}
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.jar b/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..e708b1c023
Binary files /dev/null and b/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.properties b/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..1a903ddfa5
--- /dev/null
+++ b/frontend/flutter_vision-master/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Feb 22 11:31:00 CET 2023
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/frontend/flutter_vision-master/android/gradlew b/frontend/flutter_vision-master/android/gradlew
new file mode 100644
index 0000000000..4f906e0c81
--- /dev/null
+++ b/frontend/flutter_vision-master/android/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/frontend/flutter_vision-master/android/gradlew.bat b/frontend/flutter_vision-master/android/gradlew.bat
new file mode 100644
index 0000000000..107acd32c4
--- /dev/null
+++ b/frontend/flutter_vision-master/android/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/frontend/flutter_vision-master/android/libs/tesseract4android-release.aar b/frontend/flutter_vision-master/android/libs/tesseract4android-release.aar
new file mode 100644
index 0000000000..42fe53b713
Binary files /dev/null and b/frontend/flutter_vision-master/android/libs/tesseract4android-release.aar differ
diff --git a/frontend/flutter_vision-master/android/settings.gradle b/frontend/flutter_vision-master/android/settings.gradle
new file mode 100644
index 0000000000..c434a6bcd5
--- /dev/null
+++ b/frontend/flutter_vision-master/android/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = "flutter_vision"
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/android/src/main/AndroidManifest.xml b/frontend/flutter_vision-master/android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..6854aa529f
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/FlutterVisionPlugin.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/FlutterVisionPlugin.java
new file mode 100644
index 0000000000..5a71fa08af
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/FlutterVisionPlugin.java
@@ -0,0 +1,387 @@
+package com.vladih.computer_vision.flutter_vision;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+
+import androidx.annotation.NonNull;
+
+import com.vladih.computer_vision.flutter_vision.models.Tesseract;
+import com.vladih.computer_vision.flutter_vision.models.Yolo;
+import com.vladih.computer_vision.flutter_vision.models.Yolov8;
+import com.vladih.computer_vision.flutter_vision.models.Yolov5;
+import com.vladih.computer_vision.flutter_vision.models.Yolov8Seg;
+import com.vladih.computer_vision.flutter_vision.utils.utils;
+
+import org.opencv.android.OpenCVLoader;
+import org.opencv.android.Utils;
+import org.opencv.core.Mat;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
+import io.flutter.plugin.common.MethodChannel.Result;
+
+/**
+ * FlutterVisionPlugin
+ */
+public class FlutterVisionPlugin implements FlutterPlugin, MethodCallHandler {
+ private static final String CHANNEL_NAME = "flutter_vision";
+ private MethodChannel methodChannel;
+ private Context context;
+ private FlutterAssets assets;
+ private Yolo yolo_model;
+ private Tesseract tesseract_model;
+
+ private ExecutorService executor;
+
+ private boolean isDetecting = false;
+
+ private static ArrayList> empty = new ArrayList<>();
+
+ @Override
+ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
+ setupChannel(binding.getApplicationContext(), binding.getFlutterAssets(), binding.getBinaryMessenger());
+ }
+
+ @Override
+ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+ try {
+ this.context = null;
+ this.methodChannel.setMethodCallHandler(null);
+ this.methodChannel = null;
+ this.assets = null;
+ close_tesseract();
+ close_yolo();
+ this.executor.shutdownNow();
+ } catch (Exception e) {
+ if (!this.executor.isShutdown()) {
+ this.executor.shutdownNow();
+ }
+// System.out.println(e.getMessage());
+ }
+ }
+
+ private void setupChannel(Context context, FlutterAssets assets, BinaryMessenger messenger) {
+ OpenCVLoader.initDebug();
+ this.assets = assets;
+ this.context = context;
+ this.methodChannel = new MethodChannel(messenger, CHANNEL_NAME);
+ this.methodChannel.setMethodCallHandler(this);
+ this.executor = Executors.newSingleThreadExecutor();
+ }
+
+ @Override
+ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
+ // Handle method calls from Flutter
+ if (call.method.equals("loadOcrModel")) {
+ try {
+ load_ocr_model((Map) call.arguments);
+ } catch (Exception e) {
+ result.error("100", "Error on load ocr components", e);
+ }
+ } else if (call.method.equals("ocrOnFrame")) {
+ ocr_on_frame((Map) call.arguments, result);
+ } else if (call.method.equals("closeOcrModel")) {
+ close_ocr_model(result);
+ } else if (call.method.equals("loadYoloModel")) {
+ try {
+ load_yolo_model((Map) call.arguments);
+ result.success("ok");
+ } catch (Exception e) {
+ result.error("100", "Error on load Yolov5 model", e);
+ }
+ } else if (call.method.equals("yoloOnFrame")) {
+ yolo_on_frame((Map) call.arguments, result);
+ } else if (call.method.equals("yoloOnImage")) {
+ yolo_on_image((Map) call.arguments, result);
+ } else if (call.method.equals("closeYoloModel")) {
+ close_yolo_model(result);
+ } else if (call.method.equals("loadTesseractModel")) {
+ try {
+ load_tesseract_model((Map) call.arguments);
+ result.success("ok");
+ } catch (Exception e) {
+ result.error("100", "Error on load Tesseract model", e);
+ }
+ } else if (call.method.equals("tesseractOnImage")) {
+ tesseract_on_image((Map) call.arguments, result);
+ } else if (call.method.equals("closeTesseractModel")) {
+ close_tesseract_model(result);
+ } else {
+ result.notImplemented();
+ }
+ }
+
+ private void load_ocr_model(Map args) throws Exception {
+ load_yolo_model(args);
+ load_tesseract_model(args);
+ }
+
+ private void ocr_on_frame(Map args, Result result) {
+ try {
+ List image = (ArrayList) args.get("bytesList");
+ int image_height = (int) args.get("image_height");
+ int image_width = (int) args.get("image_width");
+ float iou_threshold = (float) (double) (args.get("iou_threshold"));
+ float conf_threshold = (float) (double) (args.get("conf_threshold"));
+ float class_threshold = (float) (double) (args.get("class_threshold"));
+ List class_is_text = (List) args.get("class_is_text");
+ Bitmap bitmap = utils.feedInputToBitmap(context.getApplicationContext(), image, image_height, image_width, 90);
+ int[] shape = yolo_model.getInputTensor().shape();
+ ByteBuffer byteBuffer = utils.feedInputTensor(bitmap, shape[1], shape[2], image_width, image_height, 0, 255);
+
+ List> yolo_results = yolo_model.detect_task(byteBuffer, image_height, image_width, iou_threshold, conf_threshold, class_threshold);
+ for (Map yolo_result : yolo_results) {
+ float[] box = (float[]) yolo_result.get("box");
+ if (class_is_text.contains((int) box[5])) {
+ Bitmap crop = utils.crop_bitmap(bitmap,
+ box[0], box[1], box[2], box[3]);
+ //utils.getScreenshotBmp(crop, "crop");
+ Bitmap tmp = crop.copy(crop.getConfig(), crop.isMutable());
+ yolo_result.put("text", tesseract_model.predict_text(tmp));
+ } else {
+ yolo_result.put("text", "");
+ }
+ }
+ result.success(yolo_results);
+ } catch (Exception e) {
+ result.error("100", "Ocr error", e);
+ }
+ }
+
+ private void close_ocr_model(Result result) {
+ try {
+ close_tesseract();
+ close_yolo();
+ result.success("OCR model closed succesfully");
+ } catch (Exception e) {
+ result.error("100", "Fail closed ocr model", e);
+ }
+ }
+
+ private void load_yolo_model(Map args) throws Exception {
+ final String model = this.assets.getAssetFilePathByName(args.get("model_path").toString());
+ final Object is_asset_obj = args.get("is_asset");
+ final boolean is_asset = is_asset_obj == null ? false : (boolean) is_asset_obj;
+ final int num_threads = (int) args.get("num_threads");
+ final boolean quantization = (boolean) args.get("quantization");
+ final boolean use_gpu = (boolean) args.get("use_gpu");
+ final String label_path = this.assets.getAssetFilePathByName(args.get("label_path").toString());
+ final int rotation = (int) args.get("rotation");
+ final String version = args.get("model_version").toString();
+ switch (version) {
+ case "yolov5": {
+ yolo_model = new Yolov5(
+ context,
+ model,
+ is_asset,
+ num_threads,
+ quantization,
+ use_gpu,
+ label_path,
+ rotation);
+ break;
+ }
+ case "yolov8": {
+ yolo_model = new Yolov8(
+ context,
+ model,
+ is_asset,
+ num_threads,
+ quantization,
+ use_gpu,
+ label_path,
+ rotation);
+ break;
+ }
+
+ case "yolov8seg": {
+ yolo_model = new Yolov8Seg(
+ context,
+ model,
+ is_asset,
+ num_threads,
+ quantization,
+ use_gpu,
+ label_path,
+ rotation);
+ break;
+ }
+ default: {
+ throw new Exception("Model version must be yolov5, yolov8 or yolov8seg");
+ }
+ }
+ yolo_model.initialize_model();
+ }
+
+ //https://www.baeldung.com/java-single-thread-executor-service
+ class DetectionTask implements Runnable {
+ // private static volatile DetectionTasks instance;
+ private Yolo yolo;
+ byte[] image;
+
+ List frame;
+ int image_height;
+ int image_width;
+ float iou_threshold;
+ float conf_threshold;
+ float class_threshold;
+
+ String typing;
+ private Result result;
+
+ public DetectionTask(Yolo yolo, Map args, String typing, Result result) {
+ this.typing = typing;
+ this.yolo = yolo;
+ if (typing == "img") {
+ this.image = (byte[]) args.get("bytesList");
+ } else {
+ this.frame = (ArrayList) args.get("bytesList");
+ }
+ this.image_height = (int) args.get("image_height");
+ this.image_width = (int) args.get("image_width");
+ this.iou_threshold = (float) (double) (args.get("iou_threshold"));
+ this.conf_threshold = (float) (double) (args.get("conf_threshold"));
+ this.class_threshold = (float) (double) (args.get("class_threshold"));
+ this.result = result;
+ }
+ @Override
+ public void run() {
+ try {
+ Bitmap bitmap;
+ if (typing == "img") {
+ bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
+ } else {
+ //rotate image, because android take a photo rotating 90 degrees
+ bitmap = utils.feedInputToBitmap(context, frame, image_height, image_width, 90);
+ }
+ int[] shape = yolo.getInputTensor().shape();
+ int src_width = bitmap.getWidth();
+ int src_height = bitmap.getHeight();
+ ByteBuffer byteBuffer = utils.feedInputTensor(bitmap, shape[1], shape[2], src_width, src_height, 0, 255);
+ List> detections = yolo.detect_task(byteBuffer, src_height, src_width, iou_threshold, conf_threshold, class_threshold);
+ isDetecting = false;
+ result.success(detections);
+ } catch (Exception e) {
+ result.error("100", "Detection Error", e);
+ }
+ }
+ }
+
+ private void yolo_on_frame(Map args, Result result) {
+ try {
+ if (isDetecting) {
+ result.success(empty);
+ } else {
+ isDetecting = true;
+ DetectionTask detectionTask = new DetectionTask(yolo_model, args, "frame", result);
+ executor.submit(detectionTask);
+ }
+ } catch (Exception e) {
+ result.error("100", "Detection Error", e);
+ }
+ }
+
+ private void yolo_on_image(Map args, Result result) {
+ try {
+ if (isDetecting) {
+ result.success(empty);
+ } else {
+ isDetecting = true;
+ DetectionTask detectionTask = new DetectionTask(yolo_model, args, "img", result);
+ executor.submit(detectionTask);
+ }
+ } catch (Exception e) {
+ result.error("100", "Detection Error", e);
+ }
+ }
+
+ private void close_yolo_model(Result result) {
+ try {
+ close_yolo();
+ result.success("Yolo model closed succesfully");
+ } catch (Exception e) {
+ result.error("100", "Close_yolo_model error", e);
+ }
+ }
+
+ private void load_tesseract_model(Map args) throws Exception {
+ final String tess_data = args.get("tess_data").toString();
+ final Map arg = (Map) args.get("arg");
+ final String language = args.get("language").toString();
+ tesseract_model = new Tesseract(tess_data, arg, language);
+ tesseract_model.initialize_model();
+ }
+
+ class PredictionTask implements Runnable {
+ private Tesseract tesseract;
+ private Bitmap bitmap;
+ private Result result;
+
+ public PredictionTask(Tesseract tesseract, Map args, Result result) {
+ byte[] image = (byte[]) args.get("bytesList");
+ this.tesseract = tesseract;
+ this.bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
+ this.result = result;
+ }
+
+ @Override
+ public void run() {
+ try {
+ Mat mat = utils.rgbBitmapToMatGray(bitmap);
+ double angle = utils.computeSkewAngle(mat.clone());
+ mat = utils.deskew(mat, angle);
+ mat = utils.filterTextFromImage(mat);
+ bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888);
+ Utils.matToBitmap(mat, bitmap);
+// utils.getScreenshotBmp(bitmap,"TESSEREACT");
+ result.success(tesseract.predict_text(bitmap));
+ } catch (Exception e) {
+ result.error("100", "Prediction text Error", e);
+ }
+ }
+ }
+
+ private void tesseract_on_image(Map args, Result result) {
+ try {
+ PredictionTask predictionTask = new PredictionTask(tesseract_model, args, result);
+ executor.submit(predictionTask);
+ } catch (Exception e) {
+ result.error("100", "Prediction Error", e);
+ }
+ }
+
+ private void close_tesseract_model(Result result) {
+ try {
+ close_tesseract();
+ result.success("Tesseract model closed succesfully");
+ } catch (Exception e) {
+ result.error("100", "close_tesseract_model error", e);
+ }
+ }
+
+ private void close_tesseract(){
+ if (tesseract_model != null) {
+ tesseract_model.close();
+ tesseract_model = null;
+ }
+ }
+
+ private void close_yolo(){
+ if (yolo_model != null) {
+ yolo_model.close();
+ yolo_model = null;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Tesseract.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Tesseract.java
new file mode 100644
index 0000000000..9a7bc46875
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Tesseract.java
@@ -0,0 +1,78 @@
+package com.vladih.computer_vision.flutter_vision.models;
+
+import android.graphics.Bitmap;
+
+import com.googlecode.tesseract.android.TessBaseAPI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+public class Tesseract {
+ private TessBaseAPI interpreter;
+ private final int default_page_seg_mode = TessBaseAPI.PageSegMode.PSM_SINGLE_BLOCK;
+ private final String tess_data;
+ private final Map arg;
+ private final String language;
+
+ public Tesseract(String tess_data, Map arg, String language) {
+ this.tess_data = tess_data;
+ this.arg = arg;
+ this.language = language;
+ }
+ public void close(){
+ if (interpreter!=null){
+ interpreter.clear();
+ interpreter.recycle();
+ }
+ }
+ public void initialize_model() throws Exception {
+ try {
+ if(interpreter==null){
+ this.interpreter = new TessBaseAPI();
+ if (!this.interpreter.init(this.tess_data, this.language)) {
+ // Error initializing Tesseract (wrong data path or language)
+ this.interpreter.recycle();
+ throw new Exception("Cannot initialize Tesseract model");
+ }
+ if(!this.arg.isEmpty()){
+ for(Map.Entry entry:this.arg.entrySet()){
+ interpreter.setVariable(entry.getKey(),entry.getValue());
+ }
+ }
+ interpreter.setPageSegMode(this.default_page_seg_mode);
+ }
+ }
+ catch (Exception e){
+ throw e;
+ }
+ }
+
+ public Map predict_text(Bitmap bitmap) throws Exception {
+ try{
+ this.interpreter.setImage(bitmap);
+ String result = this.interpreter.getUTF8Text();
+ return out(result, interpreter.meanConfidence(), interpreter.wordConfidences());
+ }catch (Exception e){
+ throw new Exception(e.getMessage());
+ }finally {
+ if(!bitmap.isRecycled()){
+ bitmap.recycle();
+ }
+ }
+ }
+
+ protected Map out(String text, int mean, int[] word_conf){
+ try {
+ Map result = new HashMap();
+ result.put("text",text);
+ result.put("mean_conf", mean);
+ result.put("word_conf",word_conf);
+ return result;
+ }catch (Exception e){
+ throw e;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolo.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolo.java
new file mode 100644
index 0000000000..97d62548eb
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolo.java
@@ -0,0 +1,320 @@
+package com.vladih.computer_vision.flutter_vision.models;
+
+import static java.lang.Math.min;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.util.Log;
+
+import com.vladih.computer_vision.flutter_vision.utils.FeedInputTensorHelper;
+
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.tensorflow.lite.Interpreter;
+import org.tensorflow.lite.Tensor;
+import org.tensorflow.lite.gpu.CompatibilityList;
+import org.tensorflow.lite.gpu.GpuDelegate;
+import org.tensorflow.lite.gpu.GpuDelegateFactory;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+
+public class Yolo {
+ protected float[][][] output;
+ protected Interpreter interpreter;
+ protected Vector labels;
+ protected final Context context;
+ protected final String model_path;
+ protected final boolean is_assets;
+ protected final int num_threads;
+ protected final boolean quantization;
+ protected final boolean use_gpu;
+ protected final String label_path;
+ protected final int rotation;
+
+ public Yolo(Context context,
+ String model_path,
+ boolean is_assets,
+ int num_threads,
+ boolean quantization,
+ boolean use_gpu,
+ String label_path,
+ int rotation) {
+ this.context = context;
+ this.model_path = model_path;
+ this.is_assets = is_assets;
+ this.num_threads = num_threads;
+ this.quantization = quantization;
+ this.use_gpu = use_gpu;
+ this.label_path = label_path;
+ this.rotation = rotation;
+ }
+
+ // public Vector getLabels(){return this.labels;}
+ public Tensor getInputTensor() {
+ return this.interpreter.getInputTensor(0);
+ }
+
+ @SuppressLint("SuspiciousIndentation")
+ public void initialize_model() throws Exception {
+ AssetManager asset_manager = null;
+ MappedByteBuffer buffer = null;
+ FileChannel file_channel = null;
+ FileInputStream input_stream = null;
+
+ try {
+ if (is_assets) {
+ asset_manager = context.getAssets();
+ AssetFileDescriptor file_descriptor = asset_manager.openFd(this.model_path);
+ input_stream = new FileInputStream(file_descriptor.getFileDescriptor());
+
+ file_channel = input_stream.getChannel();
+ buffer = file_channel.map(
+ FileChannel.MapMode.READ_ONLY, file_descriptor.getStartOffset(),
+ file_descriptor.getLength()
+ );
+ file_descriptor.close();
+ } else {
+ input_stream = new FileInputStream(new File(this.model_path));
+ file_channel = input_stream.getChannel();
+ buffer = file_channel.map(FileChannel.MapMode.READ_ONLY, 0, file_channel.size());
+ }
+
+ Interpreter.Options interpreterOptions = new Interpreter.Options();
+ try {
+ // Check if GPU support is available
+ CompatibilityList compatibilityList = new CompatibilityList();
+ if (use_gpu && compatibilityList.isDelegateSupportedOnThisDevice()) {
+ GpuDelegateFactory.Options delegateOptions = compatibilityList.getBestOptionsForThisDevice();
+ GpuDelegate gpuDelegate = new GpuDelegate(delegateOptions.setQuantizedModelsAllowed(this.quantization));
+ interpreterOptions.addDelegate(gpuDelegate);
+ } else {
+ interpreterOptions.setNumThreads(num_threads);
+ }
+ // Create the interpreter
+ this.interpreter = new Interpreter(buffer, interpreterOptions);
+ } catch (Exception e) {
+ interpreterOptions = new Interpreter.Options();
+ interpreterOptions.setNumThreads(num_threads);
+ // Create the interpreter
+ this.interpreter = new Interpreter(buffer, interpreterOptions);
+ }
+ this.interpreter.allocateTensors();
+ this.labels = load_labels(asset_manager, label_path);
+ int[] shape = interpreter.getOutputTensor(0).shape();//3dimension
+ this.output = (float [][][]) Array.newInstance(float.class, shape);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ if (buffer != null)
+ buffer.clear();
+ if (file_channel != null && file_channel.isOpen()) {
+ file_channel.close();
+ input_stream.close();
+ }
+ }
+ }
+
+ protected Vector load_labels(AssetManager asset_manager, String label_path) throws Exception {
+ BufferedReader br = null;
+ try {
+ if (asset_manager != null) {
+ br = new BufferedReader(new InputStreamReader(asset_manager.open(label_path)));
+ } else {
+ br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(label_path))));
+ }
+ String line;
+ Vector labels = new Vector<>();
+ while ((line = br.readLine()) != null) {
+ labels.add(line);
+ }
+ return labels;
+ } catch (Exception e) {
+ throw new Exception(e.getMessage());
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+
+ public List> detect_task(ByteBuffer byteBuffer,
+ int source_height,
+ int source_width,
+ float iou_threshold,
+ float conf_threshold, float class_threshold) throws Exception {
+ try {
+ int[] input_shape = this.interpreter.getInputTensor(0).shape();
+ this.interpreter.run(byteBuffer, this.output);
+ List boxes = filter_box(this.output, iou_threshold, conf_threshold,
+ class_threshold, input_shape[1], input_shape[2]);
+ boxes = restore_size(boxes, input_shape[1], input_shape[2], source_width, source_height);
+ return out(boxes, this.labels);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ byteBuffer.clear();
+ }
+ }
+
+ protected List filter_box(float[][][] model_outputs, float iou_threshold,
+ float conf_threshold, float class_threshold, float input_width, float input_height) {
+ try {
+ //model_outputs = [1,box+model_conf+class,detected_box]
+ List pre_box = new ArrayList<>();
+ int conf_index = 4;
+ int class_index = 5;
+ int dimension = model_outputs[0][0].length;
+ int rows = model_outputs[0].length;
+ float x1, y1, x2, y2, conf;
+ int max_index = 0;
+ float max = 0f;
+ for (int i = 0; i < rows; i++) {
+ //convert xywh to xyxy
+ x1 = (model_outputs[0][i][0] - model_outputs[0][i][2] / 2f) * input_width;
+ y1 = (model_outputs[0][i][1] - model_outputs[0][i][3] / 2f) * input_height;
+ x2 = (model_outputs[0][i][0] + model_outputs[0][i][2] / 2f) * input_width;
+ y2 = (model_outputs[0][i][1] + model_outputs[0][i][3] / 2f) * input_height;
+ conf = model_outputs[0][i][conf_index];
+ if (conf < conf_threshold) continue;
+
+ max_index = class_index;
+ max = model_outputs[0][i][max_index];
+
+ for (int j = class_index + 1; j < dimension; j++) {
+ float current = model_outputs[0][i][j];
+ if (current > max) {
+ max = current;
+ max_index = j;
+ }
+ }
+ if (max > class_threshold){
+ float[] tmp = new float[6];
+ tmp[0] = x1;
+ tmp[1] = y1;
+ tmp[2] = x2;
+ tmp[3] = y2;
+ tmp[4] = model_outputs[0][i][max_index];
+ tmp[5] = (max_index - class_index) * 1f;
+ pre_box.add(tmp);
+ }
+ }
+ if (pre_box.isEmpty()) return new ArrayList<>();
+ //for reverse orden, insteand of using .reversed method
+ Comparator compareValues = (v1, v2) -> Float.compare(v2[4], v1[4]);
+ //Collections.sort(pre_box,compareValues.reversed());
+ Collections.sort(pre_box, compareValues);
+ return nms(pre_box, iou_threshold);
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ protected static List nms(List boxes, float iou_threshold) {
+ try {
+ List filteredBoxes = new ArrayList<>(boxes); // Create a copy of the input list
+
+ for (int i = 0; i < filteredBoxes.size(); i++) {
+ float[] box = filteredBoxes.get(i);
+ for (int j = i + 1; j < filteredBoxes.size(); j++) {
+ float[] next_box = filteredBoxes.get(j);
+ float x1 = Math.max(next_box[0], box[0]);
+ float y1 = Math.max(next_box[1], box[1]);
+ float x2 = Math.min(next_box[2], box[2]);
+ float y2 = Math.min(next_box[3], box[3]);
+
+ float width = Math.max(0, x2 - x1);
+ float height = Math.max(0, y2 - y1);
+
+ float intersection = width * height;
+ float union = (next_box[2] - next_box[0]) * (next_box[3] - next_box[1])
+ + (box[2] - box[0]) * (box[3] - box[1]) - intersection;
+ float iou = intersection / union;
+ if (iou > iou_threshold) {
+ filteredBoxes.remove(j);
+ j--;
+ }
+ }
+ }
+ return filteredBoxes;
+ } catch (Exception e) {
+ Log.e("nms", e.getMessage());
+ throw e;
+ }
+ }
+
+ protected List restore_size(List nms,
+ int input_width,
+ int input_height,
+ int src_width,
+ int src_height) {
+ try {
+ //restore size after scaling, larger images
+ if (src_width > input_width || src_height > input_height) {
+ float gainx = src_width / (float) input_width;
+ float gainy = src_height / (float) input_height;
+ for (int i = 0; i < nms.size(); i++) {
+ nms.get(i)[0] = min(src_width, Math.max(nms.get(i)[0] * gainx, 0));
+ nms.get(i)[1] = min(src_height, Math.max(nms.get(i)[1] * gainy, 0));
+ nms.get(i)[2] = min(src_width, Math.max(nms.get(i)[2] * gainx, 0));
+ nms.get(i)[3] = min(src_height, Math.max(nms.get(i)[3] * gainy, 0));
+ }
+ //restore size after padding, smaller images
+ } else {
+ float padx = (src_width - input_width) / 2f;
+ float pady = (src_height - input_height) / 2f;
+ for (int i = 0; i < nms.size(); i++) {
+ nms.get(i)[0] = min(src_width, Math.max(nms.get(i)[0] + padx, 0));
+ nms.get(i)[1] = min(src_height, Math.max(nms.get(i)[1] + pady, 0));
+ nms.get(i)[2] = min(src_width, Math.max(nms.get(i)[2] + padx, 0));
+ nms.get(i)[3] = min(src_height, Math.max(nms.get(i)[3] + pady, 0));
+ }
+ }
+ return nms;
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ protected List> out(List yolo_result, Vector labels) {
+ try {
+ List> result = new ArrayList<>();
+ //utils.getScreenshotBmp(bitmap, "current");
+ for (float[] box : yolo_result) {
+ Map output = new HashMap<>();
+ output.put("box", new float[]{box[0], box[1], box[2], box[3], box[4]}); //x1,y1,x2,y2,conf_class
+ output.put("tag", labels.get((int) box[5]));
+ result.add(output);
+ }
+ return result;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ public void close() {
+ try {
+ if (interpreter != null)
+ interpreter.close();
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov5.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov5.java
new file mode 100644
index 0000000000..82ecdb5de5
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov5.java
@@ -0,0 +1,34 @@
+package com.vladih.computer_vision.flutter_vision.models;
+
+import static java.lang.Math.min;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.util.Log;
+
+import org.tensorflow.lite.Interpreter;
+import org.tensorflow.lite.gpu.CompatibilityList;
+import org.tensorflow.lite.gpu.GpuDelegate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class Yolov5 extends Yolo{
+ public Yolov5(Context context,
+ String model_path,
+ boolean is_assets,
+ int num_threads,
+ boolean quantization,
+ boolean use_gpu,
+ String label_path,
+ int rotation) {
+ super(context, model_path, is_assets, num_threads, quantization, use_gpu, label_path, rotation);
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8.java
new file mode 100644
index 0000000000..cfe89c9cad
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8.java
@@ -0,0 +1,141 @@
+package com.vladih.computer_vision.flutter_vision.models;
+
+import static java.lang.Math.min;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.util.Log;
+
+import com.vladih.computer_vision.flutter_vision.utils.utils;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.imgproc.Imgproc;
+import org.tensorflow.lite.Interpreter;
+import org.tensorflow.lite.gpu.CompatibilityList;
+import org.tensorflow.lite.gpu.GpuDelegate;
+import org.tensorflow.lite.schema.Buffer;
+import org.tensorflow.lite.schema.ReshapeOptions;
+import org.tensorflow.lite.support.image.ImageProcessor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Vector;
+
+public class Yolov8 extends Yolo {
+ public Yolov8(Context context,
+ String model_path,
+ boolean is_assets,
+ int num_threads,
+ boolean quantization,
+ boolean use_gpu,
+ String label_path,
+ int rotation) {
+ super(context, model_path, is_assets, num_threads, quantization, use_gpu, label_path, rotation);
+ }
+
+ @Override
+ public List> detect_task(ByteBuffer byteBuffer,
+ int source_height,
+ int source_width,
+ float iou_threshold,
+ float conf_threshold,
+ float class_threshold) throws Exception {
+ try {
+ int[] input_shape = this.interpreter.getInputTensor(0).shape();
+ this.interpreter.run(byteBuffer, this.output);
+ //INFO: output from detection model is not normalized
+ List boxes = filter_box(this.output, iou_threshold, conf_threshold,
+ class_threshold, input_shape[1], input_shape[2]);
+ boxes = restore_size(boxes, input_shape[1], input_shape[2], source_width, source_height);
+ return out(boxes, this.labels);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ byteBuffer.clear();
+ }
+ }
+
+ @Override
+ protected List filter_box(float[][][] model_outputs, float iou_threshold,
+ float conf_threshold, float class_threshold, float input_width, float input_height) {
+ try {
+ //model_outputs = [1,box+class,detected_box]
+ List pre_box = new ArrayList<>();
+ int class_index = 4;
+ int dimension = model_outputs[0][0].length;
+ int rows = model_outputs[0].length;
+ int max_index = 0;
+ float max = 0f;
+ for (int i = 0; i < dimension; i++) {
+ float x1 = (model_outputs[0][0][i] - model_outputs[0][2][i] / 2f)* input_width;
+ float y1 = (model_outputs[0][1][i] - model_outputs[0][3][i] / 2f)* input_height;
+ float x2 = (model_outputs[0][0][i] + model_outputs[0][2][i] / 2f)* input_width;
+ float y2 = (model_outputs[0][1][i] + model_outputs[0][3][i] / 2f)* input_height;
+
+ max_index = class_index;
+ max = model_outputs[0][max_index][i];
+
+ for (int j = class_index + 1; j < rows; j++) {
+ float current = model_outputs[0][j][i];
+ if (current > max) {
+ max = current;
+ max_index = j;
+ }
+ }
+
+ if (max > class_threshold) {
+ float[] tmp = new float[6];
+ tmp[0] = x1;
+ tmp[1] = y1;
+ tmp[2] = x2;
+ tmp[3] = y2;
+ tmp[4] = max;
+ tmp[5] = (max_index - class_index) * 1f;
+ pre_box.add(tmp);
+ }
+ }
+ if (pre_box.isEmpty()) return new ArrayList<>();
+ //for reverse orden, insteand of using .reversed method
+ Comparator compareValues = (v1, v2) -> Float.compare(v2[4], v1[4]);
+ //Collections.sort(pre_box,compareValues.reversed());
+ Collections.sort(pre_box, compareValues);
+ return nms(pre_box, iou_threshold);
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ @Override
+ protected List> out(List yolo_result, Vector labels) {
+ try {
+ List> result = new ArrayList<>();
+ for (float[] box : yolo_result) {
+ Map output = new HashMap<>();
+ output.put("box", new float[]{box[0], box[1], box[2], box[3], box[4]}); //x1,y1,x2,y2,conf_class
+ output.put("tag", labels.get((int) box[5]));
+ result.add(output);
+ }
+ return result;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8Seg.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8Seg.java
new file mode 100644
index 0000000000..b64f3e1bfe
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/models/Yolov8Seg.java
@@ -0,0 +1,303 @@
+package com.vladih.computer_vision.flutter_vision.models;
+
+import static java.lang.Math.min;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.util.Log;
+
+import com.vladih.computer_vision.flutter_vision.utils.utils;
+
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.imgproc.Imgproc;
+import org.tensorflow.lite.Interpreter;
+import org.tensorflow.lite.gpu.CompatibilityList;
+import org.tensorflow.lite.gpu.GpuDelegate;
+import org.tensorflow.lite.schema.Buffer;
+import org.tensorflow.lite.schema.ReshapeOptions;
+import org.tensorflow.lite.support.image.ImageProcessor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Vector;
+
+//https://dev.to/andreygermanov/how-to-implement-instance-segmentation-using-yolov8-neural-network-3if9
+//PAPER: https://openaccess.thecvf.com/content_ICCV_2019/papers/Bolya_YOLACT_Real-Time_Instance_Segmentation_ICCV_2019_paper.pdf
+public class Yolov8Seg extends Yolo {
+ public Yolov8Seg(Context context,
+ String model_path,
+ boolean is_assets,
+ int num_threads,
+ boolean quantization,
+ boolean use_gpu,
+ String label_path,
+ int rotation) {
+ super(context, model_path, is_assets, num_threads, quantization, use_gpu, label_path, rotation);
+ }
+
+ @Override
+ public List> detect_task(ByteBuffer byteBuffer,
+ int source_height,
+ int source_width,
+ float iou_threshold,
+ float conf_threshold,
+ float class_threshold) {
+ try {
+ if (has_multiple_output()) {
+ Map outputs = new HashMap<>();
+ for (int i = 0; i < interpreter.getOutputTensorCount(); i++) {
+ int[] shape = interpreter.getOutputTensor(i).shape();
+ outputs.put(i, Array.newInstance(float.class, shape));
+ }
+ Object[] inputs = {byteBuffer};
+ this.interpreter.runForMultipleInputsOutputs(inputs, outputs);
+
+ int[] input_shape = interpreter.getInputTensor(0).shape(); // 1, 640, 640
+ int[] output0_shape = interpreter.getOutputTensor(0).shape(); //1,116,2184
+ int[] output1_shape = interpreter.getOutputTensor(1).shape(); //1,160,160,32
+
+ float[][][] output0 = (float[][][]) outputs.get(0);
+
+ //seg_boxes = coordinates[4]+classes[x=84]+masks_weight[32]
+ //INFO: output from segment model return normalized values
+ List seg_boxes = filter_box(output0,
+ iou_threshold, conf_threshold, class_threshold,
+ input_shape[1], input_shape[2]);
+
+ output0 = null;
+
+ //it only restores the size of the boxes, nothing has been done with mask_weight
+ seg_boxes = restore_size(seg_boxes, input_shape[1], input_shape[2],
+ source_width, source_height);
+
+ float[][][][] masks = (float[][][][]) outputs.get(1);
+ List seg_boxes_mask = new ArrayList<>();
+ for (float[] mask_weight : seg_boxes) {
+ seg_boxes_mask.add(compute_mask(mask_weight,
+ masks[0], (float) 0.3,
+ output1_shape[1], output1_shape[2]));
+ }
+ masks = null;
+ List>> restore_seg_mask = restore_seg_mask_size(seg_boxes,
+ seg_boxes_mask, output1_shape[1], output1_shape[2], source_height, source_width
+ );
+ return out_segmentation(seg_boxes, restore_seg_mask, this.labels);
+ } else {
+ throw new ExceptionInInitializerError("tflite model should have two outputs in segmentation mode");
+ }
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ byteBuffer.clear();
+ }
+ }
+
+ private int[] compute_mask(float[] mask_weight,
+ float[][][] masks_protos,
+ float seg_thresh,
+ int mask_height,
+ int mask_width) {
+ int prefix_box = 6;
+ int numMask = mask_weight.length - prefix_box;
+ int[] masks = new int[mask_height * mask_width];
+ int index = 0;
+ // Set all pixels to either white (255) or black (0)
+ for (int h = 0; h < mask_height; h++) {
+ for (int w = 0; w < mask_width; w++) {
+ float sum = 0.0f;
+ for (int j = 0; j < numMask; j++) {
+ sum += mask_weight[j + prefix_box] * masks_protos[h][w][j];
+ }
+ if (sigmoid(sum) > seg_thresh) {
+ masks[index++] = Color.WHITE;
+ } else {
+ masks[index++] = Color.BLACK;
+ }
+ }
+// System.out.println();
+ }
+// Bitmap bitmap =Bitmap.createBitmap(masks, maskHeight, maskWidth, Bitmap.Config.ARGB_8888);
+// utils.getScreenshotBmp(bitmap, UUID.randomUUID().toString());
+ return masks;
+ }
+
+ float sigmoid(float x) {
+ return (float) (1.0 / (1.0 + Math.exp(-x)));
+ }
+
+ private List>> restore_seg_mask_size(List boxes, List seg_mask,
+ int mask_height, int mask_width,
+ int source_height, int source_width) {
+ Bitmap bitmap = null;
+ Bitmap crop = null;
+ try {
+ List>> polygons = new ArrayList<>();
+ for (int i = 0; i < boxes.size(); i++) {
+ // Set the pixel data from the flattened array
+ bitmap = Bitmap.createBitmap(seg_mask.get(i), mask_width, mask_height, Bitmap.Config.ARGB_8888);
+// String tag = UUID.randomUUID().toString();
+// utils.getScreenshotBmp(bitmap, tag+"0");
+ crop = utils.crop_bitmap(bitmap,
+ min(mask_width, Math.max(boxes.get(i)[0] * mask_width / source_width, 0)),
+ min(mask_height, Math.max(boxes.get(i)[1] * mask_height / source_height, 0)),
+ min(mask_width, Math.max(boxes.get(i)[2] * mask_width / source_width, 0)),
+ min(mask_height, Math.max(boxes.get(i)[3] * mask_height / source_height, 0))
+ );
+// utils.getScreenshotBmp(crop, tag+"1");
+ List> crop_polygon = get_polygons_from_bitmap(crop, mask_height,
+ mask_width, source_height, source_width);
+ polygons.add(crop_polygon);
+ }
+ return polygons;
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ if (bitmap != null) bitmap.recycle();
+ if (crop != null) crop.recycle();
+ }
+ }
+
+ public static List> get_polygons_from_bitmap(Bitmap mask,
+ int mask_height,
+ int mask_width,
+ int source_height,
+ int source_width) {
+ Mat maskMat = utils.rgbBitmapToMatGray(mask); // Convert Bitmap to Mat
+ List contours = new ArrayList<>();
+ Imgproc.findContours(maskMat, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
+
+ MatOfPoint largestContour = null;
+ double largestArea = 0;
+
+ for (MatOfPoint contour : contours) {
+ double area = Imgproc.contourArea(contour);
+ if (area > largestArea) {
+ largestArea = area;
+ largestContour = contour;
+ }
+ }
+ List polygon = new ArrayList<>(largestContour.toList());
+// List> polygons = new ArrayList<>();
+// for (MatOfPoint contour : contours) {
+// List polygon = new ArrayList<>();
+// for (Point point : contour.toList()) {
+// polygon.add(point);
+// }
+// polygons.add(polygon);
+// }
+// List>> converted_polygons = new ArrayList<>();
+
+// for (List polygon : polygons) {
+ List> convertedPolygon = new ArrayList<>();
+ for (Point point : polygon) {
+ Map pointMap = new HashMap<>();
+ pointMap.put("x", point.x * source_width / mask_width);
+ pointMap.put("y", point.y * source_height / mask_height);
+ convertedPolygon.add(pointMap);
+ }
+// converted_polygons.add(convertedPolygon);
+// }
+// return converted_polygons;
+ return convertedPolygon;
+ }
+
+ private boolean has_multiple_output() {
+ return this.interpreter.getOutputTensorCount() > 1;
+ }
+
+ @Override
+ protected List filter_box(float[][][] model_outputs, float iou_threshold,
+ float conf_threshold, float class_threshold,
+ float input_width, float input_height) {
+ try {
+ //model_outputs = [1,box+class+mask_weight,detected_box]
+ List pre_box = new ArrayList<>();
+ int class_index = 4;
+ int dimension = model_outputs[0][0].length;
+ int rows = model_outputs[0].length;
+ int index_mask = rows - 32;
+ float[] mask_weight = new float[32];
+ int max_index = 0;
+ float max = 0f;
+ for (int i = 0; i < dimension; i++) {
+ // Convertir xywh a xyxy y ajustar por el ancho y alto de entrada
+ float x1 = (model_outputs[0][0][i] - model_outputs[0][2][i] / 2f) * input_width;
+ float y1 = (model_outputs[0][1][i] - model_outputs[0][3][i] / 2f) * input_height;
+ float x2 = (model_outputs[0][0][i] + model_outputs[0][2][i] / 2f) * input_width;
+ float y2 = (model_outputs[0][1][i] + model_outputs[0][3][i] / 2f) * input_height;
+
+ max_index = class_index;
+ max = model_outputs[0][max_index][i];
+
+ for (int j = class_index + 1; j < index_mask; j++) {
+ float current = model_outputs[0][j][i];
+ if (current > max) {
+ max = current;
+ max_index = j;
+ }
+ }
+
+ if (max > class_threshold) {
+ float[] tmp = new float[38];
+ tmp[0] = x1;
+ tmp[1] = y1;
+ tmp[2] = x2;
+ tmp[3] = y2;
+ tmp[4] = max;
+ tmp[5] = (max_index - class_index) * 1f;
+ for (int j = index_mask; j < rows; j++) {
+ tmp[j - index_mask + 6] = model_outputs[0][j][i];
+ }
+ pre_box.add(tmp);
+ }
+ }
+ if (pre_box.isEmpty()) return new ArrayList<>();
+ //for reverse orden, insteand of using .reversed method
+ Comparator compareValues = (v1, v2) -> Float.compare(v2[4], v1[4]);
+ //Collections.sort(pre_box,compareValues.reversed());
+ Collections.sort(pre_box, compareValues);
+ return nms(pre_box, iou_threshold);
+// return nms_segmentation(pre_box, iou_threshold);
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ //ignore out method of super class
+ protected List> out_segmentation(List yolo_result,
+ List>> polygons,
+ Vector labels) {
+ try {
+ List> result = new ArrayList<>();
+ for (int i = 0; i < yolo_result.size(); i++) {
+ Map output = new HashMap<>();
+ output.put("box", new float[]{yolo_result.get(i)[0], yolo_result.get(i)[1],
+ yolo_result.get(i)[2], yolo_result.get(i)[3], yolo_result.get(i)[4]}); //x1,y1,x2,y2,conf_class
+ output.put("polygons", polygons.get(i));
+ output.put("tag", labels.get((int) yolo_result.get(i)[5]));
+ result.add(output);
+ }
+ return result;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/FeedInputTensorHelper.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/FeedInputTensorHelper.java
new file mode 100644
index 0000000000..e940d4e624
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/FeedInputTensorHelper.java
@@ -0,0 +1,72 @@
+package com.vladih.computer_vision.flutter_vision.utils;
+
+import android.graphics.Bitmap;
+
+import com.googlecode.leptonica.android.Scale;
+
+import org.tensorflow.lite.DataType;
+import org.tensorflow.lite.support.common.ops.NormalizeOp;
+import org.tensorflow.lite.support.image.ImageProcessor;
+import org.tensorflow.lite.support.image.TensorImage;
+import org.tensorflow.lite.support.image.ops.ResizeOp;
+import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp;
+
+public class FeedInputTensorHelper {
+ private static FeedInputTensorHelper instance;
+ private TensorImage tensorImage;
+ private ImageProcessor downSizeImageProcessor;
+ private ImageProcessor upSizeImageProcessor;
+
+ private int previus_width = 0;
+ private int previus_height = 0;
+ private FeedInputTensorHelper(int width, int height, float mean, float std) {
+ previus_width = width;
+ previus_height = height;
+ tensorImage = new TensorImage(DataType.FLOAT32);
+ downSizeImageProcessor =
+ new ImageProcessor.Builder()
+ // Resize using Bilinear or Nearest neighbour
+ .add(new ResizeOp(height, width, ResizeOp.ResizeMethod.BILINEAR))
+ // Rotation counter-clockwise in 90 degree increments
+// .add(new Rot90Op(rotateDegrees / 90))
+ .add(new NormalizeOp(mean, std))
+// .add(new QuantizeOp(128.0, 1/128.0))
+ .build();
+ upSizeImageProcessor =
+ new ImageProcessor.Builder()
+ // Center crop the image to the largest square possible
+ .add(new ResizeWithCropOrPadOp(height, width))
+ .add(new NormalizeOp(mean, std))
+ .build();
+ }
+
+ public static synchronized FeedInputTensorHelper getInstance(int width, int height, float mean, float std) {
+ if (instance == null) {
+ instance = new FeedInputTensorHelper(width, height,mean, std);
+ }else{
+ if (instance.previus_width!=width || instance.previus_height!=height){
+ instance = new FeedInputTensorHelper(width, height,mean, std);
+ }
+ }
+ return instance;
+ }
+
+ public static TensorImage getBytebufferFromBitmap(Bitmap bitmap,
+ int input_width,
+ int input_height, float mean, float std, String size_option) throws Exception {
+ try{
+ //https://www.tensorflow.org/lite/inference_with_metadata/lite_support
+ FeedInputTensorHelper feedInputTensorHelper = getInstance(input_width, input_height, mean, std);
+ feedInputTensorHelper.tensorImage.load(bitmap);
+ if (size_option=="downsize"){
+ return feedInputTensorHelper.downSizeImageProcessor.process(feedInputTensorHelper.tensorImage);
+ }
+ if (size_option=="upsize"){
+ return feedInputTensorHelper.upSizeImageProcessor.process(feedInputTensorHelper.tensorImage);
+ }
+ throw new Exception("internal error, size_option no supported");
+ }catch (Exception e){
+ throw e;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/RenderScriptHelper.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/RenderScriptHelper.java
new file mode 100644
index 0000000000..2cf0a18aff
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/RenderScriptHelper.java
@@ -0,0 +1,67 @@
+package com.vladih.computer_vision.flutter_vision.utils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptIntrinsicYuvToRGB;
+import android.renderscript.Type;
+
+public class RenderScriptHelper {
+ private static RenderScriptHelper instance;
+
+ private RenderScript rs;
+ private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
+ private Type.Builder yuvType;
+ private Type.Builder rgbaType;
+ private Allocation in;
+ private Allocation out;
+
+ private RenderScriptHelper(Context context) {
+ rs = RenderScript.create(context);
+ yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
+ }
+
+ public static synchronized RenderScriptHelper getInstance(Context context) {
+ if (instance == null) {
+ instance = new RenderScriptHelper(context);
+ }
+ return instance;
+ }
+
+ public Allocation renderScriptNV21ToRGBA888(int width, int height, byte[] nv21) {
+ if (yuvType == null) {
+ yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length);
+ }
+ if (rgbaType == null) {
+ rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
+ }
+ // Create input allocation for YUV data
+ if (in == null) {
+ in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
+ }
+ // Create output allocation for RGBA data
+ if (out == null) {
+ out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
+ }
+
+ // Convert YUV to RGBA using RenderScript intrinsic
+ in.copyFrom(nv21);
+ yuvToRgbIntrinsic.setInput(in);
+ yuvToRgbIntrinsic.forEach(out);
+ return out;
+ }
+
+ public static Bitmap getBitmapFromNV21(Context context, byte[] nv21, int width, int height) {
+ RenderScriptHelper rsHelper = getInstance(context);
+ //https://blog.minhazav.dev/how-to-convert-yuv-420-sp-android.media.Image-to-Bitmap-or-jpeg/
+ Allocation allocation = rsHelper.renderScriptNV21ToRGBA888(width, height, nv21);
+
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ allocation.copyTo(bitmap);
+
+ return bitmap;
+ }
+}
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/utils.java b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/utils.java
new file mode 100644
index 0000000000..d629ac4fe5
--- /dev/null
+++ b/frontend/flutter_vision-master/android/src/main/java/com/vladih/computer_vision/flutter_vision/utils/utils.java
@@ -0,0 +1,345 @@
+package com.vladih.computer_vision.flutter_vision.utils;
+import static java.lang.Math.min;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.os.Environment;
+
+import org.opencv.android.Utils;
+import org.opencv.core.Core;
+import org.opencv.core.CvType;
+import org.opencv.core.Mat;
+import org.opencv.core.MatOfFloat;
+import org.opencv.core.MatOfPoint;
+import org.opencv.core.Point;
+import org.opencv.core.Rect;
+import org.opencv.core.Scalar;
+import org.opencv.core.Size;
+import org.opencv.imgproc.Imgproc;
+import org.opencv.photo.Photo;
+import org.tensorflow.lite.support.image.TensorImage;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class utils {
+ public static Bitmap crop_bitmap(Bitmap bitmap, float x1, float y1, float x2, float y2) {
+ try{
+ final int x = Math.max((int)x1,0);
+ final int y = Math.max((int)y1,0);
+ final int width = Math.abs((int)(x2-x1));
+ final int height = Math.abs((int)(y2-y1));
+ return Bitmap.createBitmap(bitmap,x,y,width,height);
+ }catch (Exception e){
+ throw e;
+ }
+ }
+ public static byte[] bitmap_to_byte(Bitmap bitmap){
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
+ return stream.toByteArray();
+ }
+ public static Bitmap getScreenshotBmp(Bitmap bitmap, String name) {
+ FileOutputStream fileOutputStream = null;
+
+ File path = Environment
+ .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+
+ String uniqueID = name;
+
+ File file = new File(path, uniqueID + ".jpg");
+ try {
+ fileOutputStream = new FileOutputStream(file);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
+
+ try {
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return bitmap;
+ }
+ //These code lines work well but is so slower, now rename as filterTextFromImage
+// public static Mat image_preprocessing(Mat mat){
+// try {
+// Photo.fastNlMeansDenoising(mat,mat, new MatOfFloat(7),3,21, Core.NORM_L1);
+// Core.normalize(mat,mat, 0, 255, Core.NORM_MINMAX);
+// Imgproc.GaussianBlur(mat, mat, new Size(5,5), 1);
+// Imgproc.adaptiveThreshold(mat,mat,255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,Imgproc.THRESH_BINARY,21,15);
+// return mat;
+// }catch (Exception e){
+// throw e;
+// }
+// }
+ //Accept gray Mat
+ public static Mat filterTextFromImage(Mat mat){
+ try {
+ //find posibles box text
+ List rects = findRects(mat);
+ //join posibles box text that belong to same horizontal line
+ rects = mergeRects(rects);
+ //remove boxes which belong to another
+ rects = non_max_suppression(rects);
+
+ Mat new_image = new Mat(mat.height(), mat.width(), CvType.CV_8UC1, new Scalar(255));
+ for (Rect box : rects) {
+ try{
+ //Todo: Still there are error to fix when image have black border ie. images, stains
+ //this errors are produced by findRects function, also text doesnt working when
+ // images has wave text
+ Mat crop = mat.submat(box);
+ Core.normalize(crop, crop, 0, 255, Core.NORM_MINMAX);
+ Imgproc.threshold(crop, crop, 0, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
+ Scalar meanScalar = Core.mean(crop);
+ double meanValue = meanScalar.val[0];
+ if (meanValue<100){
+ continue;
+ }
+ Mat roi = new_image.submat(new Rect(box.x, box.y, box.width, box.height));
+ Core.bitwise_and(crop,roi,roi);
+ }catch (Exception e){
+ System.err.println("Warning, vission text error filter");
+ }
+// crop.copyTo(roi);
+ }
+ return new_image;
+ }catch (Exception e){
+ throw e;
+ }
+ }
+ public static Mat rgbBitmapToMatGray(Bitmap bitmap){
+ Mat mat = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC3);
+ Utils.bitmapToMat(bitmap,mat);
+ Imgproc.cvtColor(mat,mat, Imgproc.COLOR_RGB2GRAY);
+ return mat;
+ }
+
+ public static List non_max_suppression(List boxes) {
+ // Sort the list of bounding boxes in ascending order based on their y-coordinates
+ Collections.sort(boxes, new Comparator() {
+ @Override
+ public int compare(Rect r1, Rect r2) {
+ return Integer.compare(r1.y, r2.y);
+ }
+ });
+
+ // Initialize the list of selected boxes
+ List selected_boxes = new ArrayList<>();
+
+ // Perform NMS
+ while (boxes.size() > 0) {
+ Rect current = boxes.get(0);
+ selected_boxes.add(current);
+ boxes.remove(0);
+
+ List next_boxes = new ArrayList<>();
+ for (Rect box : boxes) {
+ if (!contain(current, box) && (box.width/ box.height)>1) {
+ next_boxes.add(box);
+ }
+ }
+ boxes = next_boxes;
+ }
+
+ return selected_boxes;
+ }
+
+ public static boolean contain(Rect box1, Rect box2) {
+ // Calculate the coordinates of the intersection rectangle
+ int x1 = Math.max(box1.x, box2.x);
+ int y1 = Math.max(box1.y, box2.y);
+ int x2 = Math.min(box1.x+box1.width, box2.x+box2.width);
+ int y2 = Math.min(box1.y+box1.height, box2.y+box2.height);
+ int w = Math.max(0, x2 - x1);
+ int h = Math.max(0, y2 - y1);
+
+ // Calculate the area of intersection rectangle
+ int intersection = w * h;
+
+ // Calculate the area of both bounding boxes
+// int area_box1 = box1.width * box1.height;
+ int area_box2 = box2.width * box2.height;
+
+ return area_box2 == intersection;
+ }
+ public static List mergeRects(List rects){
+ Collections.sort(rects, new Comparator() {
+ @Override
+ public int compare(Rect r1, Rect r2) {
+ return r1.y - r2.y;
+ }
+ });
+ List mergedBoxes = new ArrayList<>();
+ for (int i = 0; i < rects.size(); i++) {
+ Rect rect = rects.get(i);
+ if (mergedBoxes.isEmpty()) {
+ mergedBoxes.add(rect);
+ } else {
+ Rect prevRect = mergedBoxes.get(mergedBoxes.size()-1);
+ if (Math.abs(rect.y - prevRect.y) > prevRect.height * 0.5) {
+ mergedBoxes.add(rect);
+ } else {
+ if(rect.x - (prevRect.x + prevRect.width)> 0){
+ mergedBoxes.add(rect);
+ }
+ else{
+ int newX = Math.min(rect.x, prevRect.x);
+ int newY = Math.min(rect.y, prevRect.y);
+ int newW = Math.max(rect.x + rect.width, prevRect.x + prevRect.width) - newX;
+ int newH = Math.max(rect.y + rect.height, prevRect.y + prevRect.height) - newY;
+ mergedBoxes.set(mergedBoxes.size()-1, new Rect(newX, newY, newW, newH));
+ }
+ }
+ }
+ }
+ return mergedBoxes;
+ }
+ public static List findRects(Mat image){
+ Mat thresh = new Mat();
+ //find countours in gray image
+ Imgproc.Canny(image, thresh, 50, 150, 3, false);
+ List contours = new ArrayList<>();
+ Mat hierarchy = new Mat();
+ Imgproc.findContours(thresh, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
+ List filteredContours = new ArrayList<>();
+ double height = 0;
+ for (int i = 0; i < contours.size(); i++) {
+ Rect rect = Imgproc.boundingRect(contours.get(i));
+ double area = rect.width * rect.height;
+ double aspectRatio = (double)rect.width / rect.height;
+ //remove rect that doesn't satisface this rules
+ if (area > 80 && aspectRatio > 0.4 && aspectRatio < 5) {
+ height += rect.height;
+ filteredContours.add(new Rect((int)Math.max(0, rect.x-rect.height/2), rect.y, (int)Math.min(image.width(),rect.width+rect.height), rect.height));
+ }
+ }
+ //remove rects with large height than mean height
+ height = height / Math.sqrt(filteredContours.size());
+ List rects = new ArrayList<>();
+ for (int i = 0; i < filteredContours.size(); i++) {
+ Rect rect = filteredContours.get(i);
+ if (rect.height > height) continue;
+ rects.add(rect);
+ }
+ return rects;
+ }
+ public static Mat deskew(Mat image, double skewAngle) {
+ try {
+ Mat rotationMatrix = Imgproc.getRotationMatrix2D(new Point(image.width() / 2, image.height() / 2), skewAngle, 1);
+ Scalar borderValue = new Scalar(255); // white border value
+ // Crop the output image to remove border artifacts
+ Rect cropRect = new Rect(0, 0, image.width(), image.height());
+// System.out.println(image.size());
+// System.out.println(skewAngle);
+ Imgproc.warpAffine(image, image, rotationMatrix, image.size(), Imgproc.INTER_CUBIC + Imgproc.WARP_FILL_OUTLIERS, Core.BORDER_CONSTANT, borderValue);
+ image = image.submat(cropRect);
+ return image;
+ }catch (Exception e){
+ throw e;
+ }
+ }
+
+ //input:binary matrix
+ public static double computeSkewAngle(Mat image) {
+ try {
+ // Apply Canny edge detection to find the edges in the image
+ Imgproc.Canny(image, image, 50, 150, 3);
+ // Apply the Hough transform to find the lines in the image
+ Mat lines = new Mat();
+ Imgproc.HoughLinesP(image, lines, 1, Math.PI / 180, 100, 100, 10);
+
+ // Compute the average angle of the lines
+ double angle = 0.0;
+ int numLines = lines.cols();
+ if (numLines > 0) {
+ // Find the longest line
+ double longestLineLength = -1;
+ Point[] longestLine = null;
+ for (int i = 0; i < lines.cols(); i++) {
+ double[] line = lines.get(0, i);
+ Point pt1 = new Point(line[0], line[1]);
+ Point pt2 = new Point(line[2], line[3]);
+ double length = Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
+ if (length > longestLineLength) {
+ longestLineLength = length;
+ longestLine = new Point[] { pt1, pt2 };
+ }
+ }
+ // Calculate angle between longest line and horizontal axis
+ double dx = longestLine[1].x - longestLine[0].x;
+ double dy = longestLine[1].y - longestLine[0].y;
+ angle = Math.atan2(dy, dx) * 180 / Math.PI;
+ }
+ // Convert the angle from radians to degrees and return it
+ return angle;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+
+ public static ByteBuffer feedInputTensor(
+ Bitmap bitmap,
+ int input_width,
+ int input_height,
+ int src_width,
+ int src_height,
+ float mean,
+ float std) throws Exception {
+ try {
+// utils.getScreenshotBmp(bitmap, "antes");
+ TensorImage tensorImage;
+ if (src_width > input_width || src_height > input_height) {
+ tensorImage= FeedInputTensorHelper.getBytebufferFromBitmap(bitmap, input_width, input_height, mean, std, "downsize");
+ }else{
+ tensorImage= FeedInputTensorHelper.getBytebufferFromBitmap(bitmap, input_width, input_height, mean, std, "upsize");
+ }
+// utils.getScreenshotBmp(tensorImage.getBitmap(), "despues");
+ return tensorImage.getBuffer();
+ }catch (Exception e){
+ throw e;
+
+ }finally {
+ assert bitmap != null;
+ if(!bitmap.isRecycled()){
+ bitmap.recycle();
+ }
+ }
+ }
+ public static Bitmap feedInputToBitmap(Context context,
+ List bytesList,
+ int imageHeight,
+ int imageWidth,
+ int rotation) throws Exception {
+
+ int Yb = bytesList.get(0).length;
+ int Ub = bytesList.get(1).length ;
+ int Vb = bytesList.get(2).length ;
+ // Copy YUV data to plane byte
+ byte[] data = new byte[Yb+Ub+Vb];
+ System.arraycopy(bytesList.get(0), 0, data, 0, Yb);
+ System.arraycopy(bytesList.get(2), 0, data, Yb, Ub);
+ System.arraycopy(bytesList.get(1), 0, data, Yb+Ub, Vb);
+
+ Bitmap bitmapRaw = RenderScriptHelper.getBitmapFromNV21(context,data, imageWidth, imageHeight);
+// utils.getScreenshotBmp(bitmapRaw, "NV21");
+ Matrix matrix = new Matrix();
+ matrix.postRotate(rotation);
+ bitmapRaw = Bitmap.createBitmap(bitmapRaw, 0, 0, bitmapRaw.getWidth(), bitmapRaw.getHeight(), matrix, true);
+ return bitmapRaw;
+ }
+}
diff --git a/frontend/flutter_vision-master/example/.gitignore b/frontend/flutter_vision-master/example/.gitignore
new file mode 100644
index 0000000000..0fa6b675c0
--- /dev/null
+++ b/frontend/flutter_vision-master/example/.gitignore
@@ -0,0 +1,46 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/frontend/flutter_vision-master/example/.metadata b/frontend/flutter_vision-master/example/.metadata
new file mode 100644
index 0000000000..5a023280af
--- /dev/null
+++ b/frontend/flutter_vision-master/example/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: 7e9793dee1b85a243edd0e06cb1658e98b077561
+ channel: stable
+
+project_type: app
diff --git a/frontend/flutter_vision-master/example/README.md b/frontend/flutter_vision-master/example/README.md
new file mode 100644
index 0000000000..30dcde6637
--- /dev/null
+++ b/frontend/flutter_vision-master/example/README.md
@@ -0,0 +1,16 @@
+# flutter_vision_example
+
+Demonstrates how to use the flutter_vision plugin.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
+
+For help getting started with Flutter, view our
+[online documentation](https://flutter.dev/docs), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/frontend/flutter_vision-master/example/analysis_options.yaml b/frontend/flutter_vision-master/example/analysis_options.yaml
new file mode 100644
index 0000000000..61b6c4de17
--- /dev/null
+++ b/frontend/flutter_vision-master/example/analysis_options.yaml
@@ -0,0 +1,29 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at
+ # https://dart-lang.github.io/linter/lints/index.html.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/frontend/flutter_vision-master/example/android/.gitignore b/frontend/flutter_vision-master/example/android/.gitignore
new file mode 100644
index 0000000000..6f568019d3
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/frontend/flutter_vision-master/example/android/app/build.gradle b/frontend/flutter_vision-master/example/android/app/build.gradle
new file mode 100644
index 0000000000..c0c4fa70b8
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/build.gradle
@@ -0,0 +1,56 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion flutter.compileSdkVersion
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.vladih.computer_vision.flutter_vision_example"
+ minSdkVersion localProperties.getProperty('flutter.minSdkVersion').toInteger()
+ targetSdkVersion flutter.targetSdkVersion
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
diff --git a/frontend/flutter_vision-master/example/android/app/src/debug/AndroidManifest.xml b/frontend/flutter_vision-master/example/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000000..8117cc51fe
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/AndroidManifest.xml b/frontend/flutter_vision-master/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..51056b1f83
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/java/com/vladih/computer_vision/flutter_vision_example/MainActivity.java b/frontend/flutter_vision-master/example/android/app/src/main/java/com/vladih/computer_vision/flutter_vision_example/MainActivity.java
new file mode 100644
index 0000000000..942c5dfba4
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/java/com/vladih/computer_vision/flutter_vision_example/MainActivity.java
@@ -0,0 +1,6 @@
+package com.vladih.computer_vision.flutter_vision_example;
+
+import io.flutter.embedding.android.FlutterActivity;
+
+public class MainActivity extends FlutterActivity {
+}
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/drawable-v21/launch_background.xml b/frontend/flutter_vision-master/example/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 0000000000..f74085f3f6
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/drawable/launch_background.xml b/frontend/flutter_vision-master/example/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000000..304732f884
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..db77bb4b7b
Binary files /dev/null and b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..17987b79bb
Binary files /dev/null and b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..09d4391482
Binary files /dev/null and b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..d5f1c8d34e
Binary files /dev/null and b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..4d6372eebd
Binary files /dev/null and b/frontend/flutter_vision-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/values-night/styles.xml b/frontend/flutter_vision-master/example/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000000..3db14bb539
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/main/res/values/styles.xml b/frontend/flutter_vision-master/example/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000000..d460d1e921
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/app/src/profile/AndroidManifest.xml b/frontend/flutter_vision-master/example/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000000..8117cc51fe
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/android/build.gradle b/frontend/flutter_vision-master/example/android/build.gradle
new file mode 100644
index 0000000000..0a2d6a10f9
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/build.gradle
@@ -0,0 +1,31 @@
+buildscript {
+ ext.kotlin_version = '1.6.10'
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.1.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+tasks.register("clean", Delete) {
+ delete rootProject.buildDir
+}
diff --git a/frontend/flutter_vision-master/example/android/gradle.properties b/frontend/flutter_vision-master/example/android/gradle.properties
new file mode 100644
index 0000000000..d5466d8af3
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/gradle.properties
@@ -0,0 +1,4 @@
+#org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
+org.gradle.jvmargs=-Xmx4096m
diff --git a/frontend/flutter_vision-master/example/android/gradle/wrapper/gradle-wrapper.properties b/frontend/flutter_vision-master/example/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..eeaff8aa63
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Feb 22 16:51:52 CET 2023
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/frontend/flutter_vision-master/example/android/settings.gradle b/frontend/flutter_vision-master/example/android/settings.gradle
new file mode 100644
index 0000000000..44e62bcf06
--- /dev/null
+++ b/frontend/flutter_vision-master/example/android/settings.gradle
@@ -0,0 +1,11 @@
+include ':app'
+
+def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
+def properties = new Properties()
+
+assert localPropertiesFile.exists()
+localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
+
+def flutterSdkPath = properties.getProperty("flutter.sdk")
+assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
diff --git a/frontend/flutter_vision-master/example/assets/labels.txt b/frontend/flutter_vision-master/example/assets/labels.txt
new file mode 100644
index 0000000000..1f42c8eb44
--- /dev/null
+++ b/frontend/flutter_vision-master/example/assets/labels.txt
@@ -0,0 +1,80 @@
+person
+bicycle
+car
+motorcycle
+airplane
+bus
+train
+truck
+boat
+traffic light
+fire hydrant
+stop sign
+parking meter
+bench
+bird
+cat
+dog
+horse
+sheep
+cow
+elephant
+bear
+zebra
+giraffe
+backpack
+umbrella
+handbag
+tie
+suitcase
+frisbee
+skis
+snowboard
+sports ball
+kite
+baseball bat
+baseball glove
+skateboard
+surfboard
+tennis racket
+bottle
+wine glass
+cup
+fork
+knife
+spoon
+bowl
+banana
+apple
+sandwich
+orange
+broccoli
+carrot
+hot dog
+pizza
+donut
+cake
+chair
+couch
+potted plant
+bed
+dining table
+toilet
+tv
+laptop
+mouse
+remote
+keyboard
+cell phone
+microwave
+oven
+toaster
+sink
+refrigerator
+book
+clock
+vase
+scissors
+teddy bear
+hair drier
+toothbrush
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/example/assets/tessdata/spa.traineddata b/frontend/flutter_vision-master/example/assets/tessdata/spa.traineddata
new file mode 100644
index 0000000000..f703e0535e
Binary files /dev/null and b/frontend/flutter_vision-master/example/assets/tessdata/spa.traineddata differ
diff --git a/frontend/flutter_vision-master/example/assets/tessdata_config.json b/frontend/flutter_vision-master/example/assets/tessdata_config.json
new file mode 100644
index 0000000000..521c2d9ba1
--- /dev/null
+++ b/frontend/flutter_vision-master/example/assets/tessdata_config.json
@@ -0,0 +1,5 @@
+{
+ "files": [
+ "spa.traineddata"
+ ]
+ }
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/example/assets/yolov5n.tflite b/frontend/flutter_vision-master/example/assets/yolov5n.tflite
new file mode 100644
index 0000000000..0ccf9e4f18
Binary files /dev/null and b/frontend/flutter_vision-master/example/assets/yolov5n.tflite differ
diff --git a/frontend/flutter_vision-master/example/assets/yolov8n-seg.tflite b/frontend/flutter_vision-master/example/assets/yolov8n-seg.tflite
new file mode 100644
index 0000000000..9f089da3f6
Binary files /dev/null and b/frontend/flutter_vision-master/example/assets/yolov8n-seg.tflite differ
diff --git a/frontend/flutter_vision-master/example/assets/yolov8n.tflite b/frontend/flutter_vision-master/example/assets/yolov8n.tflite
new file mode 100644
index 0000000000..b8aeb41b16
Binary files /dev/null and b/frontend/flutter_vision-master/example/assets/yolov8n.tflite differ
diff --git a/frontend/flutter_vision-master/example/ios/.gitignore b/frontend/flutter_vision-master/example/ios/.gitignore
new file mode 100644
index 0000000000..7a7f9873ad
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/frontend/flutter_vision-master/example/ios/Flutter/AppFrameworkInfo.plist b/frontend/flutter_vision-master/example/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000000..8d4492f977
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 9.0
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Flutter/Debug.xcconfig b/frontend/flutter_vision-master/example/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000000..592ceee85b
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Flutter/Debug.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/frontend/flutter_vision-master/example/ios/Flutter/Release.xcconfig b/frontend/flutter_vision-master/example/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000000..592ceee85b
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Flutter/Release.xcconfig
@@ -0,0 +1 @@
+#include "Generated.xcconfig"
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.pbxproj b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..182c3f120b
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,481 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 1300;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.vladih.computervision.flutterVisionExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.vladih.computervision.flutterVisionExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.vladih.computervision.flutterVisionExample;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..919434a625
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000000..18d981003d
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000000..f9b0d7c5ea
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000000..c87d15a335
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..1d526a16ed
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000000..18d981003d
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000000..f9b0d7c5ea
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner/AppDelegate.swift b/frontend/flutter_vision-master/example/ios/Runner/AppDelegate.swift
new file mode 100644
index 0000000000..70693e4a8c
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import UIKit
+import Flutter
+
+@UIApplicationMain
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..d36b1fab2d
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000000..dc9ada4725
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000000..28c6bf0301
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000000..2ccbfd967d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000000..f091b6b0bc
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000000..4cde12118d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000000..d0ef06e7ed
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000000..dcdc2306c2
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000000..2ccbfd967d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000000..c8f9ed8f5c
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000000..a6d6b8609d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000000..a6d6b8609d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000000..75b2d164a5
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000000..c4df70d39d
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000000..6a84f41e14
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000000..d0e1f58536
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000000..0bedcf2fd4
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000000..9da19eacad
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000000..9da19eacad
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000000..9da19eacad
Binary files /dev/null and b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000000..89c2725b70
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000000..f2e259c7c9
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/Main.storyboard b/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000000..f3c28516fb
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Info.plist b/frontend/flutter_vision-master/example/ios/Runner/Info.plist
new file mode 100644
index 0000000000..2c41f84e38
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Info.plist
@@ -0,0 +1,52 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ Flutter Vision
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ flutter_vision_example
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UIViewControllerBasedStatusBarAppearance
+
+
+ NSCameraUsageDescription
+ Access to camera is necesary to run flutter_vision plugin
+ NSMicrophoneUsageDescription
+ Access to mycrophone is not necesary but camera plugin require it to run flutter_vision plugin
+
+
diff --git a/frontend/flutter_vision-master/example/ios/Runner/Runner-Bridging-Header.h b/frontend/flutter_vision-master/example/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 0000000000..308a2a560b
--- /dev/null
+++ b/frontend/flutter_vision-master/example/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/frontend/flutter_vision-master/example/lib/main.dart b/frontend/flutter_vision-master/example/lib/main.dart
new file mode 100644
index 0000000000..5cd7dc89d5
--- /dev/null
+++ b/frontend/flutter_vision-master/example/lib/main.dart
@@ -0,0 +1,933 @@
+import 'dart:io';
+import 'dart:typed_data';
+import 'dart:ui';
+
+import 'package:camera/camera.dart';
+import 'package:flutter/material.dart';
+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';
+
+enum Options { none, imagev5, imagev8, imagev8seg, frame, tesseract, vision }
+
+late List cameras;
+main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ DartPluginRegistrant.ensureInitialized();
+ runApp(
+ const MaterialApp(
+ home: MyApp(),
+ ),
+ );
+}
+
+class MyApp extends StatefulWidget {
+ const MyApp({Key? key}) : super(key: key);
+
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
+ late FlutterVision vision;
+ Options option = Options.none;
+ @override
+ void initState() {
+ super.initState();
+ vision = FlutterVision();
+ }
+
+ @override
+ void dispose() async {
+ super.dispose();
+ await vision.closeTesseractModel();
+ await vision.closeYoloModel();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: task(option),
+ floatingActionButton: SpeedDial(
+ //margin bottom
+ icon: Icons.menu, //icon on Floating action button
+ activeIcon: Icons.close, //icon when menu is expanded on button
+ backgroundColor: Colors.black12, //background color of button
+ foregroundColor: Colors.white, //font color, icon color in button
+ activeBackgroundColor:
+ Colors.deepPurpleAccent, //background color when menu is expanded
+ activeForegroundColor: Colors.white,
+ visible: true,
+ closeManually: false,
+ curve: Curves.bounceIn,
+ overlayColor: Colors.black,
+ overlayOpacity: 0.5,
+ buttonSize: const Size(56.0, 56.0),
+ children: [
+ SpeedDialChild(
+ //speed dial child
+ child: const Icon(Icons.video_call),
+ backgroundColor: Colors.red,
+ foregroundColor: Colors.white,
+ label: 'Yolo on Frame',
+ labelStyle: const TextStyle(fontSize: 18.0),
+ onTap: () {
+ setState(() {
+ option = Options.frame;
+ });
+ },
+ ),
+ SpeedDialChild(
+ child: const Icon(Icons.camera),
+ backgroundColor: Colors.blue,
+ foregroundColor: Colors.white,
+ label: 'YoloV8seg on Image',
+ labelStyle: const TextStyle(fontSize: 18.0),
+ onTap: () {
+ setState(() {
+ option = Options.imagev8seg;
+ });
+ },
+ ),
+ SpeedDialChild(
+ child: const Icon(Icons.camera),
+ backgroundColor: Colors.blue,
+ foregroundColor: Colors.white,
+ label: 'YoloV8 on Image',
+ labelStyle: const TextStyle(fontSize: 18.0),
+ onTap: () {
+ setState(() {
+ option = Options.imagev8;
+ });
+ },
+ ),
+ SpeedDialChild(
+ child: const Icon(Icons.camera),
+ backgroundColor: Colors.blue,
+ foregroundColor: Colors.white,
+ label: 'YoloV5 on Image',
+ labelStyle: const TextStyle(fontSize: 18.0),
+ onTap: () {
+ setState(() {
+ option = Options.imagev5;
+ });
+ },
+ ),
+ SpeedDialChild(
+ child: const Icon(Icons.text_snippet_outlined),
+ foregroundColor: Colors.white,
+ backgroundColor: Colors.green,
+ label: 'Tesseract',
+ labelStyle: const TextStyle(fontSize: 18.0),
+ onTap: () {
+ setState(() {
+ option = Options.tesseract;
+ });
+ },
+ ),
+ // SpeedDialChild(
+ // child: const Icon(Icons.document_scanner),
+ // foregroundColor: Colors.white,
+ // backgroundColor: Colors.green,
+ // label: 'Vision',
+ // labelStyle: const TextStyle(fontSize: 18.0),
+ // onTap: () {
+ // setState(() {
+ // option = Options.vision;
+ // });
+ // },
+ // ),
+ ],
+ ),
+ );
+ }
+
+ Widget task(Options option) {
+ if (option == Options.frame) {
+ return YoloVideo(vision: vision);
+ }
+ if (option == Options.imagev5) {
+ return YoloImageV5(vision: vision);
+ }
+ if (option == Options.imagev8) {
+ return YoloImageV8(vision: vision);
+ }
+ if (option == Options.imagev8seg) {
+ return YoloImageV8Seg(vision: vision);
+ }
+ if (option == Options.tesseract) {
+ return TesseractImage(vision: vision);
+ }
+ return const Center(child: Text("Choose Task"));
+ }
+}
+
+class YoloVideo extends StatefulWidget {
+ final FlutterVision vision;
+ const YoloVideo({Key? key, required this.vision}) : super(key: key);
+
+ @override
+ State createState() => _YoloVideoState();
+}
+
+class _YoloVideoState extends State {
+ late CameraController controller;
+ late List> yoloResults;
+ CameraImage? cameraImage;
+ bool isLoaded = false;
+ bool isDetecting = false;
+
+ @override
+ void initState() {
+ super.initState();
+ init();
+ }
+
+ init() async {
+ cameras = await availableCameras();
+ controller = CameraController(cameras[0], ResolutionPreset.medium);
+ controller.initialize().then((value) {
+ loadYoloModel().then((value) {
+ setState(() {
+ isLoaded = true;
+ isDetecting = false;
+ yoloResults = [];
+ });
+ });
+ });
+ }
+
+ @override
+ void dispose() async {
+ super.dispose();
+ controller.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 Stack(
+ fit: StackFit.expand,
+ children: [
+ AspectRatio(
+ aspectRatio: controller.value.aspectRatio,
+ child: CameraPreview(
+ controller,
+ ),
+ ),
+ ...displayBoxesAroundRecognizedObjects(size),
+ Positioned(
+ bottom: 75,
+ width: MediaQuery.of(context).size.width,
+ child: Container(
+ height: 80,
+ width: 80,
+ 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,
+ color: Colors.white,
+ ),
+ iconSize: 50,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Future loadYoloModel() async {
+ await widget.vision.loadYoloModel(
+ labels: 'assets/labels.txt',
+ modelPath: 'assets/yolov8n.tflite',
+ modelVersion: "yolov8",
+ 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(() {
+ yoloResults = result;
+ });
+ }
+ }
+
+ Future startDetection() async {
+ setState(() {
+ isDetecting = true;
+ });
+ if (controller.value.isStreamingImages) {
+ return;
+ }
+ await controller.startImageStream((image) async {
+ if (isDetecting) {
+ cameraImage = image;
+ yoloOnFrame(image);
+ }
+ });
+ }
+
+ Future stopDetection() async {
+ setState(() {
+ isDetecting = false;
+ yoloResults.clear();
+ });
+ }
+
+ List displayBoxesAroundRecognizedObjects(Size screen) {
+ if (yoloResults.isEmpty) return [];
+ double factorX = screen.width / (cameraImage?.height ?? 1);
+ double factorY = screen.height / (cameraImage?.width ?? 1);
+
+ 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,
+ 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: 18.0,
+ ),
+ ),
+ ),
+ );
+ }).toList();
+ }
+}
+
+class YoloImageV5 extends StatefulWidget {
+ final FlutterVision vision;
+ const YoloImageV5({Key? key, required this.vision}) : super(key: key);
+
+ @override
+ State createState() => _YoloImageV5State();
+}
+
+class _YoloImageV5State extends State {
+ late List> 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 Stack(
+ fit: StackFit.expand,
+ children: [
+ imageFile != null ? Image.file(imageFile!) : const SizedBox(),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: pickImage,
+ child: const Text("Pick image"),
+ ),
+ ElevatedButton(
+ onPressed: yoloOnImage,
+ child: const Text("Detect"),
+ )
+ ],
+ ),
+ ),
+ ...displayBoxesAroundRecognizedObjects(size),
+ ],
+ );
+ }
+
+ Future loadYoloModel() async {
+ await widget.vision.loadYoloModel(
+ labels: 'assets/labels.txt',
+ modelPath: 'assets/yolov5n.tflite',
+ modelVersion: "yolov5",
+ quantization: false,
+ numThreads: 2,
+ useGpu: true);
+ setState(() {
+ isLoaded = true;
+ });
+ }
+
+ Future pickImage() async {
+ final ImagePicker picker = ImagePicker();
+ // Capture a photo
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ setState(() {
+ imageFile = File(photo.path);
+ });
+ }
+ }
+
+ 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.4,
+ classThreshold: 0.5);
+ if (result.isNotEmpty) {
+ setState(() {
+ yoloResults = result;
+ });
+ }
+ }
+
+ List 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: 18.0,
+ ),
+ ),
+ ),
+ );
+ }).toList();
+ }
+}
+
+class YoloImageV8 extends StatefulWidget {
+ final FlutterVision vision;
+ const YoloImageV8({Key? key, required this.vision}) : super(key: key);
+
+ @override
+ State createState() => _YoloImageV8State();
+}
+
+class _YoloImageV8State extends State {
+ late List> 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 Stack(
+ fit: StackFit.expand,
+ children: [
+ imageFile != null ? Image.file(imageFile!) : const SizedBox(),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: pickImage,
+ child: const Text("Pick an image"),
+ ),
+ ElevatedButton(
+ onPressed: yoloOnImage,
+ child: const Text("Detect"),
+ )
+ ],
+ ),
+ ),
+ ...displayBoxesAroundRecognizedObjects(size),
+ ],
+ );
+ }
+
+ Future loadYoloModel() async {
+ await widget.vision.loadYoloModel(
+ labels: 'assets/labels.txt',
+ modelPath: 'assets/yolov8n.tflite',
+ modelVersion: "yolov8",
+ quantization: false,
+ numThreads: 2,
+ useGpu: true);
+ setState(() {
+ isLoaded = true;
+ });
+ }
+
+ Future pickImage() async {
+ final ImagePicker picker = ImagePicker();
+ // Capture a photo
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ setState(() {
+ imageFile = File(photo.path);
+ });
+ }
+ }
+
+ 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.4,
+ classThreshold: 0.5);
+ if (result.isNotEmpty) {
+ setState(() {
+ yoloResults = result;
+ });
+ }
+ }
+
+ List 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: 18.0,
+ ),
+ ),
+ ),
+ );
+ }).toList();
+ }
+}
+
+class YoloImageV8Seg extends StatefulWidget {
+ final FlutterVision vision;
+ const YoloImageV8Seg({Key? key, required this.vision}) : super(key: key);
+
+ @override
+ State createState() => _YoloImageV8SegState();
+}
+
+class _YoloImageV8SegState extends State {
+ late List> 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 Stack(
+ fit: StackFit.expand,
+ children: [
+ imageFile != null ? Image.file(imageFile!) : const SizedBox(),
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: pickImage,
+ child: const Text("Pick image"),
+ ),
+ ElevatedButton(
+ onPressed: yoloOnImage,
+ child: const Text("Detect"),
+ )
+ ],
+ ),
+ ),
+ ...displayBoxesAroundRecognizedObjects(size),
+ ],
+ );
+ }
+
+ Future loadYoloModel() async {
+ await widget.vision.loadYoloModel(
+ labels: 'assets/labels.txt',
+ modelPath: 'assets/yolov8n-seg.tflite',
+ modelVersion: "yolov8seg",
+ quantization: false,
+ numThreads: 2,
+ useGpu: true);
+ setState(() {
+ isLoaded = true;
+ });
+ }
+
+ Future pickImage() async {
+ final ImagePicker picker = ImagePicker();
+ // Capture a photo
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ setState(() {
+ imageFile = File(photo.path);
+ });
+ }
+ }
+
+ 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.4,
+ classThreshold: 0.5);
+ if (result.isNotEmpty) {
+ setState(() {
+ yoloResults = result;
+ });
+ }
+ }
+
+ List 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 Stack(children: [
+ 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: 18.0,
+ ),
+ ),
+ ),
+ ),
+ 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: CustomPaint(
+ painter: PolygonPainter(
+ points: (result["polygons"] as List).map((e) {
+ Map xy = Map.from(e);
+ xy['x'] = (xy['x'] as double) * factorX;
+ xy['y'] = (xy['y'] as double) * factorY;
+ return xy;
+ }).toList()),
+ )),
+ ]);
+ }).toList();
+ }
+}
+
+class PolygonPainter extends CustomPainter {
+ final List> points;
+
+ PolygonPainter({required this.points});
+
+ @override
+ void paint(Canvas canvas, Size size) {
+ final paint = Paint()
+ ..color = const Color.fromARGB(129, 255, 2, 124)
+ ..strokeWidth = 2
+ ..style = PaintingStyle.fill;
+
+ final path = Path();
+ if (points.isNotEmpty) {
+ path.moveTo(points[0]['x']!, points[0]['y']!);
+ for (var i = 1; i < points.length; i++) {
+ path.lineTo(points[i]['x']!, points[i]['y']!);
+ }
+ path.close();
+ }
+
+ canvas.drawPath(path, paint);
+ }
+
+ @override
+ bool shouldRepaint(CustomPainter oldDelegate) {
+ return false;
+ }
+}
+
+class TesseractImage extends StatefulWidget {
+ final FlutterVision vision;
+ const TesseractImage({Key? key, required this.vision}) : super(key: key);
+
+ @override
+ State createState() => _TesseractImageState();
+}
+
+class _TesseractImageState extends State {
+ late List> tesseractResults = [];
+ File? imageFile;
+ bool isLoaded = false;
+
+ @override
+ void initState() {
+ super.initState();
+ loadTesseractModel().then((value) {
+ setState(() {
+ isLoaded = true;
+ tesseractResults = [];
+ });
+ });
+ }
+
+ @override
+ void dispose() async {
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ if (!isLoaded) {
+ return const Scaffold(
+ body: Center(
+ child: Text("Model not loaded, waiting for it"),
+ ),
+ );
+ }
+ return Center(
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ imageFile != null ? Image.file(imageFile!) : const SizedBox(),
+ tesseractResults.isEmpty
+ ? const SizedBox()
+ : Align(child: Text(tesseractResults[0]["text"])),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ TextButton(
+ onPressed: pickImage,
+ child: const Text("Pick an image"),
+ ),
+ ElevatedButton(
+ onPressed: tesseractOnImage,
+ child: const Text("Get Text"),
+ )
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Future loadTesseractModel() async {
+ await widget.vision.loadTesseractModel(
+ args: {
+ 'psm': '11',
+ 'oem': '1',
+ 'preserve_interword_spaces': '1',
+ },
+ language: 'spa',
+ );
+ setState(() {
+ isLoaded = true;
+ });
+ }
+
+ Future pickImage() async {
+ final ImagePicker picker = ImagePicker();
+ // Capture a photo
+ final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
+ if (photo != null) {
+ setState(() {
+ imageFile = File(photo.path);
+ });
+ }
+ }
+
+ tesseractOnImage() async {
+ tesseractResults.clear();
+ Uint8List byte = await imageFile!.readAsBytes();
+ final result = await widget.vision.tesseractOnImage(bytesList: byte);
+ if (result.isNotEmpty) {
+ setState(() {
+ tesseractResults = result;
+ });
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/example/pubspec.lock b/frontend/flutter_vision-master/example/pubspec.lock
new file mode 100644
index 0000000000..ea616238d1
--- /dev/null
+++ b/frontend/flutter_vision-master/example/pubspec.lock
@@ -0,0 +1,457 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.11.0"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ camera:
+ dependency: "direct main"
+ description:
+ name: camera
+ sha256: "3ad71371b8168a4c8012c0b40a53c05afc75d46cc688b0f37b4611a841d47b25"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.8+1"
+ camera_android:
+ dependency: transitive
+ description:
+ name: camera_android
+ sha256: "665d62c1f334722c7519ca5d3b94ad68ecaa801691870602da5638a42c1fff67"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.8+3"
+ camera_avfoundation:
+ dependency: transitive
+ description:
+ name: camera_avfoundation
+ sha256: "6a68c20593d4cd58974d555f74a48b244f9db28cc9156de57781122d11b8754b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.11"
+ camera_platform_interface:
+ dependency: transitive
+ description:
+ name: camera_platform_interface
+ sha256: b632be28e61d00a233f67d98ea90fd7041956f27a1c65500188ee459be60e15f
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.0"
+ camera_web:
+ dependency: transitive
+ description:
+ name: camera_web
+ sha256: "18cdbee5441e9a6fb129fdd9b68a06d1b8c5236932ba97d5faeaefe80db2e5bd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.2.1+6"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ clock:
+ dependency: transitive
+ description:
+ name: clock
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.17.2"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.3+4"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.5"
+ fake_async:
+ dependency: transitive
+ description:
+ name: fake_async
+ sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.1"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.4"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ flutter_plugin_android_lifecycle:
+ dependency: transitive
+ description:
+ name: flutter_plugin_android_lifecycle
+ sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.7"
+ flutter_speed_dial:
+ dependency: "direct main"
+ description:
+ name: flutter_speed_dial
+ sha256: "41d7ad0bc224248637b3a5e0b9083e912a75445bdb450cf82b8ed06d7af7c61d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.0"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_vision:
+ dependency: "direct main"
+ description:
+ path: ".."
+ relative: true
+ source: path
+ version: "1.1.2"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.13.5"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ image_picker:
+ dependency: "direct main"
+ description:
+ name: image_picker
+ sha256: "22207768556b82d55ec70166824350fee32298732d5efa4d6e756f848f51f66a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.6+3"
+ image_picker_android:
+ dependency: transitive
+ description:
+ name: image_picker_android
+ sha256: "68d067baf7f6e401b1124ee83dd6967e67847314250fd68012aab34a69beb344"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.5+7"
+ image_picker_for_web:
+ dependency: transitive
+ description:
+ name: image_picker_for_web
+ sha256: "66fc6e3877bbde82c33d122f3588777c3784ac5bd7d1cdd79213ef7aecb85b34"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.11"
+ image_picker_ios:
+ dependency: transitive
+ description:
+ name: image_picker_ios
+ sha256: "39aa70b5f1e5e7c94585b9738632d5fdb764a5655e40cd9e7b95fbd2fc50c519"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.6+9"
+ image_picker_platform_interface:
+ dependency: transitive
+ description:
+ name: image_picker_platform_interface
+ sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.3"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: a5e201311cb08bf3912ebbe9a2be096e182d703f881136ec1e81a2338a9e120d
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.4"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.16"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.5.0"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.9.1"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.8.3"
+ path_provider:
+ dependency: transitive
+ description:
+ name: path_provider
+ sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.12"
+ path_provider_android:
+ dependency: transitive
+ description:
+ name: path_provider_android
+ sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.22"
+ path_provider_foundation:
+ dependency: transitive
+ description:
+ name: path_provider_foundation
+ sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: "2e32f1640f07caef0d3cb993680f181c79e54a3827b997d5ee221490d131fbd9"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.8"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.5"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
+ process:
+ dependency: transitive
+ description:
+ name: process
+ sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.4"
+ quiver:
+ dependency: transitive
+ description:
+ name: quiver
+ sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.2.1"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.10.0"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.11.0"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
+ stream_transform:
+ dependency: transitive
+ description:
+ name: stream_transform
+ sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.0"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.0"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.1.4-beta"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.3"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
+sdks:
+ dart: ">=3.1.0-185.0.dev <4.0.0"
+ flutter: ">=3.0.0"
diff --git a/frontend/flutter_vision-master/example/pubspec.yaml b/frontend/flutter_vision-master/example/pubspec.yaml
new file mode 100644
index 0000000000..c29ed4a64a
--- /dev/null
+++ b/frontend/flutter_vision-master/example/pubspec.yaml
@@ -0,0 +1,74 @@
+name: flutter_vision_example
+description: Demonstrates how to use the flutter_vision plugin.
+
+# The following line prevents the package from being accidentally published to
+# pub.dev using `flutter pub publish`. This is preferred for private packages.
+publish_to: "none" # Remove this line if you wish to publish to pub.dev
+
+environment:
+ sdk: ">=2.17.1 <3.0.0"
+
+# Dependencies specify other packages that your package needs in order to work.
+# To automatically upgrade your package dependencies to the latest versions
+# consider running `flutter pub upgrade --major-versions`. Alternatively,
+# dependencies can be manually updated by changing the version numbers below to
+# the latest version available on pub.dev. To see which dependencies have newer
+# versions available, run `flutter pub outdated`.
+dependencies:
+ camera: ^0.9.8+1
+ cupertino_icons: ^1.0.5
+ flutter:
+ sdk: flutter
+ flutter_vision:
+ path: ../
+ flutter_speed_dial: ^6.2.0
+ image_picker: ^0.8.6+3
+
+dev_dependencies:
+ # The "flutter_lints" package below contains a set of recommended lints to
+ # encourage good coding practices. The lint set provided by the package is
+ # activated in the `analysis_options.yaml` file located at the root of your
+ # package. See that file for information about deactivating specific lint
+ # rules and activating additional ones.
+ flutter_lints: ^2.0.1
+ flutter_test:
+ sdk: flutter
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+# The following section is specific to Flutter.
+flutter:
+ # The following line ensures that the Material Icons font is
+ # included with your application, so that you can use the icons in
+ # the material Icons class.
+ uses-material-design: true
+
+ # To add assets to your application, add an assets section, like this:
+ assets:
+ - assets/
+ - assets/labels.txt
+ - assets/yolov5n.tflite
+ - assets/tessdata/
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/assets-and-images/#resolution-aware.
+ # For details regarding adding assets from package dependencies, see
+ # https://flutter.dev/assets-and-images/#from-packages
+ # To add custom fonts to your application, add a fonts section here,
+ # in this "flutter" section. Each entry in this list should have a
+ # "family" key with the font family name, and a "fonts" key with a
+ # list giving the asset and other descriptors for the font. For
+ # example:
+ # fonts:
+ # - family: Schyler
+ # fonts:
+ # - asset: fonts/Schyler-Regular.ttf
+ # - asset: fonts/Schyler-Italic.ttf
+ # style: italic
+ # - family: Trajan Pro
+ # fonts:
+ # - asset: fonts/TrajanPro.ttf
+ # - asset: fonts/TrajanPro_Bold.ttf
+ # weight: 700
+ #
+ # For details regarding fonts from package dependencies,
+ # see https://flutter.dev/custom-fonts/#from-packages
diff --git a/frontend/flutter_vision-master/example/test/widget_test.dart b/frontend/flutter_vision-master/example/test/widget_test.dart
new file mode 100644
index 0000000000..55da4f5403
--- /dev/null
+++ b/frontend/flutter_vision-master/example/test/widget_test.dart
@@ -0,0 +1,27 @@
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility that Flutter provides. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+// import 'package:flutter_vision_example/main.dart';
+
+void main() {
+ testWidgets('Verify Platform version', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ //await tester.pumpWidget(const MyApp());
+
+ // Verify that platform version is retrieved.
+ expect(
+ find.byWidgetPredicate(
+ (Widget widget) =>
+ widget is Text && widget.data!.startsWith('Running on:'),
+ ),
+ findsOneWidget,
+ );
+ });
+}
diff --git a/frontend/flutter_vision-master/ios/.gitignore b/frontend/flutter_vision-master/ios/.gitignore
new file mode 100644
index 0000000000..0c885071e3
--- /dev/null
+++ b/frontend/flutter_vision-master/ios/.gitignore
@@ -0,0 +1,38 @@
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+.DS_Store
+*.swp
+profile
+
+DerivedData/
+build/
+GeneratedPluginRegistrant.h
+GeneratedPluginRegistrant.m
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+/Flutter/Generated.xcconfig
+/Flutter/ephemeral/
+/Flutter/flutter_export_environment.sh
\ No newline at end of file
diff --git a/frontend/flutter_vision-master/ios/Assets/.gitkeep b/frontend/flutter_vision-master/ios/Assets/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.h b/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.h
new file mode 100644
index 0000000000..00292d490f
--- /dev/null
+++ b/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.h
@@ -0,0 +1,4 @@
+#import
+
+@interface FlutterVisionPlugin : NSObject
+@end
diff --git a/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.m b/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.m
new file mode 100644
index 0000000000..e9df5fd95e
--- /dev/null
+++ b/frontend/flutter_vision-master/ios/Classes/FlutterVisionPlugin.m
@@ -0,0 +1,15 @@
+#import "FlutterVisionPlugin.h"
+#if __has_include()
+#import
+#else
+// Support project import fallback if the generated compatibility header
+// is not copied when this plugin is created as a library.
+// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
+#import "flutter_vision-Swift.h"
+#endif
+
+@implementation FlutterVisionPlugin
++ (void)registerWithRegistrar:(NSObject*)registrar {
+ [SwiftFlutterVisionPlugin registerWithRegistrar:registrar];
+}
+@end
diff --git a/frontend/flutter_vision-master/ios/Classes/SwiftFlutterVisionPlugin.swift b/frontend/flutter_vision-master/ios/Classes/SwiftFlutterVisionPlugin.swift
new file mode 100644
index 0000000000..3bbaa51904
--- /dev/null
+++ b/frontend/flutter_vision-master/ios/Classes/SwiftFlutterVisionPlugin.swift
@@ -0,0 +1,14 @@
+import Flutter
+import UIKit
+
+public class SwiftFlutterVisionPlugin: NSObject, FlutterPlugin {
+ public static func register(with registrar: FlutterPluginRegistrar) {
+ let channel = FlutterMethodChannel(name: "flutter_vision", binaryMessenger: registrar.messenger())
+ let instance = SwiftFlutterVisionPlugin()
+ registrar.addMethodCallDelegate(instance, channel: channel)
+ }
+
+ public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
+ result("iOS " + UIDevice.current.systemVersion)
+ }
+}
diff --git a/frontend/flutter_vision-master/ios/flutter_vision.podspec b/frontend/flutter_vision-master/ios/flutter_vision.podspec
new file mode 100644
index 0000000000..03e44c49d6
--- /dev/null
+++ b/frontend/flutter_vision-master/ios/flutter_vision.podspec
@@ -0,0 +1,23 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint flutter_vision.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+ s.name = 'flutter_vision'
+ s.version = '0.0.1'
+ s.summary = 'A new flutter plugin project.'
+ s.description = <<-DESC
+A new flutter plugin project.
+ DESC
+ s.homepage = 'http://example.com'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Your Company' => 'email@example.com' }
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.dependency 'Flutter'
+ s.platform = :ios, '9.0'
+
+ # Flutter.framework does not contain a i386 slice.
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
+ s.swift_version = '5.0'
+end
diff --git a/frontend/flutter_vision-master/lib/flutter_vision.dart b/frontend/flutter_vision-master/lib/flutter_vision.dart
new file mode 100644
index 0000000000..993d8cabb2
--- /dev/null
+++ b/frontend/flutter_vision-master/lib/flutter_vision.dart
@@ -0,0 +1,176 @@
+import 'dart:async';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:flutter_vision/src/plugin/android.dart';
+
+abstract class FlutterVision {
+ factory FlutterVision() {
+ switch (Platform.operatingSystem) {
+ case 'android':
+ return AndroidFlutterVision();
+ case 'ios':
+ throw UnimplementedError('iOS is not supported for now');
+ //return IosDniScanner();
+ default:
+ throw UnsupportedError('Unsupported platform');
+ }
+ }
+
+ // ///loadOcrModel: loads both YOLOv5 and Tesseract4 model from the assets folder and
+ // ///return a ResponseHandler object.
+ // ///
+ // ///if the load is successful, it returns a ResponseHandler as a success object,
+ // ///otherwise it returns a ResponseHandler as an error object
+ // ///```json:{
+ // /// "type": "success" or "error",
+ // /// "message": "ok",
+ // /// "data": {}```
+ // ///
+ // /// args: [modelPath] - path to the model file
+ // /// ,[labelsPath] - path to the labels file
+ // /// ,[numThreads] - number of threads to use for inference
+ // /// ,[useGPU] - use GPU for inference
+ // /// ,[language] - language for tesseract4(en,spa,de,fr,it,nl,ru,pt,tr,zh)
+ // /// ,[tesseract4Config] - tesseract4 config
+ // Future loadOcrModel(
+ // {required String modelPath,
+ // required String labels,
+ // int? numThreads,
+ // bool? useGpu,
+ // String? language,
+ // Map? args});
+
+ // ///scanOnFrame accept a byte List as input and
+ // ///return a ResponseHandler object.
+ // ///
+ // ///if scanOnFrame run without error, it returns a ResponseHandler as a success object,
+ // ///otherwise it returns a ResponseHandler as an error object.
+ // ///
+ // ///```json:{
+ // /// "type": 'success',
+ // /// "message": "ok",
+ // /// "data": List>
+ // /// }```
+ // ///where map is mapped as follows:
+ // ///
+ // ///```Map:{
+ // /// "confidence": double,
+ // /// "box": {x1:double, y1:double, x2:double, y2:double},
+ // /// "text": String,
+ // /// "image": Uint8List,
+ // /// "tag": String
+ // /// }```
+ // ///
+ // ///args: [bytesList] - image as byte list
+ // ///, [imageHeight] - image height
+ // ///, [imageWidth] - image width
+ // ///, [classIsText] - list of classes to be detected as text
+ // ///, [iouThreshold] - intersection over union threshold
+ // ///, [confThreshold] - confidence threshold
+ // Future>> ocrOnFrame({
+ // required List bytesList,
+ // required int imageHeight,
+ // required int imageWidth,
+ // required List classIsText,
+ // double? iouThreshold,
+ // double? confThreshold,
+ // });
+
+ // /// dispose OCRModel, clean and save resources
+ // Future closeOcrModel();
+
+ ///loadYoloModel: load YOLOv5 model from the assets folder
+ ///
+ /// args: [modelPath] - path to the model file
+ /// ,[labelsPath] - path to the labels file
+ /// ,[modelVersion] - yolov5, yolov8
+ /// ,[quantization] - When set to true, quantized models are used, which can result in faster execution, reduced memory usage, and slightly lower accuracy.
+ /// ,[numThreads] - number of threads to use for inference
+ /// ,[useGPU] - use GPU for inference
+ Future loadYoloModel(
+ {required String modelPath,
+ required String labels,
+ required String modelVersion,
+ bool? quantization,
+ int? numThreads,
+ bool? useGpu});
+
+ ///yoloOnFrame accept a byte List as input and
+ ///return a List>.
+ ///
+ ///where map is mapped as follow:
+ ///
+ ///```Map:{
+ /// "box": [x1:left, y1:top, x2:right, y2:bottom, class_confidence]
+ /// "tag": String: detected class
+ /// }```
+ ///
+ ///args: [bytesList] - image as byte list
+ ///, [imageHeight] - image height
+ ///, [imageWidth] - image width
+ ///, [iouThreshold] - intersection over union threshold, default 0.4
+ ///, [confThreshold] - model confidence threshold, default 0.5, only for [yolov5]
+ ///, [classThreshold] - class confidence threshold, default 0.5
+ Future>> yoloOnFrame({
+ required List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ double? iouThreshold,
+ double? confThreshold,
+ double? classThreshold,
+ });
+
+ ///yoloOnImage accept a Uint8List as input and
+ ///return a List>.
+ ///
+ ///where map is mapped as follows:
+ ///
+ ///```Map:{
+ /// "box": [x1:left, y1:top, x2:right, y2:bottom, class_confidence]
+ /// "tag": String: detected class
+ /// }```
+ ///
+ ///args: [bytesList] - image bytes
+ ///, [imageHeight] - image height
+ ///, [imageWidth] - image width
+ ///, [iouThreshold] - intersection over union threshold, default 0.4
+ ///, [confThreshold] - model confidence threshold, default 0.5, only for [yolov5]
+ ///, [classThreshold] - class confidence threshold, default 0.5
+ Future>> yoloOnImage({
+ required Uint8List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ double? iouThreshold,
+ double? confThreshold,
+ double? classThreshold,
+ });
+
+ /// dispose OCRModel, clean and save resources
+ Future closeYoloModel();
+
+ ///loadTesseractModel: load Tesseract5 model from the assets folder.
+ ///
+ /// ,[language] - language for tesseract4(en,spa,de,fr,it,nl,ru,pt,tr,zh)
+ /// ,[tesseract4Config] - tesseract4 config
+ Future loadTesseractModel(
+ {String? language, Map? args});
+
+ ///tesseractOnImage accept a byte as input and
+ ///return a List.
+ ///
+ ///where map is mapped as follows:
+ ///
+ ///```Map:{
+ /// "text": String
+ /// "word_conf": List:int
+ /// "mean_conf": int
+ /// }```
+ ///
+ ///args: [bytesList] - image as byte
+ Future>> tesseractOnImage(
+ {required Uint8List bytesList});
+
+ /// dispose Tesseract model, clean and save resources
+ Future closeTesseractModel();
+}
diff --git a/frontend/flutter_vision-master/lib/src/plugin/android.dart b/frontend/flutter_vision-master/lib/src/plugin/android.dart
new file mode 100644
index 0000000000..c13f298c1c
--- /dev/null
+++ b/frontend/flutter_vision-master/lib/src/plugin/android.dart
@@ -0,0 +1,245 @@
+import 'dart:typed_data';
+
+import '../../flutter_vision.dart';
+import 'base.dart';
+
+class AndroidFlutterVision extends BaseFlutterVision implements FlutterVision {
+ // @override
+ // Future loadOcrModel(
+ // {required String modelPath,
+ // required String labels,
+ // int? numThreads,
+ // bool? useGpu,
+ // String? language,
+ // Map? args}) async {
+ // try {
+ // final String testData = await loadTessData();
+ // await channel.invokeMethod('loadOcrModel', {
+ // 'model_path': modelPath,
+ // 'is_asset': true,
+ // 'num_threads': numThreads ?? 1,
+ // 'use_gpu': useGpu ?? false,
+ // 'label_path': labels,
+ // 'image_mean': 0.0,
+ // 'image_std': 255.0,
+ // 'rotation': 90,
+ // 'tess_data': testData,
+ // 'arg': args,
+ // 'language': language ?? 'eng'
+ // });
+ // } catch (e) {
+ // rethrow;
+ // }
+ // }
+
+ // @override
+ // Future>> ocrOnFrame({
+ // required List bytesList,
+ // required int imageHeight,
+ // required int imageWidth,
+ // required List classIsText,
+ // double? iouThreshold,
+ // double? confThreshold,
+ // }) async {
+ // try {
+ // return await _ocrOnFrame(
+ // bytesList: bytesList,
+ // imageHeight: imageHeight,
+ // imageWidth: imageWidth,
+ // iouThreshold: iouThreshold ?? 0.4,
+ // confThreshold: confThreshold ?? 0.5,
+ // classIsText: classIsText);
+ // } catch (e) {
+ // rethrow;
+ // }
+ // }
+
+ // Future>> _ocrOnFrame({
+ // required List bytesList,
+ // required int imageHeight,
+ // required int imageWidth,
+ // required double iouThreshold,
+ // required double confThreshold,
+ // required List classIsText,
+ // }) async {
+ // try {
+ // final x = await channel.invokeMethod>>(
+ // 'ocrOnFrame',
+ // {
+ // "bytesList": bytesList,
+ // "image_height": imageHeight,
+ // "image_width": imageWidth,
+ // "iou_threshold": iouThreshold,
+ // "conf_threshold": confThreshold,
+ // "class_is_text": classIsText
+ // },
+ // );
+ // return x ?? [];
+ // } catch (e) {
+ // rethrow;
+ // }
+ // }
+
+ @override
+ Future loadYoloModel(
+ {required String modelPath,
+ required String labels,
+ required String modelVersion,
+ bool? quantization,
+ int? numThreads,
+ bool? useGpu}) async {
+ try {
+ await channel.invokeMethod('loadYoloModel', {
+ 'model_path': modelPath,
+ 'is_asset': true,
+ 'quantization': quantization ?? false,
+ 'num_threads': numThreads ?? 1,
+ 'use_gpu': useGpu ?? false,
+ 'label_path': labels,
+ 'rotation': 90,
+ 'model_version': modelVersion
+ });
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ @override
+ Future>> yoloOnFrame({
+ required List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ double? iouThreshold,
+ double? confThreshold,
+ double? classThreshold,
+ }) async {
+ try {
+ return (await _yoloOnFrame(
+ bytesList: bytesList,
+ imageHeight: imageHeight,
+ imageWidth: imageWidth,
+ iouThreshold: iouThreshold ?? 0.4,
+ confThreshold: confThreshold ?? 0.5,
+ classThreshold: classThreshold ?? 0.5));
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ Future>> _yoloOnFrame({
+ required List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ required double iouThreshold,
+ required double confThreshold,
+ required double classThreshold,
+ }) async {
+ try {
+ final x = await channel.invokeMethod>(
+ 'yoloOnFrame',
+ {
+ "bytesList": bytesList,
+ "image_height": imageHeight,
+ "image_width": imageWidth,
+ "iou_threshold": iouThreshold,
+ "conf_threshold": confThreshold,
+ "class_threshold": classThreshold
+ },
+ );
+ return x?.isNotEmpty ?? false
+ ? x!.map((e) => Map.from(e)).toList()
+ : [];
+ } catch (e) {
+ // print(e);
+ rethrow;
+ }
+ }
+
+ @override
+ Future>> yoloOnImage({
+ required Uint8List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ double? iouThreshold,
+ double? confThreshold,
+ double? classThreshold,
+ }) async {
+ try {
+ return await _yoloOnImage(
+ bytesList: bytesList,
+ imageHeight: imageHeight,
+ imageWidth: imageWidth,
+ iouThreshold: iouThreshold ?? 0.4,
+ confThreshold: confThreshold ?? 0.5,
+ classThreshold: classThreshold ?? 0.5);
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ Future>> _yoloOnImage({
+ required Uint8List bytesList,
+ required int imageHeight,
+ required int imageWidth,
+ required double iouThreshold,
+ required double confThreshold,
+ required double classThreshold,
+ }) async {
+ try {
+ final x = await channel.invokeMethod>(
+ 'yoloOnImage',
+ {
+ "bytesList": bytesList,
+ "image_height": imageHeight,
+ "image_width": imageWidth,
+ "iou_threshold": iouThreshold,
+ "conf_threshold": confThreshold,
+ "class_threshold": classThreshold
+ },
+ );
+ return x?.isNotEmpty ?? false
+ ? x!.map((e) => Map.from(e)).toList()
+ : [];
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ @override
+ Future loadTesseractModel(
+ {String? language, Map? args}) async {
+ try {
+ final String testData = await loadTessData();
+ await channel.invokeMethod('loadTesseractModel',
+ {'tess_data': testData, 'arg': args, 'language': language ?? 'eng'});
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ @override
+ Future>> tesseractOnImage({
+ required Uint8List bytesList,
+ }) async {
+ try {
+ return await _tesseractOnImage(bytesList: bytesList);
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ Future>> _tesseractOnImage(
+ {required Uint8List bytesList}) async {
+ try {
+ final x = await channel.invokeMethod(
+ 'tesseractOnImage',
+ {
+ "bytesList": bytesList,
+ },
+ );
+ return x == null ? [] : [Map.from(x)];
+ } catch (e) {
+ rethrow;
+ }
+ }
+}
diff --git a/frontend/flutter_vision-master/lib/src/plugin/base.dart b/frontend/flutter_vision-master/lib/src/plugin/base.dart
new file mode 100644
index 0000000000..0245f4def3
--- /dev/null
+++ b/frontend/flutter_vision-master/lib/src/plugin/base.dart
@@ -0,0 +1,106 @@
+import 'dart:convert';
+import 'dart:io';
+import 'package:path/path.dart';
+import 'package:flutter/services.dart';
+import 'package:path_provider/path_provider.dart';
+
+abstract class BaseFlutterVision {
+ // ignore: constant_identifier_names
+ static const String TESS_DATA_CONFIG = 'assets/tessdata_config.json';
+ // ignore: constant_identifier_names
+ static const String TESS_DATA_PATH = 'assets/tessdata';
+ static const MethodChannel _channel = MethodChannel('flutter_vision');
+ MethodChannel get channel => _channel;
+
+ Future