· case-study · 2 min read

Flutter와 YOLOv8로 만든 현장형 FFB 수확 데이터 플랫폼

1) 포트폴리오 소개 : - 일팜 수확 현장에서 FFB(Fresh Fruit Bunch) 수확량, 숙성 상태, Sack 무게, GPS 위치, 운송 상태를 모바일에서 기록하고, YOLOv8 기반 비디오/이미지 감지와 역할별 업무 흐름을 결합한 Flutter Android 앱 2) 작업 범위 : - 앱: Flutter / Dart - Android 네이티브: Kotlin, MethodChannel, EventChannel - AI 추론: YOLOv8, TFLite, `tflite_flutter`, `flutter_vision` - 객체 추적: IoU 기반 BunchTracker, Motion Vector, 프레임 스킵 보정 - 지도/GPS: Google Maps Flutter, Geolocator/Location, GPS fallback - 로컬 저장: JSON 파일, SharedPreferences - 서버 연동: AWS API Gateway 계열 REST API, S3 업로드 URL 방식 - 알림/백그라운드: Firebase Messaging, local notifications, foreground task - 다국어: Flutter intl, 영어/프랑스어/스페인어/포르투갈어/말레이어/인도네시아어/태국어 중심 3) 주요 기능 : - FFB 수확 수량 - 수확/검수/운송/공장 도착 상태 - GPS 위치 - 수확 사진과 Sack 무게 - YOLOv8 기반 FFB 감지 결과 - 작업자 역할별 데이터 흐름

Flutter와 YOLOv8로 만든 현장형 FFB 수확 데이터 플랫폼

오일팜 수확 현장의 데이터는 책상 위에서 만들어지지 않는다. 작업자는 농장 블록을 이동하고, 네트워크는 끊기고, GPS는 흔들리며, 수확물은 사진과 수량, 무게, 운송 상태까지 함께 기록되어야 한다. Agrevo Android 프로젝트는 이런 환경을 전제로 만든 Flutter 기반 현장 데이터 수집 앱이다. 핵심은 단순한 모바일 입력 폼이 아니라, 역할별 워크플로우, YOLOv8 기반 FFB 감지, 로컬 JSON 저장, 지도 기반 상태 추적, 백그라운드 비디오 분석을 하나의 현장 흐름으로 묶는 것이었다.

현장 앱의 첫 번째 조건: 오프라인에서도 기록이 남아야 한다.

이 프로젝트의 기본 데이터 단위는 OnRoadFFB다. 하나의 수확 기록에는 촬영 시간, GPS 좌표, 블록 번호, 수확자 정보, 트럭 번호, FFB 이미지, Sack 이미지, 무게, 업로드 상태, 검수 상태, 운송 상태, 공장 도착 상태가 함께 들어간다.

서버 전송보다 먼저 고려한 것은 로컬 저장이었다. 현장에서는 네트워크가 항상 안정적이지 않기 때문에, 기록은 먼저 앱 내부 JSON 파일로 저장된다. 이후 업로드가 성공하면 Uploaded 상태가 바뀌고, 사용자가 데이터를 다시 수정하면 자동으로 재업로드 대상이 된다. 이 방식은 데이터 유실을 줄이고, 작업자가 인터넷 연결 상태를 의식하지 않아도 업무를 이어갈 수 있게 만든다.

AI 객체인식 기반 수확물 관리 어플

역할별로 다른 앱이어야 했다.

현장에는 여러 종류의 사용자가 있다. 수확자, 검수자, 운송자, 관리자는 같은 데이터를 보더라도 해야 할 일이 다르다. 그래서 앱은 Harvester, Checker, Trucker, Manager 역할을 기준으로 화면과 데이터 흐름을 분리했다.

Harvester는 수확 데이터를 입력하고, Checker는 수확자 이름과 검수 상태를 남기며, Trucker는 사진 촬영 없이 텍스트 기반으로 수거 데이터를 기록한다. Manager는 직접 수집보다 조회와 내보내기에 집중한다.

특히 Trucker는 별도 설계가 필요했다. 운송자는 여러 수확 지점의 FFB를 한 번의 운송 단위로 묶어야 한다. 이를 위해 Trip ID를 만들고, 같은 Trip에 속한 수거 기록을 리스트에서 하나의 그룹으로 표시했다. 공장 도착 시에는 Trip 전체에 총 중량을 입력하고, 그룹 내 모든 항목을 공장 도착 상태로 바꾼다.

AI 객체인식 기반 수확물 관리 어플

AI 감지는 모델보다 후처리가 더 어려웠다

FFB 감지는 YOLOv8 기반으로 구현했다. 하지만 실제 개발에서 어려웠던 부분은 모델 실행 자체가 아니라, 프레임별 감지 결과를 일관된 객체로 추적하고 최종 카운트와 상태를 안정적으로 만드는 일이었다.

초기 Python 알고리즘과 Dart 구현은 같은 영상을 넣어도 결과가 달라질 수 있었다. Python은 마지막으로 감지된 클래스를 최종 태그로 사용했고, 기존 Dart 코드는 우선순위 기반으로 태그를 결정했다. 스킵 프레임 처리 방식도 달라서 긴 영상에서 동일 객체가 새 객체로 잡힐 수 있었다.

이를 해결하기 위해 Python 알고리즘과 Dart 구현을 비교했고, 이후 Copil 기반 추적기로 통합했다. IoU 기반 중복 제거, Motion Vector, 객체 매칭, 최종 필터링 기준을 명확히 하고, 분석 설정값을 앱 설정에서 조정할 수 있도록 했다.

AI 객체인식 기반 수확물 관리 어플

백그라운드 분석은 별도의 아키텍처 문제였다.

긴 비디오 분석은 사용자가 화면을 계속 켜둔 상태에서만 동작하면 안 된다. 그래서 백그라운드 분석을 Android 네이티브 코드와 연결했다.

포그라운드에서는 Dart 기반 프레임 추출, TFLite 추론, NMS, BunchTracker가 동작한다. 백그라운드에서는 Kotlin의 MediaMetadataRetriever, 네이티브 TFLite 실행, MethodChannel/EventChannel, foreground notification이 관여한다.

이때 가장 큰 문제는 전환 시점의 추적 상태였다. 단순히 영상의 시작 시점만 넘기면 백그라운드 분석은 이어서 실행되지만, 트래커 내부의 객체 ID와 Motion Vector 히스토리는 사라진다. 결과적으로 이미 추적하던 FFB가 새 객체로 카운트될 수 있다.

해결책은 트래커 상태 직렬화였다. 포그라운드 트래커의 객체 목록, 마지막 ID, 스킵 카운트, Motion Vector 히스토리, 처리 프레임 정보를 JSON으로 저장하고, 백그라운드 서비스가 이를 복원해 분석을 이어가도록 했다. 이 방식으로 화면 전환 이후에도 기존 객체 ID를 유지하고 중복 카운트를 줄일 수 있었다.

지도는 단순 표시가 아니라 상태 관리 화면이다

지도에서는 수확, 검수, 수거, 공장 도착 상태를 마커 아이콘으로 구분한다. 기본 수확 마커, 검수 완료 마커, 운송 완료 마커, 공장 도착 마커가 상태 우선순위에 따라 표시된다.

역할별 필터링도 다르다. Harvester는 로컬 기록 중심으로 보고, Checker는 당일 데이터를 중심으로 보며, Trucker는 아직 수거되지 않은 항목을 중심으로 본다. Manager는 운영 관점에서 당일 수확과 미수거 위치를 확인한다.

또한 GPS가 실패할 때를 대비해 마지막 성공 위치를 SharedPreferences에 저장하고, 다음 지도 진입 시 fallback으로 사용했다. 네트워크가 없어도 로컬 마커는 계속 보여야 하므로, 오프라인일 때 지도 전체를 막는 대신 서버 마커 요청만 생략하도록 개선했다.

작은 UX 수정이 데이터 품질을 바꾼다.

현장 앱에서는 작은 UI 조건 하나가 데이터 품질에 직접 영향을 준다. 예를 들어 업로드 버튼 활성화 조건이 미확인 데이터 수에 묶여 있으면, 데이터를 열어 확인한 뒤 수정했을 때 업로드 버튼이 비활성화될 수 있다. 실제로 이 문제는 전체 수 - 업로드 완료 수 기준으로 조건을 바꿔 해결했다.

또 다른 예는 이미지 편집 화면의 Save 버튼이다. 하단 고정 버튼이 감지 박스를 가리면 사용자는 박스 조정을 제대로 할 수 없다. 그래서 FFB/Sack 에디터에는 Save 바 접기/펼치기 토글을 추가했다.

이런 수정은 화려하지 않지만, 현장 데이터 수집 앱에서는 매우 중요하다. 사용자가 기록을 편하게 수정할 수 있어야 데이터가 정확해지고, 업로드 조건이 명확해야 운영자가 누락 데이터를 줄일 수 있다.

마무리

Agrevo Android 프로젝트는 Flutter 앱 개발, Android 네이티브 연동, YOLOv8 추론, 객체 추적, 지도/GPS, 오프라인 저장, 역할 기반 UX가 모두 들어간 현장형 개발 사례다. 중요한 점은 기술을 많이 넣었다는 것이 아니라, 불안정한 현장 환경에서 데이터가 끊기지 않도록 각 기술을 업무 흐름 안에 배치했다는 점이다.

이 개발을 통해 얻은 가장 큰 결론은 명확하다. 현장 앱은 입력 화면을 만드는 일이 아니라, 데이터가 생성되고, 검수되고, 운송되고, 업로드되고, 다시 조회되는 전 과정을 끊기지 않게 설계하는 일이다.

요약

  • Flutter 기반 Android 현장 데이터 수집 앱
  • YOLOv8 기반 FFB 감지 및 객체 추적
  • Harvester, Checker, Trucker, Manager 역할별 워크플로우
  • 오프라인 우선 로컬 JSON 저장 및 재업로드 구조
  • Google Maps 기반 수확/검수/운송/공장 도착 상태 시각화
  • Kotlin 네이티브 기반 백그라운드 비디오 분석
  • 트래커 상태 직렬화로 백그라운드 전환 중 중복 카운트 방지

관련 서비스

3d웹, 3dweb, 3d 컨피규레이터, 3D 제품 컨피규레이터, 3D 제품 뷰어, WebGPU, Three.js

← 인사이트로

프로젝트 문의