Принимаем и декодируем передачи SSTV с МКС

  • Tutorial

Привет, Хабр.

Как было написано в недавнем анонсе, с 24 по 31 декабря производится передача изображений формата SSTV с МКС. Передача идет в радиолюбительском диапазоне на частоте 145.800 МГц и принять её может любой желающий.

МКС (c) https://en.wikipedia.org/wiki/International_Space_Station
МКС (c) https://en.wikipedia.org/wiki/International_Space_Station

Посмотрим, как это работает и как такой сигнал можно декодировать.

Общие сведения

Передача изображений с МКС производится в рамках проекта "О Гагарине из космоса", вполне благородная цель которого - привлечь внимание к космонавтике. Передачи осуществляются несколько раз в год, любой желающий в любой точке мира может принять изображения формата SSTV на частоте 145.8 МГц. SSTV (Slow-scan television) - это формат передачи изображений с малой скоростью. Сам формат появился весьма давно, таким способом передавались еще изображения обратной стороны Луны со станции Луна-3. Гораздо позже SSTV нашел популярность у радиолюбителей, т.к. позволял передавать изображения на коротких волнах при помощи обычного радиопередатчика. С некоторыми изменениями формат SSTV (а точнее, несколько, их около десятка разновидностей) дожил и до наших дней. Когда-то прием таких изображений был доступен лишь на специальной и дорогостоящей аппаратуре, сейчас это можно сделать с помощью компьютера, бесплатной программы-декодера и приемника RTL-SDR ценой 35$. Изображения могут приниматься как на КВ, так и на УКВ, дальше речь пойдет только об SSTV с МКС.

Прием

Т.к. сигналы передаются с космической станции, первым делом мы должны узнать точное время приема. Когда-то давно для этого использовали программу Orbitron, но сейчас гораздо проще открыть сайт n2yo.com и посмотреть ближайшее время пролета.

На частоты в правом верхнем углу можно не смотреть, они к SSTV отношения не имеют. Нам нужна частота 145.800 МГц, разумеется нужен приемник, подойдет например самый дешевый RTL-SDR V3. За 35$ можно купить такой набор, который вполне подойдет для первого знакомства с радио:

Если все было сделано правильно, мы должны увидеть примерно такой сигнал:

Для записи нужно использовать частотную модуляцию, но можно декодировать и в реальном времени, если использовать программу virtal audio card для перенаправления звука из SDR в программу-декодер.

Декодирование

Существует много программ для декодирования SSTV, которые позволяют сделать всё в 2-3 клика мышью. Мне все же интересен сам формат передачи, поэтому посмотрим как его можно декодировать вручную.

Для начала можно посмотреть на спектр сигнала:

SSTV это аналоговый формат, строки передаются последовательно, длительность передачи одной строки в PD-120 (в этом формате идут передачи с МКС) составляет 0.5с. Используется частотная модуляция, где частота меняется в зависимости от яркости и уровню черного соответствует 1500 Гц, а уровню белого 2300 Гц.

Загрузим изображение и используем band-pass фильтр, чтобы убрать все лишнее:

import scipy.io.wavfile as wav
import scipy.signal as signal
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image


fs, data = wav.read('HDSDR_20201228_075406Z_145803kHz_AF.wav')

def butter_bandpass(lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = signal.butter(order, [low, high], btype='band')
    return b, a


def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    b, a = butter_bandpass(lowcut, highcut, fs, order=order)
    y = signal.lfilter(b, a, data)
    return y

data1 = butter_bandpass_filter(data, 1400, 2200, fs, order=4)

Применим к изображению частотный демодулятор. Я не нашел готовой библиотеки, поэтому просто вычисляю частоту напрямую, по переходам через ноль:

data_fsk = np.zeros(len(data1))

pos1 = 0
for p in range(0, len(data1)-1):
    if np.sign(data1[p]) != np.sign(data1[p+1]):
        pr = p - pos1
        data_fsk[pos1:p] = np.full(p - pos1, pr)
        pos1 = p

"Развернем" данные в виде 2D-изображения:

frame_width = int(0.5*fs) + 203
w, h = frame_width, data_fsk.shape[0]//frame_width
image = Image.new('RGB', (w, h))

data_2d = data_fsk[:w*h].reshape((h,w))
for py in range(h):
    for px in range(w):
        lum = int(data_2d[py][px]*16)
        if lum < 0: lum = 0
        if lum > 255: lum = 255
        image.putpixel((px, py), (lum, lum, lum))

Выведем изображение на экран:

plt.imshow(image)
plt.show()

Мы видим довольно любопытную картинку. В одной строке передается 4 кадра. Это цветное изображение формата YCrCb, точнее сказать, Y1CrCbY2 - в одной линии передаются каналы яркости для двух строк и общий канал цвета, таким образом, цветовое разрешение картинки вдвое меньше чем яркостное. Итоговое разрешение составляет 640х480 - всего передается 240 линий, но в каждой линии, как можно видеть, хранится 2 строки.

Кстати, одна строка передается за 0.5с, что при 240 строках дает время передачи 120с, т.е. 2 минуты. Название формата PD-120 также указывает нам на эту величину.

Далее остается выполнить преобразование YCrCb => RGB:

image_rgb = Image.new('RGB', (w//4, 2*h))
for py in range(h):
    for px in range(int(0.125*fs)):
            # PD-120 – 640×480, 190 ?s/pixel
            k = 32
            y0 = 255 - k*data_2d[py][px]
            cr = 255 - k*data_2d[py][px + int(0.1216*fs)]
            cb = 255 - k*data_2d[py][px + 2*int(0.1216*fs)]
            y1 = 255 - k*data_2d[py][px + 3*int(0.1216*fs)]
            image_rgb.putpixel((px, 2*py), (int(y0 + 1.402 * cr), int(y0 - 0.34414 * cb - 0.71414 * cr), int(y0 + 1.772 * cb)))
            image_rgb.putpixel((px, 2*py + 1), (int(y1 + 1.402 * cr), int(y1 - 0.34414 * cb - 0.71414 * cr), int(y1 + 1.772 * cb)))

Это простейший код, без какого-либо выравнивания границ и нормализации уровней, некоторые цвета различить вполне можно:

Здесь показана лишь общая идея, у меня не было цели сделать еще один конвертор SSTV, их уже много разных, можно лишь показать что при использовании готовой программы получается такая картинка:

Заключение

Как можно видеть, все не так уж сложно и вполне интересно. Желающие могут попробовать принять изображения с МКС самостоятельно, судя по анонсам, передача продлится до 31 декабря (и будем надеяться, традиция продолжится и в следующем году). Разумеется, не обязательно использовать Python, готовые декодеры SSTV можно найти для любой платформы.

Также стоит поблагодарить всех участников программы ARISS (Amateur Radio on the International Space Station) за проведение и поддержку подобных передач. Это отличная возможность для радиолюбителей, школьников и студентов прикоснуться к освоению космоса.

Средняя зарплата в IT

113 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 10 037 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 28

    +2
    Дополнение. Не обязательно самим принимать сигнал. Можно воспользоваться сетью satnogs и подобрать для опытов подходящие файлы там.
    Пример network.satnogs.org/observations/3369171
      +1
      Это не спортивно :) Но для анализа сигналов тоже вариант, да.
        0
        У меня с приёмом на метровых волнах даже с радиолюбителями на 144 не очень получается — FM передатчики забивают вход приемника. О фильтре (или на диапазон или режектор на ФМ) иногда думаю, но без приборов неизвестно какой результат получится и отгоняю эту мысль прочь.
          0
          Если нет приборов и желания пилить коробочки, то фильтр проще купить, цена вопроса 20$, у китайцев наверно еще дешевле: www.amazon.de/-/en/Flamingo-FM-applications-88-108MHz-frequencies/dp/B07XKY8YKB

          В моем случае больше мешают не FM, а близкорасположенные передатчики, весь спектр «проседает» из-за них когда что-то включается на передачу.
            0
            В вашем случае и в моем для лучшего результата надо band-pass фильтр, но это если надо всегда только кусочек спектра слушать. Более выгодно режектором давить ближайшие сильные сигналы, а с остальным мириться.
              0
              Это да, band pass актуален для одного диапазона, но я не настолько часто принимаю МКС чтобы покупать фильтр специально для этого :)
                0
                Для таких как мы «интересующихся» проще погасить помеху. Есть простые варианты для «вечера выходного дня». Из измерительных приборов — только линейка нужна.
                Он представляет собой включенный параллельно входу приемника коаксиальный кабель длиной четверть волны принимаемого канала (рис.7). Такой отрезок кабеля представляет собой почти короткое замыкание не только для своей резонансной частоты – L/4, но и для всех ее нечетных гармоник.

                image
                www.cqham.ru/rk3zk/3.htm
                  0
                  Я думаю, любой хоть немного интересующийся радио, должен иметь антенный анализатор, тем более что сейчас это стоит 35$ за девайс от 0.1 МГц до 1 ГГц:

                  www.ebay.com/itm/Nanovna-50KHz-900MHz-Vector-Network-Analyzer-UHF-HF-VNA-UV-VHF-Antenna-Analyzer/264715019796

                  Цена одного похода в супермаркет ведь. Времена когда что-то вымеряли только линейкой, к счастью прошли, спасибо китайцам :)
                    +2
                    Это должно быть у друга, которого можно попросить сделать, настроить, измерить.
                    Не имей $35, а имей 35 друзей.
              0
              А чем принимаете?
                0
                Телевизионные усы. Два свистка — синий R820T и и черный E4000. E4000 на этом диапазоне очень шумный — какие-то пульсации, толи собственные, толи по питанию т.к. на macbook их нет.
                  0
                  Желательно еще длину усов в резонанс настроить по формуле для полуволнового диполя (а лучше антенным анализатором, они сейчас совсем дешевые стали).
                    0
                    Я настраивал по громкости на слух по ATIS аэропорта — 130+ МГц
                      0
                      А может Вы усиление на всю ставите? Если с усилением на 3/4 по бегунку и все равно мешают FM, то смысл режекторного фильтра есть.
                        0
                        ФМ радио принимается без антенны, а ATIS/радиолюбители на 144 слабо и только на максимуме собственного усиления тюнера.
                        С радиолюбителями на 433 ситуация на порядок лучше. Использование предусилителя SPF5189 качественно меняет ситуацию, но чем ближе к ФМ тем ниже надо выставлять собственное усиление тюнера.
              0
              А общедоступные SDR подойдут? Например websdr.org. Более спортивно чем у коммента от Javian, но не менее бюджетно.
                0
                Если кто-то держит SDR, настроенный на 148.8 МГц, то да, подойдут.

                Здесь есть список amsat-uk.org/2015/04/14/using-websdrs-for-iss довольно старый судя по дате, но ссылки внутри вроде еще рабочие.

                Только расписание пролетов нужно тогда смотреть для локации websdr, разумеется :)
                  0
                  Опечатка, не 148.8 а 145.8 МГц.
            0
            >Для начала можно посмотреть на спектр сигнала:
            image
            А это точно спектр сигнала?
            В смысле амплитуда от частоты или все таки амплитуда от времени?
              0
              Точно, sstv кодируется именно частотой. На спектре время и частота.
                +1
                Ну это не спектр сигнала тогда)
                У вас спектр в вашей же статье, одной картинкой выше.
                  0
                  Тут фактически двойная частотная модуляция — сигнал SSTV кодируется в FM, но в самом формате SSTV частота кодирует цвет. Т.е. мы должны запустить FM-демодулятор дважды по сути.

                  Вот картинка из Adube Audition, со шкалой понятнее:
                  Скриншот

                  +1
                  Т.е. значение частоты от времени.
                  Это конечно не спектр, но для частотно-модулированных сигналов — да показательно.
                  ИМХО не хватает подписанных осей и значений для понимания размаха частоты.
                  И последняя треть несколько размазанная это что?
                    0
                    Да, с осями было бы понятнее, но программа для рисования спектра не умеет их выводить, версия давно не обновлялась. Размазанная часть справа это и есть закодированное изображение, скачки частоты вверх-вниз в соответствии с точками разной яркости.
                +1

                Простите за бессодержательный комментарий, но
                SPAAACE!
                //в игре Portal так же (SSTV) кодировалась картинка с радиоприёмников.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое