Hallo Habr.
Wie in der jüngsten Ankündigung vom 24. bis 31. Dezember geschrieben, werden SSTV-Bilder von der ISS übertragen. Die Übertragung erfolgt im Funkamateurband mit einer Frequenz von 145,800 MHz und kann von jedem empfangen werden.
Mal sehen, wie es funktioniert und wie ein solches Signal dekodiert werden kann.
Allgemeine Information
" ", - . , 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 - , , . 640480 - 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) . , .