Привет, Хабр.
Как было написано в недавнем анонсе, с 24 по 31 декабря производится передача изображений формата SSTV с МКС. Передача идет в радиолюбительском диапазоне на частоте 145.800 МГц и принять её может любой желающий.
Посмотрим, как это работает и как такой сигнал можно декодировать.
Общие сведения
Передача изображений с МКС производится в рамках проекта "О Гагарине из космоса", вполне благородная цель которого - привлечь внимание к космонавтике. Передачи осуществляются несколько раз в год, любой желающий в любой точке мира может принять изображения формата 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) за проведение и поддержку подобных передач. Это отличная возможность для радиолюбителей, школьников и студентов прикоснуться к освоению космоса.
Javian
Дополнение. Не обязательно самим принимать сигнал. Можно воспользоваться сетью satnogs и подобрать для опытов подходящие файлы там.
Пример network.satnogs.org/observations/3369171
DmitrySpb79 Автор
Это не спортивно :) Но для анализа сигналов тоже вариант, да.
Javian
У меня с приёмом на метровых волнах даже с радиолюбителями на 144 не очень получается — FM передатчики забивают вход приемника. О фильтре (или на диапазон или режектор на ФМ) иногда думаю, но без приборов неизвестно какой результат получится и отгоняю эту мысль прочь.
DmitrySpb79 Автор
Если нет приборов и желания пилить коробочки, то фильтр проще купить, цена вопроса 20$, у китайцев наверно еще дешевле: www.amazon.de/-/en/Flamingo-FM-applications-88-108MHz-frequencies/dp/B07XKY8YKB
В моем случае больше мешают не FM, а близкорасположенные передатчики, весь спектр «проседает» из-за них когда что-то включается на передачу.
Javian
В вашем случае и в моем для лучшего результата надо band-pass фильтр, но это если надо всегда только кусочек спектра слушать. Более выгодно режектором давить ближайшие сильные сигналы, а с остальным мириться.
DmitrySpb79 Автор
Это да, band pass актуален для одного диапазона, но я не настолько часто принимаю МКС чтобы покупать фильтр специально для этого :)
Javian
Для таких как мы «интересующихся» проще погасить помеху. Есть простые варианты для «вечера выходного дня». Из измерительных приборов — только линейка нужна.
www.cqham.ru/rk3zk/3.htm
DmitrySpb79 Автор
Я думаю, любой хоть немного интересующийся радио, должен иметь антенный анализатор, тем более что сейчас это стоит 35$ за девайс от 0.1 МГц до 1 ГГц:
www.ebay.com/itm/Nanovna-50KHz-900MHz-Vector-Network-Analyzer-UHF-HF-VNA-UV-VHF-Antenna-Analyzer/264715019796
Цена одного похода в супермаркет ведь. Времена когда что-то вымеряли только линейкой, к счастью прошли, спасибо китайцам :)
Javian
Это должно быть у друга, которого можно попросить сделать, настроить, измерить.
Не имей $35, а имей 35 друзей.
sicambr
http://www.radioscanner.ru/board/id130299.html
R820T2
А чем принимаете?
Javian
Телевизионные усы. Два свистка — синий R820T и и черный E4000. E4000 на этом диапазоне очень шумный — какие-то пульсации, толи собственные, толи по питанию т.к. на macbook их нет.
DmitrySpb79 Автор
Желательно еще длину усов в резонанс настроить по формуле для полуволнового диполя (а лучше антенным анализатором, они сейчас совсем дешевые стали).
Javian
Я настраивал по громкости на слух по ATIS аэропорта — 130+ МГц
R820T2
А может Вы усиление на всю ставите? Если с усилением на 3/4 по бегунку и все равно мешают FM, то смысл режекторного фильтра есть.
Javian
ФМ радио принимается без антенны, а ATIS/радиолюбители на 144 слабо и только на максимуме собственного усиления тюнера.
С радиолюбителями на 433 ситуация на порядок лучше. Использование предусилителя SPF5189 качественно меняет ситуацию, но чем ближе к ФМ тем ниже надо выставлять собственное усиление тюнера.
meljohin
А общедоступные SDR подойдут? Например websdr.org. Более спортивно чем у коммента от Javian, но не менее бюджетно.
DmitrySpb79 Автор
Если кто-то держит SDR, настроенный на 148.8 МГц, то да, подойдут.
Здесь есть список amsat-uk.org/2015/04/14/using-websdrs-for-iss довольно старый судя по дате, но ссылки внутри вроде еще рабочие.
Только расписание пролетов нужно тогда смотреть для локации websdr, разумеется :)
DmitrySpb79 Автор
Опечатка, не 148.8 а 145.8 МГц.