← 전체 프로젝트

Food Safe Vision

카메라로 식품과 유통기한을 인식해 자동으로 등록·관리하는 Android 앱

기간
2024.10 – 2024.12
구성
캡스톤 디자인 — Android 앱 구현 담당
내 역할
Android 앱 구현 전반 — 카메라 인식(바코드·객체·문자)부터 로컬 DB·알림까지 (구현은 AI 페어)
KotlinJetpack ComposeCameraXML KitPyTorchRoom

한눈에

식품 목록 화면 — 유통기한 D-day 표시 식품 등록 화면 — 이름·유통기한·태그·수량 설정 화면 — 임박 기준일과 알림 시각

앱 핵심 화면 — 등록한 식품이 유통기한 임박 순으로 쌓이고(왼쪽, D-2는 빨갛게 강조), 등록 화면에서 이름·날짜·태그·수량을 확정하며(가운데), 설정한 기준일·시각에 임박 알림을 받는다(오른쪽).

내가 맡은 범위

캡스톤에서 안드로이드 앱 구현 전부를 내가 맡았다 — 화면, 카메라 연동, 세 가지 인식, 로컬 데이터베이스, 알림까지. (기획 논의·보고서·테스트·발표는 팀원들과 나눴다.)

내가 내린 설계 결정

식품을 등록하는 길을 네 갈래로 — 무엇이든 등록되게

바코드가 있는 공산품도 있고, 바코드가 없는 과일·채소도 있고, 인쇄가 흐려 인식이 안 되는 것도 있다. 한 가지 방법만 두면 나머지는 등록을 못 한다. 그래서 입력 경로를 네 가지로 두었다 — ① 바코드 스캔, ② 사진으로 식품 종류 자동 인식, ③ 유통기한 문자 인식, ④ 직접 입력. 앞 단계가 실패하면 자연스럽게 다음·수동 입력으로 넘어가, 어떤 식품이든 끝까지 등록되도록 한 것이 핵심 설계다.

바코드 인식 카메라 화면 식품 사진 자동 인식 카메라 화면 유통기한 문자 인식 카메라 화면

카메라 인식 3종 — 바코드 스캔(왼쪽), 식품 사진 자동 인식(가운데), 유통기한 문자 인식(오른쪽). 모두 휴대폰 안에서 실시간으로 처리한다.

인터넷 없이 휴대폰 안에서 — 온디바이스 처리

바코드·문자·사진 인식을 모두 휴대폰 안에서(온디바이스) 처리하도록 ML Kit와 PyTorch 모델을 앱에 직접 넣었다. 서버로 사진을 보내지 않으니 네트워크가 없어도 즉시 동작하고, 식품 사진이 밖으로 나가지 않아 프라이버시에도 안전하다. 카메라는 최신 프레임만 분석하도록(STRATEGY_KEEP_ONLY_LATEST) 설정해 실시간 인식이 끊기지 않게 했다.

날짜를 자주 틀리게 읽는 문자 인식 — 후보정 + 직접 선택

유통기한은 글씨가 작고 포장이 구겨져 문자 인식이 자주 틀린다. 특히 숫자 0을 알파벳 O로, 2를 Z로 잘못 읽는다. 그래서 인식된 글자에 후보정 규칙(O→0, Z→2, 쉼표·슬래시→점)을 적용하고, YYYY-MM-DD·MM-DD-YYYY 등 여러 표기를 한 형식으로 통일한 뒤, 연도 2000–2100·월 1–12·일 1–31 범위로 검증해 엉뚱한 날짜를 걸렀다. 그래도 인식이 안 되면 달력에서 직접 선택할 수 있게 두었다.

잘 안 된 것을 솔직히 — 식품 자동 인식의 한계

사진으로 식품 종류를 알아내는 자동 인식은 ImageNet으로 미리 학습된 MobileNet V3 모델을 그대로 가져다, 그 1000개 분류 중 식품에 해당하는 클래스만 골라 쓰는 방식이었다. 식품 전용 데이터로 다시 학습한 것이 아니라서 인식 범위가 좁고 정확도가 낮았다. 그래서 실제 등록은 바코드·문자 인식·직접 입력이 주력이고, 사진 자동 인식은 보조에 가깝다. 한계를 알기에 “식품 특화 데이터셋으로 다시 학습”을 향후 과제로 남겼다.

유통기한을 한눈에 — D-day 목록과 임박 알림

등록한 식품은 유통기한이 가까운 순으로 정렬해, 남은 일수를 D-7·D-1·D+2처럼 보여주고 임박한 것은 빨갛게 강조했다. 냉장고를 여러 개(태그) 나눠 관리할 수 있고, 임박 기준일(1–30일)과 알림 시각을 사용자가 직접 설정하면 그 조건에 맞는 식품을 매일 정한 시각에 알려준다.

정직하게 — 내가 한 일

이 프로젝트에서 내가 만든 것은 안드로이드 앱 구현 전체 — 화면, 카메라 연동, 세 가지 인식(바코드·사진·문자), 로컬 DB, 알림까지다. 구현은 AI를 페어로 했다. 기획 논의·보고서·테스트·발표는 팀원들과 함께 나눴다.