Initialize recipe recognition repository
This commit is contained in:
+52
@@ -0,0 +1,52 @@
|
|||||||
|
# Python bytecode and caches
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
.pytest_cache/
|
||||||
|
.mypy_cache/
|
||||||
|
.ruff_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
|
||||||
|
# Packaging and build output
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
.eggs/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
|
||||||
|
# Local configuration and secrets
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
|
||||||
|
# Local databases and runtime files
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
instance/
|
||||||
|
uploads/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# IDE and OS files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Common binary artifacts
|
||||||
|
*.bin
|
||||||
|
*.exe
|
||||||
|
*.so
|
||||||
|
*.dll
|
||||||
|
*.zip
|
||||||
|
*.tar
|
||||||
|
*.gz
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
Пользователь:
|
||||||
|
/home/naeel/MED/recipe/PLAN/recipe1.png - пример рецепта
|
||||||
|
/home/naeel/MED/recipe/PLAN/gemini.md - то что жемини советует
|
||||||
|
|
||||||
|
надо - план создания приложения для андроида, которое
|
||||||
|
1. будет вычленять прямоукльник с датой рецепта и прямоугольник с названиями/дозировками лекарств и отправлять выделенное на сервер для дальнейшей обработки
|
||||||
|
2. после обработки сервер перешлёт обратно в приложение распознынне данные, которое приложение выведет на экран на место рукописного текста
|
||||||
|
пример - как гугл переводчик в режиме распознавания
|
||||||
|
|
||||||
|
ФИО ДР пациента не должны быть копированы, их прямоугольник не доолжен выделяться. или - выделяться но явно показываться что не используется, заблюрены или как то иначе
|
||||||
|
|
||||||
|
план - коротко, без воды, понятно, НИКАКОГО КОДА, кодить будут агенты, от тебя - архитектурные идеи, что гового из библиотек можно использовать, что - писать самим
|
||||||
|
|
||||||
|
задание понятно ?
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
Задание понятно. Изучил рецепт и план Gemini. Готовлю архитектурный план.
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
---
|
||||||
|
|
||||||
|
## План: Android-приложение распознавания рецепта
|
||||||
|
|
||||||
|
**Суть:** снимок бланка → выделение зон → OCR на сервере → наложение текста поверх рукописного (AR-режим). Зона ФИО/ДР — визуально заблюрена, на сервер не отправляется.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Архитектура (4 слоя)
|
||||||
|
|
||||||
|
```
|
||||||
|
Camera → [Document Scanner] → aligned bitmap
|
||||||
|
↓
|
||||||
|
[Zone Detector] ←— ML Kit Text Recognition
|
||||||
|
↓
|
||||||
|
PATIENT | DATE | MEDICATIONS | OTHER
|
||||||
|
↓blur ↓ ↓
|
||||||
|
не отправляется POST /api/v1/recognize
|
||||||
|
↓
|
||||||
|
[Server OCR]
|
||||||
|
↓
|
||||||
|
JSON {date, medications[]}
|
||||||
|
↓
|
||||||
|
[AR Overlay Renderer]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Клиент — Android / Kotlin / Compose
|
||||||
|
|
||||||
|
**Готовые библиотеки:**
|
||||||
|
- `ML Kit Document Scanner` — захват + перспективная коррекция бланка
|
||||||
|
- `ML Kit Text Recognition v2` — определение bounding boxes зон
|
||||||
|
- `Ktor Client` — HTTP + kotlinx.serialization
|
||||||
|
- `Jetpack Compose + Material 3` — UI
|
||||||
|
- `Coil Compose` — отображение bitmap
|
||||||
|
|
||||||
|
**Писать самим:**
|
||||||
|
- **Zone Classifier** — эвристика: y-позиция блока + ключевые слова ("Rp.", "Ф.И.О.", "Дата рождения")
|
||||||
|
- **Privacy Masking** — Compose Canvas: blur overlay на PATIENT-зоне
|
||||||
|
- **AR Overlay Renderer** — Compose Canvas с наложением текста поверх изображения
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Сервер — Python / FastAPI
|
||||||
|
|
||||||
|
**Готовые:**
|
||||||
|
- `FastAPI + pydantic` — API
|
||||||
|
- `Google Cloud Vision API` или `Azure Computer Vision` — OCR рукописи
|
||||||
|
- `Tesseract 5 + LSTM` — self-hosted альтернатива
|
||||||
|
|
||||||
|
**Писать самим:**
|
||||||
|
- Обёртка OCR API
|
||||||
|
- Парсер структуры лекарств
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Фазы
|
||||||
|
|
||||||
|
1. Capture + Alignment
|
||||||
|
2. Zone Detection + Privacy
|
||||||
|
3. Server OCR
|
||||||
|
4. AR Overlay
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Пользователь:
|
||||||
|
надо учитывать что это - названия лекарств то есть ограниченный набор слов
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
Важное замечание. Это даёт два преимущества:
|
||||||
|
|
||||||
|
1. На сервере — нормализация через справочник.
|
||||||
|
2. В промпте LLM — контекст ограниченного словаря.
|
||||||
|
3. В Zone Classifier — дополнительные сигналы вроде `Rp.`, `Tab.`, `мг`, `мл`.
|
||||||
|
|
||||||
|
Результат должен нормализоваться по справочнику лекарственных средств, например через `rapidfuzz` и локальную SQLite-копию ГРЛС. Низкая уверенность помечается как `uncertain: true` и показывается пользователю для проверки.
|
||||||
|
|
||||||
|
Пользователь:
|
||||||
|
- `gpt-oss-120b`
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
`gpt-oss-120b` — модель на GitHub Models / Azure AI Foundry с OpenAI-совместимым API. В серверной части вместо отдельного OCR API и дополнительного парсера можно использовать один вызов Vision LLM, если конкретный endpoint принимает изображения.
|
||||||
|
|
||||||
|
Пользователь:
|
||||||
|
120 billions наврное это ознавает
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
Да, скорее всего «120B» означает 120 миллиардов параметров. Уточните: это конкретная модель, которая уже у вас развёрнута, или планируете деплоить? И это Vision-модель, принимающая изображения?
|
||||||
|
|
||||||
|
Пользователь:
|
||||||
|
- `gpt-oss-120b`
|
||||||
|
|
||||||
|
Ассистент:
|
||||||
|
Хорошо. Вот финальный обновлённый план:
|
||||||
|
|
||||||
|
## План: Android-приложение распознавания рецепта
|
||||||
|
|
||||||
|
**Суть:** снимок бланка → выделение зон → Vision LLM на сервере → AR-наложение распознанного текста. Зона ФИО/ДР — заблюрена, на сервер не отправляется.
|
||||||
|
|
||||||
|
### Архитектура
|
||||||
|
|
||||||
|
```
|
||||||
|
Camera → [ML Kit Document Scanner] → aligned bitmap
|
||||||
|
↓
|
||||||
|
[ML Kit Text Recognition v2]
|
||||||
|
↓
|
||||||
|
[Zone Classifier]
|
||||||
|
/ | \\
|
||||||
|
PATIENT DATE MEDICATIONS
|
||||||
|
(blur, ↓ ↓
|
||||||
|
не шлём) POST /api/v1/recognize
|
||||||
|
↓
|
||||||
|
[FastAPI + gpt-oss-120b]
|
||||||
|
один Vision LLM запрос →
|
||||||
|
JSON {date, medications[]}
|
||||||
|
↓
|
||||||
|
[AR Overlay Renderer]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Клиент — Android / Kotlin / Compose
|
||||||
|
|
||||||
|
**Готовые:**
|
||||||
|
- ML Kit Document Scanner
|
||||||
|
- ML Kit Text Recognition v2
|
||||||
|
- Ktor Client + kotlinx.serialization
|
||||||
|
- Jetpack Compose + Material 3 + Coil Compose
|
||||||
|
|
||||||
|
**Писать самим:**
|
||||||
|
- Zone Classifier для нескольких форм бланков
|
||||||
|
- Form Detector
|
||||||
|
- Privacy Masking
|
||||||
|
- AR Overlay Renderer
|
||||||
|
|
||||||
|
### Сервер — Python / FastAPI
|
||||||
|
|
||||||
|
**Готовые:**
|
||||||
|
- FastAPI + pydantic
|
||||||
|
- openai Python SDK для gpt-oss-120b
|
||||||
|
|
||||||
|
**Писать самим:**
|
||||||
|
- LLM-промпт с возвратом строго JSON
|
||||||
|
- Валидация ответа pydantic
|
||||||
|
- Retry при невалидном JSON
|
||||||
|
- Нормализация названий лекарств по справочнику ГРЛС
|
||||||
|
|
||||||
|
### Протокол
|
||||||
|
|
||||||
|
Request `POST /api/v1/recognize`:
|
||||||
|
|
||||||
|
```
|
||||||
|
zones: [
|
||||||
|
{ type: "DATE", image: "<base64 JPEG>" },
|
||||||
|
{ type: "MEDICATIONS", image: "<base64 JPEG>" }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
date: "12.03.2025",
|
||||||
|
medications: [
|
||||||
|
{
|
||||||
|
name: "Амоксициллин",
|
||||||
|
raw: "Амоксицил",
|
||||||
|
uncertain: false,
|
||||||
|
dose: "500 мг",
|
||||||
|
instructions: "3 р/день"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Фазы
|
||||||
|
|
||||||
|
1. Capture
|
||||||
|
2. Zone Detection + Privacy
|
||||||
|
3. Server LLM OCR
|
||||||
|
4. AR Overlay
|
||||||
|
|
||||||
|
### Ограниченный набор названий лекарств
|
||||||
|
|
||||||
|
Названия лекарств нужно проверять по справочнику, а не принимать ответ LLM без проверки. Рекомендуется хранить локальную SQLite-копию ГРЛС: МНН, торговые названия, формы выпуска и дозировки. Для сопоставления использовать `rapidfuzz`; при низком совпадении возвращать `uncertain: true`. Нельзя автоматически подменять сомнительное название без показа пользователю и возможности исправления.
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
```kotlin
|
||||||
|
// filename: AndroidCropPipelinePlan.md
|
||||||
|
// Architectural plan for building an Android handwriting text block cropper MVP using ML Kit.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Архитектура приложения
|
||||||
|
|
||||||
|
Приложение нацелено на максимальную скорость и простоту: оно получает кадр с камеры, определяет границы бланка рецепта, выравнивает его, находит области с рукописным текстом и отправляет нарезку на бланке в виде массива `Base64` на бэкенд.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Библиотеки и стек (Android / Kotlin)
|
||||||
|
|
||||||
|
* **UI Framework:** Jetpack Compose + Material 3.
|
||||||
|
* **Camera:** `androidx.camera:camera-camera2` (CameraX).
|
||||||
|
* **Document Scanner (Выравнивание бланка):** `com.google.android.gms:play-services-mlkit-document-scanner` (Google ML Kit Document Scanner API).
|
||||||
|
* **Text Detection (Поиск BoundingBoxes):** `com.google.android.gms:play-services-mlkit-text-recognition` (ML Kit Text Recognition).
|
||||||
|
* **Network / HTTP:** `io.ktor:ktor-client-android` + `io.ktor:ktor-client-content-negotiation` (Ktor Client).
|
||||||
|
* **Image Processing:** `io.coil-kt:coil-compose` (отображение) + стандартный `android.graphics.Bitmap`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Пошаговый план разработки для Агента
|
||||||
|
|
||||||
|
#### 1. Инициализация и разрешения
|
||||||
|
|
||||||
|
* Настроить `build.gradle.kts` с указанными выше библиотеками.
|
||||||
|
* Запросить стандартные разрешения `CAMERA` и доступ к хранилищу.
|
||||||
|
|
||||||
|
#### 2. Захват и выравнивание бланка (Document Scanner)
|
||||||
|
|
||||||
|
* Использовать `GmsDocumentScannerOptions`:
|
||||||
|
* Режим: `SCANNER_MODE_FULL`.
|
||||||
|
* Формат: `RESULT_FORMAT_JPEG`.
|
||||||
|
* Лимит страниц: `1`.
|
||||||
|
|
||||||
|
|
||||||
|
* Запустить интентом `GmsDocumentScanning.getClient(options).getStartScanIntent(...)`.
|
||||||
|
* Получить обратно отсканированный, обрезанный и выровненный `Uri` рецепта.
|
||||||
|
|
||||||
|
#### 3. Поиск рукописных прямоугольников (Bounding Boxes)
|
||||||
|
|
||||||
|
* Преобразовать `Uri` выровненного бланка в `InputImage.fromFilePath`.
|
||||||
|
* Запустить `TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)`.
|
||||||
|
* Из полученного `Text` пройтись по `Text.TextBlock` или `Text.Line`.
|
||||||
|
* Извлечь прямоугольники: `val rect: Rect? = block.boundingBox`.
|
||||||
|
|
||||||
|
#### 4. Нарезка Bitmap (Cropping)
|
||||||
|
|
||||||
|
* Загрузить исходный `Bitmap` бланка.
|
||||||
|
* Для каждого полученного `Rect` выполнить:
|
||||||
|
```kotlin
|
||||||
|
val cropBitmap = Bitmap.createBitmap(
|
||||||
|
originalBitmap,
|
||||||
|
rect.left,
|
||||||
|
rect.top,
|
||||||
|
rect.width(),
|
||||||
|
rect.height()
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
* Конвертировать каждый `cropBitmap` в строку Base64 (JPEG, quality 90).
|
||||||
|
|
||||||
|
#### 5. Отправка на бэкенд
|
||||||
|
|
||||||
|
* Сформировать DTO:
|
||||||
|
```kotlin
|
||||||
|
@Serializable
|
||||||
|
data class RecipePayload(
|
||||||
|
val clientVersion: String = "1.0",
|
||||||
|
val snippets: List<String> // Array of Base64 strings
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
* Отправить `POST`-запрос через Ktor на эндпоинт `/api/v1/recognize`.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 MiB |
Reference in New Issue
Block a user