Skip to content

Alexmozg123/lighthouse

Repository files navigation

Lighthouse

Desktop-приложение, которое видит все лица на сцене через веб-камеру, позволяет выбрать одно из них кликом и управляет световой головой по DMX так, чтобы луч следил за выбранным человеком.

Стек: Kotlin / JVM, Compose Multiplatform for Desktop, OpenCV YuNet (через JavaCV), Art-Net для DMX, Koin для DI.

Текущий статус

  • Bootstrap проекта (Gradle, Compose, JavaCV).
  • Захват веб-камеры и превью (1280×720, avfoundation на macOS).
  • YuNet face detection — все лица в кадре одновременно, bbox + 5 keypoints.
  • UI выбора POI: клик по лицу → это лицо становится целью прожектора.
  • Face tracking: стабильные ID между кадрами, чтобы выбор не терялся.
  • Art-Net DMX sender + DmxFixture (artnet4j, unicast, multi-fixture ready).
  • Сцены: сохранение/загрузка конфигурации фикстур и калибровки в ~/.lighthouse/scenes/.
  • 4-точечная homography калибровка камера → pan/tilt (с визуальным визардом и полигоном покрытия).
  • Clean Architecture: domain/adapter/app/ui слои; правило зависимостей читается по импортам.
  • One-Euro filter сглаживания движения (pan + tilt, адаптивный cutoff).
  • Edge cases: лицо пропало (blackout работает; hold-last в планах), потеря камеры.

Требования

  • macOS, Linux или Windows.
  • JDK 21 (Temurin рекомендован).
  • Веб-камера.
  • Опционально: QLC+ для отладки без физической световой головы.

Установка

git clone <repo>
cd lighthouse

JDK 21 ставим один раз. macOS:

brew install --cask temurin@21

ONNX-модели хранятся в Git LFS. Установи его до клонирования, иначе вместо модели скачается текстовый указатель и приложение упадёт на старте:

brew install git-lfs
git lfs install

Если Gradle не находит JDK 21 автоматически, пропиши путь в ~/.gradle/gradle.properties (per-machine, в репо не лежит):

org.gradle.java.home=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home

Запуск

./gradlew run

При первом запуске macOS попросит разрешение на доступ к камере — выдай его процессу, который её открыл (Terminal, iTerm или Android Studio).

Сборка дистрибутива

./gradlew packageDmg
./gradlew packageDistributionForCurrentOS

Архитектура

SceneManagerScreen → загрузить / создать SceneData (~/.lighthouse/scenes/)
       │
       ▼
CameraSource (JavaCV) → TrackingPipeline → StateFlow<DetectedFrame>
                              │                      │
                         YuNetDetector          CameraPreview (Compose)
                       (все лица в кадре)       Image + FaceOverlay
                              │
                     SpotlightController
                    (выбранное лицо → pan/tilt)
                              │
                    HomographyMapper (опционально)
                    4-точечная калибровка камера→pan/tilt
                    или линейный fallback если нет калибровки
                              │
                      List<DmxFixture>   ← по одному на голову
                              │
                      ArtNetClient (artnet4j)
                       unicastDmx → QLC+ / голова

Конвейер живёт в одном Flow на Dispatchers.IO. UI подписывается на StateFlow и перерисовывает превью с оверлеем поверх кадра. На каждый кадр SpotlightController пересчитывает координаты центра выбранного лица через гомографическую матрицу (или линейно если калибровки нет) в 16-bit pan/tilt и отправляет Art-Net пакет по unicast на каждую зарегистрированную голову.

Структура проекта

gradle/libs.versions.toml     — version catalog
build.gradle.kts              — Kotlin 2.0 + Compose 1.7 + JavaCV + Koin
src/main/kotlin/tracker/
    Main.kt                          — startKoin + when(AppState.screen)
    di/AppModule.kt                  — Koin: wire-up всех синглтонов
    domain/
        entity/                      — FaceDetection, TrackedFace, SceneData,
                                       DmxFixture, PanTilt, CalibrationData, …
        usecase/                     — FaceTracker, CalibrationUseCase, PositionMapper,
                                       MapperFactory, DmxSender, DmxSenderFactory
        repository/SceneRepository.kt— интерфейс персистентности сцен
    adapter/
        camera/                      — CameraSource, YuNetDetector
        calibration/                 — HomographyMapper (findHomography)
        dmx/                         — ArtNetSender
        persistence/SceneStore.kt    — JSON-файлы в ~/.lighthouse/scenes/
    app/
        AppState.kt                  — AppScreen, CalibrationStatus, AppState
        AppViewModel.kt              — навигация, scenes StateFlow, spotlight lifecycle
        TrackingPipeline.kt          — Flow<DetectedFrame>: capture → detect → emit
        FacePositionResolver.kt      — resolve(frame, id, mapper?) → PanTilt?
        SpotlightController.kt       — FacePositionResolver + DmxSender (оркестрация)
    ui/
        CameraPreview.kt             — Image + FaceOverlay; onRawClick для калибровки
        TrackingScreen.kt            — превью + плавающий тулбар
        SceneManagerScreen.kt        — список сцен
        SceneEditorScreen.kt         — редактор + 4-точечный калибровочный визард
src/main/resources/models/           — ONNX-модели (YuNet)

Разработка

Все версии зависимостей — в gradle/libs.versions.toml. Шпаргалка по проекту и грабли — в CLAUDE.md.

./gradlew compileKotlin                   # быстрая проверка ошибок
./gradlew run                             # запустить
./gradlew tasks --group "compose desktop"
./gradlew --stop                          # рестарт демона

Лицензия

TBD.

About

Desktop-приложение, которое видит все лица на сцене через веб-камеру, позволяет выбрать одно из них кликом и управляет световой головой по DMX так, чтобы луч следил за выбранным человеком.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages