我试图加速这段代码在整个光谱范围内的循环。它使用的是一个覆盆子Pi,和一个,涵盖了大约1.7 GHz。我的目标是横扫这一领域,并及时从其中收集数据。
#!bin/usr/python
#gathers from the rtl library needed for this program
from rtlsdr import RtlSdr
import math
from pylab import *
import time
from scipy.fftpack import fft, ifft
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import os
import sys
os.system("sudo rmmod dvb_usb_rtl28xxu rtl2832")
#RtlSdr set up
##sdr = RtlSdr()
##
##
##num_samples = 4096
##
##freq_range_lo = 50e6 #experimental center freq for now
##freq_range_hi = 600e6 #1750e6
##freq_step = 1e6
##sample_rate = 2e6
##
###Set initial parameters for RTL-SDR Dongle
##sdr.sample_rate = sample_rate
##freq = 512e6
##sdr.center_freq = freq
##
##
##sdr.freq_correction = 102
##sdr.gain = 0
class Spec_Scan(object):
samples = np.array([])
samples_temp = np.array([])
fft_data = np.array([])
fft_data_temp = np.array([])
app = QtGui.QApplication([])
win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')
def __init__(self, lo, hi, freq, step, samps):
self.freq_range_lo = lo
self.freq_range_hi = hi
self.freq_step = step
self.freq = freq
self.num_samples = samps
self.sample_rate = 2e6
self.sdr = RtlSdr()
self.sdr_default()
def sdr_default(self):
self.sdr.center_freq = self.freq
self.sdr.freq_correction = 101
self.sdr.gain = 0
self.sdr.sample_rate = self.sample_rate
def pyqt(self):
global curve, p6
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
self.win.nextRow()
p6 = self.win.addPlot(title="Freq plot")
self.curve = p6.plot(pen='y', clear=True)
#p6.setRange(xRange = [0, (self.num_samples/2)*(1700e6/self.freq_step)], yRange = [-100,100])
p6.setRange(xRange = [0, (self.num_samples/2)-48], yRange = [-100,100])
print 'here'
timer = pg.QtCore.QTimer()
print'should begin update'
timer.timeout.connect(self.update)
timer.timeout.emit()
print 'update should have finished'
timer.start(2)
if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
def update(self):
global curve, p6
for self.freq in range(int(self.freq_range_lo), int(self.freq_range_hi), int(self.freq_step)):
self.sdr.center_freq = self.freq
self.samples = self.sdr.read_samples(self.num_samples)
self.fft_data_temp = 20*np.log10(np.abs(np.fft.rfft(self.samples)))
#self.fft_data_temp = self.fft_data_temp[0:2049]
## self.fft_data_temp = self.fft_data_temp[1:(self.num_samples/2)]
## self.fft_data_temp = 2*self.fft_data_temp[2::]
self.fft_data = np.append(self.fft_data, self.fft_data_temp)
self.fft_data_temp = 0
#self.curve.setData(self.fft_data[1::], clear=True)
self.fft_data = 0
print 'refresh'
def main():
num_samples = 4096
lo = 50e6 #experimental center freq for now
hi = 1750e6
step = 1e6
freq = 425e6
test = Spec_Scan(lo, hi, freq, step, num_samples)
## test.pyqt()
start = time.time()
test.update()
end = time.time()
print str(end-start)
## Start Qt event loop unless running in interactive mode or using pyside.
main()当扫描本身被计时时,结果产生197秒左右,这是完全太长。有什么办法可以加速光谱扫描吗?
发布于 2015-07-09 22:33:14
我将添加我的小贡献,即使我不是一个真正的Python开发人员(希望有一天)。我已经采用了您的更新方法,并在我的计算机上测试了它(桌面,i3-4360@ 3.70GHz×4 ),没有SDR比特。我的直觉是对的!
就像在大多数语言中允许你这样做一样,永远不要这样做:
self.fft_data = np.append(self.fft_data, self.fft_data_temp)原因很简单:您的数组没有预定义的大小,因此对于要追加的每个调用,它必须重新分配内存以适应新的大小。这太慢了。
我们谈谈数字吧。如果没有这行代码,在我的计算机上执行快速傅立叶变换并将数据转换为dB需要300 my。加上这一行,它几乎达到9s。
那么,既然我们已经发现了这一点,那么您的应用程序应该如何处理呢?似乎你想要显示的频谱从50兆赫到1750兆赫,通过分解成信号与1兆赫的带宽。对于每一片,你会产生4096个样本。我不知道您有什么样的显示,但是显示4096 * 1700 FFT回收箱是很困难的(特别是在1000*600的窗口中)。您应该限制您想要立即显示的频谱的大小。说到波段,展示高频波段的末端,甚高频波段和超高频波段的一部分并不是真正有趣的事情。主要是因为你很难找到能同时覆盖所有这些波段的天线。
发布于 2015-07-09 20:02:21
第一个#!bin/usr/python应该是#!/bin/usr/python2。正如您应该声明它所使用的python版本一样。
这是因为Arch将python更改为python3,而不是python2。
CamelCase。不是Capitalized_Words_With_Underscores。a = b,20 * 2.这一例外情况是您需要显示优先级。20*2 + 1.,我个人认为使用括号看起来更好。(20 * 2) + 1curve和p6应该在类中。不是全球性的。=不是用于传递kwargs的赋值运算符时,运算符周围就不应该有空格。yRange=[-100,100]。[-100, 100]。if __name__=='__main__'应该阻止running.中的整个代码,它应该在模块级别执行。for self.freq in。就我个人而言,我认为你给自己打的电话太多了。以及对全球的依赖。访问局部变量更快。但不仅更快,而且更安全。
对于我来说,很难知道允许改变什么,因为所有东西都使用self.。因此,作为一所大学,我会改变一切,只是为了说明当地人是好的。
似乎您希望在update中使用列表理解。这是因为它是一个只写到变量self.fft_data的for循环。
def update(self):
self.fft_data = np.array(
20 * np.log10(np.abs(np.fft.rfft(
self.sdr.read_samples(self.num_samples))))
for _ in range(
int(self.freq_range_lo),
int(self.freq_range_hi),
int(self.freq_step))
)如果上面的代码返回切片,则需要使用如下内容。它是用纯Python编写的。这是因为我找不到numpy数组的文档。
def update(self):
self.fft_data = []
append_ = self.fft_data.append
for _ in range(
int(self.freq_range_lo),
int(self.freq_range_hi),
int(self.freq_step)):
append_(
20 * np.log10(np.abs(np.fft.rfft(
self.sdr.read_samples(self.num_samples)))))这些主要是为了不同的观点,老实说,除了这些列表之外,我不知道您需要函数做什么。我再一次指责self.s。
除了PEP8中的所有样式更改之外,您还应该使用局部变量。我真的说不出什么是允许我改变的,什么是我在自我中所必需的。
发布于 2015-07-09 19:01:59
我认为commented是“在发布或部署代码之前”,巨大的注释块,如:
#RtlSdr set up
##sdr = RtlSdr()
##
##
##num_samples = 4096
##
##freq_range_lo = 50e6 #experimental center freq for now
##freq_range_hi = 600e6 #1750e6
##freq_step = 1e6
##sample_rate = 2e6
##
###Set initial parameters for RTL-SDR Dongle
##sdr.sample_rate = sample_rate
##freq = 512e6
##sdr.center_freq = freq
##
##
##sdr.freq_correction = 102
##sdr.gain = 0应该删除:版本控制将照顾他们。
您可以节省空间:
samples = np.array([])
samples_temp = np.array([])
fft_data = np.array([])
fft_data_temp = np.array([])可以成为:
samples = samples_temp = fft_data = fft_data_temp = np.array([])https://codereview.stackexchange.com/questions/96399
复制相似问题