Brand visibility analysis for Coca-Cola vs Pepsi using custom YOLO detection, Supabase PostgreSQL, and AI-generated marketing reports.
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .envStep-by-step: docs/SUPABASE_SETUP.md (ISSUE-03)
- Create a project at supabase.com
- Run
sql/schema.sqlin the SQL Editor - Copy the Session pooler connection string into
.envasDATABASE_URL
python -m scripts.check_db
python -m scripts.test_db_insert # round-trip insert into videos (ISSUE-04)Place your fine-tuned best.pt in models/ (from Google Colab training).
streamlit run app/streamlit_app.pyapp/ Streamlit UI
src/
config.py Settings from .env
db/ Supabase connection + ORM models
detect_image.py Single-image inference CLI
detect_video.py Video inference CLI
metrics.py Visibility calculations
metrics_export.py Metrics JSON/text export CLI (#9)
crops.py Bbox crop extraction + crop_path (#10)
pipeline.py End-to-end analysis orchestrator
report/ AI marketing report generator
data/
demo/ Demo videos
crops/ Saved logo crops
uploads/ Uploaded videos (runtime)
models/ best.pt (not in Git)
sql/schema.sql Supabase schema (5 tables)
sql/storage.sql Optional Storage bucket for crops
notebooks/ Colab training (to add)
docs/ Project plans + Kanban
# Image detection
python -m src.detect_image --image path/to/image.jpg
# Video detection (persists to Supabase when DATABASE_URL is set)
python -m src.detect_video --video data/demo/sample.mp4
# Skip database write
python -m src.detect_video --video data/demo/sample.mp4 --no-db
# Visibility metrics for a processed video (reads from Supabase)
python -m src.metrics_export --video-id 1
python -m src.metrics_export --video-id 1 --export
# Verify bbox crops on disk match detections.crop_path (#10)
python -m scripts.verify_crops --video-id 1
# Full pipeline (video → DB → metrics → report)
python -c "from pathlib import Path; from src.pipeline import analyze_video; print(analyze_video(Path('data/demo/sample.mp4')))"Detection runs every SAMPLE_STRIDE frames (default 3, set in .env).
Per-brand visible seconds = unique sampled frames with a detection × (stride / fps).
Visibility % = visible_seconds / video_duration × 100.
Balance label: balanced if gap < 5% of duration; else coca_cola_dominant or pepsi_dominant.
detect_video writes brand_summary and competitive_analysis when persisting to Supabase.
Exported files: data/outputs/metrics_{video_id}.json and .txt.
Each detection bbox is cropped from the source video and saved under data/crops/{video_id}/.
The absolute path is stored in detections.crop_path when persisting via detect_video or pipeline.
Streamlit shows up to 12 crop thumbnails after analysis. Optional Supabase Storage: sql/storage.sql.
python -m src.detect_video --video data/demo/demo1.mp4
python -m scripts.verify_crops --video-id <id>docker build -t brandsight .
docker run -p 8501:8501 --env-file .env brandsightRunbook: docs/DEPLOY.md
python -m scripts.smoke_deploy # pre-flight before deploy- Push repo to GitHub (
models/best.ptmust be on the branch) - share.streamlit.io → New app →
app/streamlit_app.py - Paste secrets (see
.streamlit/secrets.toml.example) —DATABASE_URL,GEMINI_API_KEY, etc. - Deploy → verify sidebar Supabase connected → upload a short MP4 and run analysis
Live demo: add URL after deploy, e.g. https://brandsight-equipo1.streamlit.app
| Class ID | Name |
|---|---|
| 0 | coca_cola |
| 1 | pepsi |