K-pop 포토카드 수집 앱. 소지한 포카 사진을 찍으면 AI가 자동으로 인식해 보관함에 추가해줍니다.
- 포카 인식: CLIP 모델로 실물 포카 사진을 찍으면 DB의 포카와 매칭
- 보관함 관리: 아이돌/멤버별 포카 수집 현황 확인
- 관리자 기능: 아이돌·멤버 등록, 포카 이미지 직접 업로드, 멤버 분류
- 회원 시스템: 회원가입/로그인, 개인 보관함
| 역할 | 기술 |
|---|---|
| Backend | FastAPI |
| AI 인식 | CLIP (clip-ViT-B-32) via sentence-transformers |
| DB | PostgreSQL + pgvector |
| 비동기 작업 | Celery + Redis |
| 배포 | Docker Compose |
- Docker & Docker Compose
.env 파일을 생성하고 아래 값을 채워주세요.
POSTGRES_USER=your_db_user
POSTGRES_PASSWORD=your_db_password
POSTGRES_DB=your_db_name
DATABASE_URL=postgresql://your_db_user:your_db_password@db:5432/your_db_name
REDIS_URL=redis://redis:6379/0
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your_admin_password
SECRET_KEY=your_secret_key
ALLOWED_ORIGINS=http://localhost:8000docker compose up --buildhttp://localhost:8000 에서 접속 가능합니다.
- 관리자 계정으로 로그인
- 데이터 센터 진입
- 아이돌/멤버 추가
- 포카 이미지(스캔본 권장) 업로드 및 멤버 분류
- 회원가입 후 로그인
- 아이돌 선택 → 보관함 진입
- 📸 버튼으로 실물 포카 촬영
- AI가 매칭 성공하면 자동으로 보관함에 추가
- 포카 인식은 DB에 등록된 동일한 포카의 실물 사진을 찍었을 때 작동합니다.
- 같은 멤버라도 다른 컨셉/버전의 포카는 인식되지 않습니다.
- 포카 이미지는 스캔본으로 등록하는 것을 권장합니다.
포카 수집하다가 직접 만들어보고 싶어서 시작한 프로젝트다.
처음엔 별거 없을 것 같았는데 막상 만들다 보니 생각보다 삽질을 많이 했다.
제일 힘들었던 게 유사도 임계값 문제였는데, 같은 포카인데 스캔본이랑 실물 사진 유사도가 0.762가 나오고 다른 포카는 0.768이 나왔다. 근데 이게 완벽하게 구분이 안 되는 거라 어떤 임계값을 잡아도 둘 중 하나는 틀리게 됨. 그냥 임계값 좀 낮추고 "이 포카 맞아요?" 확인창 띄워서 사용자가 직접 판단하게 했다.
이미지 중복 체크도 처음엔 image_url에 UNIQUE 걸었다가 base64 이미지를 통째로 인덱싱하려니까 PostgreSQL 인덱스 크기 제한 초과 오류가 났다. MD5 해시 컬럼 따로 파서 해결했다.
pgvector 처음 써봤는데 벡터 유사도 검색을 SQL에서 바로 할 수 있어서 편했고, AI 추론을 Celery로 비동기 처리한 것도 잘한 것 같다. 그냥 동기로 했으면 사진 올릴 때마다 앱이 멈췄을 거다.
아쉬운 건 인식 정확도인데, 스캔본으로 등록해야 그나마 잘 된다. 실물 사진끼리 비교하면 조명이랑 각도 차이 때문에 유사도가 많이 떨어진다. 나중에 시간 되면 파인튜닝된 모델로 바꿔보고 싶다.