TEMPEST HDMI泄漏接收 5

上一篇文章留下了一个问题,就是如何解决垂直线变斜的问题。

这个问题本来应该从通信上来解决,找出行同步信号,然后在这个信号处换行。

但是实际并不好做,因为hdmi并不是无线通信标准,没有这方面的资料。

因此,我打算用图像处理的方式来解决。即找出原始画面的规律,然后从画面上直观地做一些修改,来改善效果。

我本来考虑过给图形做仿射变换,相当于旋转图像,但是我估计效果不会太好。

后来我想了想,目前的问题无非就是每个行开始处有个offset的问题。我只要把这个offset位置的像素点挪到最开头那个点就行。还有个问题是这个offset对于每一行来说都是在变化的,幸运的是变化的趋势是固定的,比如下一行都比上一行offset大了一个固定的值。这样就很容易搞定了。

当然实际做的时候还会碰到各种各样的细节问题,比如offset后的像素挪到了左侧后,这一行offset前的像素点是不是就直接扔掉了?显然,不能这样,不然每行的右侧都会缺东西。事实上每一行的右侧都是用下一行offset左侧的像素点补上去的。

还有就是如果一下子写不出循环也不要紧,建议先参考我注释里写的那样,想象一种比较特殊的情形,然后把特殊情形的实际的像素点位置等数字写出来,然后从这些像素点之间的关系做一个归纳,找出他们的规律,然后再写循环,就会方便不少。

实际写代码过程中还会碰到各种各样的问题:

比如range(0,10)是从0到9,如果要包含10就需要改为range(0,10+1)。

另外offset如果不停减去一个固定值,可能会小于0,导致某几个取值超过边界,这时候可以想象如果一行的offset位置是0,那下一行的位置可以认为是-1(小于0),也可以认为在屏幕的右侧出现,此时就是行宽-1。也就是说可以把行宽作为周期,在offset小于0时给它补上去。同理,如果offset不停加上一个固定值也可能超出行宽,这时给它减去一个周期(行宽)就行。这就是我在代码56~59行做的事情。如果你不理解你可以把这部分删除,看看程序是否报错,再把对应x,y,offset的变量打印出来,看看为啥这些变量在这个取值时会报错就能理解我为啥要这么写了。

from pylab import *
from rtlsdr import *
import cv2

 
sdr = RtlSdr()
# configure device
sdr.sample_rate = 1.951047e6
sdr.center_freq = 395.991e6
sdr.gain = 60
# init for opencv
x = 0
y = 0
img = np.zeros((600,600,1), np.uint8)
img_to_show = np.zeros((600,600,1), np.uint8)

coarse_length_of_line = 580
fine_tune_of_offset_variation = -2
height_to_draw = 500

while True:
    samples = sdr.read_samples(1024*100) #type(sample) is numpy.complex128
    
    for sample in samples:
        mag = np.sqrt( sample.imag * sample.imag + sample.real * sample.real)
        value = mag * 255 * 10 #type(value) numpy.float64

        img[y, x] = value
        img[y, x + 1] = value
        img[y, x + 2] = value
        img[y, x + 3] = value
        img[y, x + 4] = value
        img[y, x + 5] = value
        img[y, x + 6] = value
        img[y, x + 7] = value
        img[y, x + 8] = value
        img[y, x + 9] = value
 
        x = x + 10
        if (x >= coarse_length_of_line):
            x = 0
            y = y + 1
        if (y >= height_to_draw):
            y = 0
 

    offset = 0
    for j in range(0, height_to_draw):
        for i in range(0, coarse_length_of_line - offset + 1): # contains 0 and coarse_length_of_line - offset
            img_to_show[j, i] = img[j, i + offset]

        for i in range(coarse_length_of_line - offset + 1, coarse_length_of_line + 1):
            img_to_show[j, i] = img[j + 1, i + offset - coarse_length_of_line - 1]

        offset = offset + fine_tune_of_offset_variation
        if (offset < 0):
            offset = offset + coarse_length_of_line
        elif (offset > coarse_length_of_line):
            offset = offset - coarse_length_of_line

    '''
    img_to_show[0, 0] = img[0, 50]
    img_to_show[0, 1] = img[0, 51]
    ...
    img_to_show[0, 530] = img[0, 580]

    img_to_show[0, 531] = img[1, 0]
    ...
    img_to_show[0, 580] = img[1, 49]

    img_to_show[1, 0] = img[1, 45]
    img_to_show[1, 1] = img[1, 46]
    ...
    img_to_show[1, 535] = img[1, 580]

    img_to_show[1, 536] = img[2, 0]
    ...
    img_to_show[1, 580] = img[2, 44]
    '''


    cv2.imshow("HDMI", img)
    cv2.imshow("HDMI2", img_to_show)
    if(cv2.waitKey(10)==27):
        break
 
sdr.close()

我的程序还是有不少要优化的地方,比如纠正后的画面中间老是会有一条细斜线,如果大家知道为啥可以告诉我。

另外就是如果能找出hdmi的行同步和帧同步信号对无线电的实际影响并用于纠偏就更好了。

本文代码实际效果:

SDR接收HDMI泄漏3 极简代码实现tempestsdr_哔哩哔哩_bilibiliicon-default.png?t=M5H6https://www.bilibili.com/video/BV1U34y1H7YD

猜你喜欢

转载自blog.csdn.net/shukebeta008/article/details/125511525
5