StarGlyph
Слепое распознавание участка
звёздного неба по фотографии
и наложение карты созвездий на снимок
Как по шумному кадру аналоговой видеокамеры — не зная ни направления, ни поворота, ни поля зрения — определить, куда смотрел объектив, и подписать звёзды, созвездия и планеты. Прототип на Rust + Tauri, проверенный на 20 реальных снимках.
О чём эта работа
Построена полная система слепой астрометрической привязки (blind plate solving): по единственному снимку ночного неба система находит координаты центра кадра, поворот и масштаб, после чего рисует поверх фотографии линии созвездий, подписи ярких звёзд и положения планет.
Конвейер: робастная детекция звёзд на шумном аналоговом видео → сопоставление четырёхзвёздных геометрических паттернов по хэш-индексу (семейство алгоритмов astrometry.net / TETRA[1,2]) → независимая статистическая верификация гипотезы → нелинейное уточнение позы и оптики (Левенберг–Марквардт) → эфемериды планет VSOP87[9]. Критерий приёмки — работа на 20 реальных кадрах камеры видеонаблюдения: решено 10 из 20, остальные честно диагностируются как бедные звёздами.
Содержание
- Задача и почему она трудная
- Данные: 20 реальных кадров
- Артефакты аналогового тракта
- Детекция звёзд
- Слепое отождествление: идея
- Четырёхзвёздные паттерны
- Мультимасштаб и лестница попыток
- Верификация: log-odds
- Уточнение позы и дисторсия
- Собственные движения звёзд
- Планеты: VSOP87
- Архитектура приложения
- Результаты и анализ отказов
- Источники
Вход — фотография. Выход — карта неба поверх неё
Рис. 1. Задача «lost in space»: априори неизвестны все четыре параметра — направление (RA, Dec), поворот кадра (roll) и угловой масштаб (FOV).
- Blind — никаких подсказок: ни направления, ни времени наведения, ни фокусного расстояния объектива.
- Неизвестных четыре: RA, Dec, roll, FOV — а сравнивать приходится со 119 626 звёздами каталога HYG[7].
- Секретный ингредиент точности: звёзды — идеальные маяки, их координаты известны до долей угловой секунды.
- Та же математика управляет звёздными датчиками ориентации спутников (star trackers)[5] и телескопами-роботами.
data/input/*.bmp) — шумных, тёмных, с облаками.20 кадров аналоговой видеокамеры, 740×576, 8 бит
- Серия 23:48–23:52 (13 кадров) — камера панорамирует; на кадр 5–13 детекций.
- Пара CD_0000/0020 — два кадра одной точки неба с интервалом ~20 с.
- Серия g128 (5 кадров) — самая богатая: 16–33 детекции, но и облака.
Аналоговый тракт оставляет отпечатки — их надо снять до детекции
Рис. 3б. Медиана яркости по столбцам (первые 80): выброс x=4 (горячий) и провал x=3 (мёртвый). Вычитание медианы столбца/строки убирает и это, и полосовой шум чересстрочной развёртки.
От пикселей к субпиксельным центроидам
| Шаг | Что и зачем |
|---|---|
| 1 · Медианы столбцов/строк | снимают горячий столбец и бандинг |
| 2 · Mesh-фон 32 px | sigma-clip по ячейкам — идея SExtractor[6]; переживает облака и виньетку |
| 3 · Оценка шума | робастно через MAD: σ = 1.4826·med|I−med I| |
| 4 · Согласованный фильтр | свёртка с гауссианой σ=1.2 px (7×7) — форма PSF звезды |
| 5 · Порог + компоненты | 2.5σ по свёртке, пик ≥ 4σ; 8-связная разметка |
| 6 · Фильтры блобов | ядро ≥ 2 px (режет одиночные горячие пиксели), площадь ≤ 150 (облака/Луна), вытянутость ≤ 2.5 (треки), кайма 8 px |
| 7 · Центроид | оконный взвешенный, 3 итерации, σw=1.5 px → субпиксельная точность |
| 8 · Отбор | топ-40 по потоку; 2 яруса чувствительности (базовый + глубокий для бедных кадров) |
Почему нельзя «просто перебрать» и что придумали вместо
Перебор гипотез «в лоб» безнадёжен: ~10³ перекрывающихся направлений × ~10² углов поворота × ~10¹ масштабов — порядка 10⁶ поз, и каждую надо сверить с каталогом. Ключевая идея семейства astrometry.net[1] — обратить задачу:
- заранее вычислить для каталога геометрические коды малых групп звёзд, инвариантные к повороту и масштабу;
- сложить их в хэш-индекс;
- на кадре построить те же коды из детекций и искать совпадения за ~O(1).
Каждое совпадение — это сразу гипотеза позы: какие звёзды каталога соответствуют каким точкам кадра. Осталось её проверить (след. слайды).
Рис. 5. Вместо прохода по пространству поз — индексирование инвариантов: похожие четвёрки звёзд попадают в одну ячейку хэш-таблицы независимо от поворота и масштаба кадра.
Код четвёрки: шесть расстояний → пять отношений
Рис. 6. Четыре звезды дают 6 попарных расстояний. Сортируем, делим на наибольшее — остаются 5 чисел в (0, 1], одинаковых для кадра и каталога.
- Инвариантность: поворот и масштаб не меняют отношений расстояний — неизвестные roll и FOV исчезают из поиска.
- Квантование кода задаёт ячейку хэш-таблицы; допуск сопоставления ~0.5–0.6% на компоненту.
- Масштаб восстанавливается после совпадения: отношение углового размера каталожной четвёрки к пиксельному даёт фокус/FOV.
- Поза — из соответствий «кадр ↔ каталог» задачей Вахбы (оптимальное вращение, кватернион).
- Ложные совпадения неизбежны (шум, горячие пиксели) — поэтому дальше обязательна верификация.
Не одна база, а спектр: полосы FOV и лестница попыток
Рис. 7. Стратегия перебора масштабов. База-«разведчик» покрывает 10–70°; если уверенного решения нет — на лету строится плотная полоса 17–30° (1200 паттернов на ячейку неба, звёзды до m≤6.5), заточенная под узкое поле этих камер. Обе базы генерируются из HYG при первом запуске (~1 мин) и кэшируются на диск.
- Лестница префиксов [8, 10, 12, 16, 20, 30]: сначала пробуем 8 ярчайших детекций, затем расширяем. Яркие центроиды точнее, а шумовой хвост (горячие пиксели!) не успевает отравить четвёрки.
- Порядок попыток: трек-подсказка (если есть) → FOV-подсказка → узкий поиск 22°±5° → слепые затравки 15/25/40/60° (±35%) → плотная полоса.
- Подсказки — это ускорение, а не допущение: пакетный прогон стартует полностью вслепую.
Сырому решению верить нельзя — проверяем всей картинкой
Гипотезу позы проверяем независимо от движка: проецируем в кадр все звёзды каталога до m≤6.8 и считаем, сколько из M детекций легло на предсказанные позиции (радиус 3 px). Каждая детекция — испытание Бернулли:
0.85 — полнота (вероятность, что реальная звезда попала в свой кружок при верной позе); p — вероятность случайного попадания (площадь кружков к площади кадра).
log-odds = 13·ln(388) + 20·ln(0.150) = 77.5 − 37.9 = +39.6 — случайной позе такое не светит (порог +18 ≈ 10⁸:1).
Рис. 8. log-odds десяти решённых кадров. Правило приёма двухканальное: log-odds ≥ 18 и H ≥ 6, либо жёсткий гейт движка (совпадений ≥ 6, вероятность ложного срабатывания < 10⁻⁵) плюс H ≥ 6. Второй канал спас три настоящих решения, которым глубокий шумовой хвост детектора утащил log-odds в минус.
Левенберг–Марквардт: поза, фокус и урок про дисторсию
По инлаерам минимизируем пиксельные невязки по пяти параметрам θ = {RA, Dec, roll, f, k₁} с радиальной моделью дисторсии:
- Демпфированный Гаусс–Ньютон (LM): шаг (JᵀJ + λI)δ = Jᵀres.
- k₁ при FOV≈22° слабо идентифицируем: без регуляризации один и тот же объектив «получал» k₁ разных знаков от кадра к кадру — фит впитывал шум центроидов.
- Лечение — мягкий прайор k₁ ~ N(0, 0.1): дополнительная строка резидуалов с весом 10. Настоящий многоточечный сигнал дисторсии он не задавит.
- Итог по кадрам: RMS невязок 0.9–1.7 px на 740×576.
Рис. 9. Радиальная модель при k₁=−0.26: после пика (u*≈1.13) кривая заворачивает — математически корректные проекции физически бессмысленны. Красная зона отбрасывается предохранителем; это и был источник «вспышки».
Звёзды движутся: эпоха кадра ≠ эпоха каталога
HYG хранит позиции на эпоху J2000 и собственные движения (μα*, μδ). При загрузке каталога позиции сдвигаются на эпоху кадра (из имени файла) векторно, без сингулярностей у полюсов:
u — единичный вектор звезды; ê, n̂ — восточный и северный орты касательной плоскости; Δt — годы от J2000. Тест-якорь: звезда Барнарда, ~10.3″/год.
Проверка конвенций — тестами, не верой
- Геометрия (проекция, базис камеры, кватернионы) написана в f64 и кросс-проверена против независимой реализации симулятора (dev-зависимость в тестах).
- Сквозные тесты: синтетический кадр из каталога → детекция → решение → сравнение позы с «истиной».
- LM-тест: возмущаем позу/фокус/k₁ — уточнение обязано вернуться к истине.
- Всего в прототипе 56 автотестов; clippy в режиме -D warnings.
Эфемериды VSOP87: планеты на снимке без интернета
Рис. 10. Астрометрическое положение: гелиоцентрические векторы VSOP87A → геоцентрический вектор → одна итерация поправки за световое время (мы видим планету там, где она была τ назад) → поворот из эклиптики в экватор J2000.
- VSOP87A[9] — аналитические ряды для прямоугольных гелиоцентрических координат в фиксированной эклиптике J2000 (вариант A выбран осознанно: C/D дают координаты «на дату» и смешали бы системы).
- Световое время: τ = |g|/c, c = 173.1446 а.е./сут; одной итерации достаточно для субсекундной сходимости.
- Наклон эклиптики ε₀ = 23.439291° (IAU 1976)[10].
- Сверка с JPL Horizons[14] (астрометрические RA/Dec ICRF, 2011–2026): расхождения — доли угловой секунды.
- Блеск — фазовые полиномы Астрономического альманаха (для размера маркера).
Rust-ядро + Tauri v2: один движок для CLI и GUI
Рис. 11. Вся наука — в starglyph-core; CLI и десктоп — тонкие оболочки над ним. Симулятор синтетики (фаза 1) архитектурно отделён от распознавателя и делит с ним только конвенции геометрии (сверенные тестами).
- Tauri v2[15]: фронтенд — статические HTML/CSS/JS без npm и фреймворков; вся тяжесть — в Rust.
- Решение — в spawn_blocking + rayon; прогресс стадий — типизированный ipc::Channel.
- Кадры в webview — бинарным Response (PNG), без base64-оверхеда.
- Просмотр: canvas-слои (изображение / оверлей), зум/пан, стретч-переключатель, слои созвездий/подписей/планет/сетки, часовой пояс с пересчётом оверлея без повторного решения.
- Headless-приёмка: starglyph-cli batch-solve и запуск GUI с --auto-solve.
Результат глазами пользователя
Дизайн: тёмная астро-тема, чтобы оверлей и снимки читались в темноте; жёлтые кружки — детекции, голубые линии — созвездия; в подвале — атрибуция данных (HYG CC BY-SA 4.0, d3-celestial BSD-3-Clause).
Приёмка на 20 реальных кадрах: 10 решены полностью вслепую
| Кадр | RA° | Dec° | Roll° | FOV° | H | RMS px | log-odds | мс |
|---|---|---|---|---|---|---|---|---|
| 23:50:14 | 10.58 | +64.56 | -40.1 | 22.45 | 6 | 0.91 | +37.9 | 106 |
| 23:51:03 | 14.82 | +62.53 | -13.7 | 22.18 | 6 | 0.95 | +40.5 | 103 |
| 23:51:33 | 17.01 | +64.56 | -19.9 | 22.38 | 6 | 1.65 | -13.3 ★ | 1254 |
| 23:51:48 | 16.64 | +58.41 | -16.5 | 22.44 | 6 | 1.71 | -15.4 ★ | 373 |
| CD 0000 | 299.23 | +45.37 | -37.5 | 22.31 | 6 | 1.28 | +30.5 | 151 |
| CD 0020 | 299.30 | +45.39 | -37.5 | 22.32 | 6 | 1.44 | +30.5 | 133 |
| g128 1s | 16.39 | +60.23 | -65.6 | 22.35 | 13 | 1.54 | +39.6 | 847 |
| g128 2 | 52.98 | +52.84 | -35.5 | 21.63 | 10 | 1.11 | +24.9 | 673 |
| g128 3h | 55.44 | +43.80 | -35.2 | 21.64 | 9 | 1.08 | +19.1 | 195 |
| g128 4 | 314.65 | +36.55 | +36.2 | 21.67 | 6 | 1.70 | -0.7 ★ | 1014 |
H — сопоставленные звёзды; время — на 4 CPU-ядрах, с прогретым кэшем баз. Полный пакет: ~61 с на все 20 кадров.
Рис. 13. Восстановленное поле зрения всех 10 решений: 22.2°±0.4° — один и тот же физический объектив, хотя решения независимы. Это сильный внутренний признак корректности.
· пара CD_0000/0020 (одна точка неба): решения совпали до 0.07°;
· серия 23:48–23:52 монотонно дрейфует по небу — камера панорамировала;
· созвездия на оверлеях визуально ложатся на звёзды снимков (рис. 12).
Почему 10 кадров не решились — и почему это честно
Рис. 14. Детекции базового яруса по кадрам (цвет — исход решения). Из каждого столбика ~2 детекции — горячие пиксели. Нерешённые кадры несут 4–6 пригодных звёзд — четвёрок для устойчивого паттерна из них почти не собрать.
Что показало это исследование
- Слепая привязка работает на плохих данных: 8-битное аналоговое видео 740×576 с 8–30 звёздами решается за секунды — при условии робастной детекции.
- Готовый движок ≠ готовое решение. tetra3 дал сопоставление паттернов; продуктом его сделали независимая log-odds-верификация, двухканальное правило приёма и LM-уточнение с регуляризацией.
- Статистика важнее эвристик: явная вероятностная модель (Бернулли, полнота 0.85) и спасла настоящие решения, и не пропустила ложных.
- Геометрия проверяется перекрёстно: консистентный FOV (22.2°±0.4°), сходимость co-pointed пары до 0.07°, визуальное попадание созвездий.
- Модель камеры — до границы применимости: немонотонность радиальной модели при k₁<0 — реальная ловушка, найденная на реальном кадре.
- Честная диагностика отказов ценнее натянутых решений: нерешаемые кадры объяснены данными и подтверждены негативным экспериментом.
Литература, данные, инструменты
- Lang D., Hogg D. W., Mierle K., Blanton M., Roweis S. Astrometry.net: Blind Astrometric Calibration of Arbitrary Astronomical Images. The Astronomical Journal 139(5), 1782–1800 (2010). arXiv:0910.2233.
- Brown J., Stubis K., Cahoy K. TETRA: Star Identification with Hash Tables. Proc. 31st AIAA/USU Conf. on Small Satellites, SSC17-VIII-1 (2017).
- Pettersson G. et al. tetra3 — a fast lost-in-space plate solver for star trackers. ESA, github.com/esa/tetra3.
- tetra3 — Rust-порт движка, crates.io/crates/tetra3, v0.8.0. Лицензии MIT / Apache-2.0.
- Mortari D., Samaan M. A., Bruccoleri C., Junkins J. L. The Pyramid Star Identification Technique. Navigation 51(3), 171–183 (2004).
- Bertin E., Arnouts S. SExtractor: Software for source extraction. Astronomy & Astrophysics Suppl. 117, 393–404 (1996) — mesh-фон, sigma-clipping.
- Nash D. The HYG Database v4.2 (компиляция Hipparcos, Yale BSC, Gliese). astronexus.com/hyg · CC BY-SA 4.0.
- ESA. The Hipparcos and Tycho Catalogues. ESA SP-1200 (1997).
- Bretagnon P., Francou G. Planetary theories in rectangular and spherical variables. VSOP87 solutions. Astronomy & Astrophysics 202, 309–315 (1988); Rust-крейт vsop87 v3.
- Meeus J. Astronomical Algorithms, 2nd ed. Willmann-Bell (1998) — гл. 22, 25, 33, 47.
- Chapront-Touzé M., Chapront J. The lunar ephemeris ELP 2000. Astronomy & Astrophysics 124, 50–62 (1983).
- Levenberg K. (1944); Marquardt D. W. (1963) — метод демпфированных наименьших квадратов. Quart. Appl. Math. 2, 164–168; J. SIAM 11(2), 431–441.
- Frohn O. d3-celestial — данные линий созвездий (GeoJSON). github.com/ofrohn/d3-celestial · BSD-3-Clause.
- JPL Horizons System — эталонные эфемериды для сверки. ssd.jpl.nasa.gov/horizons.
- Tauri v2 — каркас десктоп-приложения. tauri.app.
- Liebe C. C. Star trackers for attitude determination. IEEE Aerospace and Electronic Systems Magazine 10(6), 10–16 (1995).