--- title: Stella Score Reader emoji: 🏒 colorFrom: yellow colorTo: gray sdk: docker pinned: false --- # stella_score_reader_backend 인쇄 악보λ₯Ό μΉ΄λ©”λΌλ‘œ 찍어 ν¬λ‘­ν•œ **ν•œ 쀄 μ˜€μ„ (staff)** 이미지λ₯Ό μž…λ ₯으둜 λ°›μ•„, λͺ¨λ°”일 앱이 λ°”λ‘œ μž¬μƒ/νŽΈμ§‘ν•  수 μžˆλŠ” **단일 λ©œλ‘œλ”” JSON**을 λ°˜ν™˜ν•˜λŠ” OMR API μ„œλ²„μž…λ‹ˆλ‹€. ν˜„μž¬ λͺ©ν‘œλŠ” 단일 μ—”λ“œν¬μΈνŠΈ `POST /analyze`(v1 단일 μŠ€νƒœν”„ μŠ€νŽ™)λ₯Ό μ•ˆμ •μ μœΌλ‘œ μ œκ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. ## 핡심 λͺ©ν‘œ - μž…λ ₯: **이미지당 μ˜€μ„  ν•œ 쀄**만 μžˆλ‹€κ³  κ°€μ •ν•œ 크둭 사진 1μž₯ λ˜λŠ” μ—¬λŸ¬ μž₯(μˆœμ„œλŒ€λ‘œ 이어짐) - **μŒμžλ¦¬ν‘œΒ·μ‘°ν‘œ**λŠ” 잘렀 λ‚˜κ°ˆ 수 μžˆμœΌλ―€λ‘œ, `multipart` ν•„λ“œ **`score_context`(JSON)** 둜 λ°˜λ“œμ‹œ 전달 - 좜λ ₯: **`melody.events` ν•˜λ‚˜λ‘œ λ³‘ν•©λœ JSON**(λ‹€μž₯이면 μ‹œκ°„μΆ•λ§Œ 이어 λΆ™μž„). MusicXML 등은 API 응닡에 ν¬ν•¨ν•˜μ§€ μ•ŠμŒ - ν™”μŒ(μ΅œλŒ€ 2μ„±λΆ€)은 **졜고음**으둜 쀄여 λ©œλ‘œλ””μ— 반영 μžμ„Έν•œ 계약은 `docs/analyze-api-spec.md`λ₯Ό λ”°λ¦…λ‹ˆλ‹€. ## λ¬Έμ„œ - API/데이터 λͺ¨λΈ 상세: `docs/analyze-api-spec.md` - ν”„λ‘ νŠΈ 연동 κ°€μ΄λ“œ(ν•„λ“œ 사전): `docs/frontend-integration-guide.md` - 응닡 JSON ν˜•νƒœ μ˜ˆμ‹œ(참고용): `docs/analyze-response-format-examples.json` ## 기술 μŠ€νƒ - Python 3.11+ - FastAPI - OpenCV (`opencv-python-headless`) - NumPy - PyTorch(CPU) + `transformers`(κΈ°λ³Έ λͺ¨λΈ: [Flova/omr_transformer](https://huggingface.co/Flova/omr_transformer)) - μ „μ²˜λ¦¬: `score_preprocess.py`(κΈ΄ λ³€ μƒν•œ μΆ•μ†Œ, LAB μ‘°λͺ… μ •κ·œν™”, CLAHE, bilateral, μ†Œκ°λ„ 데슀큐 λ“±; bboxλŠ” μ—…λ‘œλ“œ 원본 ν”½μ…€λ‘œ μ—­λ³€ν™˜) - μ˜€μ„  κ΅­μ†Œ 보정: `staff_rectify.py`(μƒ˜ν”Œλ§ + 닀항식 μ„Έλ‘œ `remap`) - ν™˜κ²½ λ³€μˆ˜: - `STELLA_OMR_DISABLE=1` β€” 신경망 끄고 OpenCV만(λ‘œμ»¬Β·ν…ŒμŠ€νŠΈ) - `STELLA_OMR_MODEL_ID` β€” λ‹€λ₯Έ HF λͺ¨λΈ ID - `STELLA_OMR_MAX_LENGTH` β€” Donut `generate` 토큰 μƒν•œ(κΈ°λ³Έ `1024`, λͺ¨λΈ `decoder.max_length`보닀 μž‘μ§€ μ•Šκ²Œ 반영) - `STELLA_OMR_MAX_LENGTH_CAP` β€” μœ„ κ°’μ˜ ν•˜λ“œ μƒν•œ(κΈ°λ³Έ `2048`, OOMΒ·μ§€μ—° μ™„ν™”) - `STELLA_MAX_EVENTS_PER_STAFF` β€” 응닡에 λ„£λŠ” 음 이벀트 개수 μƒν•œ per μŠ€νƒœν”„(κΈ°λ³Έ `256`, μ˜ˆμ „ `64`μ—μ„œ 상ν–₯) - `STELLA_PREPROCESS_MAX_SIDE` β€” λ‹€μš΄μŠ€μΌ€μΌ μƒν•œ(κΈ°λ³Έ `4096`, μ΅œμ†Œ 512둜 ν΄λž¨ν”„) - `STELLA_SKIP_DESKEW=1` β€” 데슀큐 λΉ„ν™œμ„±ν™” ## λΉ λ₯Έ μ‹œμž‘ ```bash pip install -r requirements.txt uvicorn main:app --reload ``` μ„œλ²„ μ‹€ν–‰ ν›„ Swagger UI: - `http://127.0.0.1:8000/docs` ## ν˜„μž¬ κ΅¬ν˜„ μƒνƒœ - `GET /`: ν—¬μŠ€ 체크 - `POST /analyze` (v1): - ν•„μˆ˜ `score_context` + 단건/닀건 `file` / `files` + 선택 `options` - μ „μ²˜λ¦¬ β†’ 단일 μŠ€νƒœν”„ 검증(μ •ν™•νžˆ 1쀄) β†’ `staff_rectify` β†’ `Flova/omr_transformer` β†’ μ‹€νŒ¨ μ‹œ OpenCV λ…ΈνŠΈν—€λ“œ 폴백 - 응닡: `melody`, `segment_map`, `timeline`, `score_context`(에코), `meta.pipeline_mode` = `single_staff_v1` κ΅¬ν˜„ 기쀀은 `docs/analyze-api-spec.md`λ₯Ό λ”°λ¦…λ‹ˆλ‹€.