1.pyinstaller打包exe(详细教程)
2.Simpleperf 翻译篇7-查看结果
3.使用 scipy.fft 进行Fourier Transform:Python 信号处理
pyinstaller打包exe(详细教程)
打包Python脚本和游戏成.exe文件,时钟不仅能方便他人在无Python环境的源码情况下运行,还能展示你的时钟作品。安装PyInstaller非常便捷,源码通过命令行的时钟pip即可完成。
要打包单个.py文件,源码弓专精源码以制作的时钟时钟程序为例。首先,源码打开命令行并切换至包含.py文件的时钟目录,输入`pyinstaller -F -w Analog_clock.py`,源码然后按回车。时钟如果出现成功打包的源码提示,说明操作完成。时钟打包后的源码.exe文件会存储在同级目录的dist文件夹中,直接点击即可运行,时钟简单快捷。
若要打包多个.py文件,如外星人入侵,首先对主文件alien_invasion.py执行上述步骤。接着,将依赖的其他文件移动到dist文件夹,然后通过点击打包好的exe运行即可。
PyInstaller的参数选项很有用:-F用于仅生成一个exe文件;-w使Windows版不显示控制台;-D默认选项,会包含依赖文件,推荐使用;-i可以设置.exe的图标,输入指定路径;-p则用于设置导入路径,以解决库文件路径问题。
Simpleperf 翻译篇7-查看结果
使用simpleperf record或app_profiler.py后,获得一个包含众多样本的profile文件。每个样本包含时间戳、线程ID、调用堆栈及事件(如CPU周期或CPU时钟)等信息。查看profile文件的方式多样,包括按时间顺序显示样本或生成火焰图,且支持文本格式和交互式UI。以下是推荐的几种UI: Continuous PProf UI(内部使用,性能分析强大):PProf UI由Google开发,适用于服务器分析,具备强大的火焰图功能,支持向下钻取、搜索、数据透视、名片赞引流源码配置文件差异和图形可视化。转换profile文件为pprof.profile protobuf格式,以便在PProf中使用。 Firefox Profiler(时间顺序排列,易于操作):Firefox Profiler提供出色的按时间顺序视图,适合查看Android profile文件。使用gecko_profile_generator.py将原始perf.data文件转换为Firefox profile文件,并进行Proguard反混淆,然后将gecko_profile.json.gz拖入Firefox Profiler进行分析。 FlameScope(卡顿查找功能):Netflix的FlameScope是一个概念验证UI,通过将配置文件布置为亚秒级热图,帮助发现重复工作模式。每个垂直条纹代表一秒,每个单元格为毫秒,颜色越深表示样本越多。FlameScope支持安装、运行和分析,并允许过滤特定时间跨度以获取火焰图。 差分火焰图:Brendan Gregg的博客提供了差分火焰图示例。使用Simpleperf的stackcollapse.py将perf.data转换为FlameGraph工具包的Folded Stacks格式,比较优化前后配置文件以识别性能差异。 Android Studio分析器:Android Studio Profiler支持记录和报告应用进程的配置文件,提供多种记录方法,包括使用simpleperf作为后端。在Android Studio中,通过特定步骤记录和报告数据。用户可以查看CPU图表、调用堆栈示例并使用火焰图查看器分析结果。 Simpleperf HTML报告:Simpleperf能够生成HTML配置文件,显示Android特定信息及所有线程的独立火焰图。尽管UI较为简陋,但适合快速查看数据。通过命令行工具将perf.data转换为report.html。 PProf交互式命令行:与Continuous PProf UI不同,PProf命令行公开可用,支持向下钻取、旋转和过滤功能。通过过滤包含processBitmap的堆栈帧并显示运行线程标签,用户可以深入了解分析结果。 Simpleperf报告命令行:简单使用simpleperf report命令以文本格式报告配置文件信息。命令可以直接调用或通过report.py调用。触店app源码 自定义报告界面:如果上述视图无法满足特定需求,可以使用simpleperf_report_lib.py解析perf.data,提取示例信息,并将其与自选的视图集成,实现个性化分析。使用 scipy.fft 进行Fourier Transform:Python 信号处理
摘要:Fourier transform 是一个强大的概念,用于各种领域,从纯数学到音频工程甚至金融。scipy.fft模块傅立叶变换是许多应用中的重要工具,尤其是在科学计算和数据科学中。因此,SciPy 长期以来一直提供它的实现及其相关转换。最初,SciPy 提供了该scipy.fftpack模块,但后来他们更新了他们的实现并将其移到了scipy.fft模块中。
SciPy 充满了功能。有关该库的更一般介绍,请查看Scientific Python:使用 SciPy 进行优化。
安装 SciPy 和 Matplotlib在开始之前,您需要安装 SciPy 和Matplotlib。您可以通过以下两种方式之一执行此操作:
使用 Anaconda 安装:下载并安装Anaconda Individual Edition。它带有 SciPy 和 Matplotlib,因此一旦您按照安装程序中的步骤操作,您就大功告成了!
安装方式pip:如果您已经pip安装,那么您可以使用以下命令安装库:
$ python -m pip install -U scipy matplotlib
您可以通过在终端中键入python并运行以下代码来验证安装是否有效:
>>>>>>importscipy,matplotlib>>>print(scipy.__file__)/usr/local/lib/python3.6/dist-packages/scipy/__init__.py>>>print(matplotlib.__file__)/usr/local/lib/python3.6/dist-packages/matplotlib/__init__.py此代码导入 SciPy 和 Matplotlib 并打印模块的位置。您的计算机可能会显示不同的路径,但只要它打印路径,安装就成功了。
SciPy 现已安装!现在是时候看看scipy.fft和之间的区别了scipy.fftpack。
scipy.fft 对比 scipy.fftpack在查看 SciPy 文档时,您可能会遇到两个看起来非常相似的模块:
scipy.fft
scipy.fftpack
该scipy.fft模块较新,应该优先于scipy.fftpack. 您可以在SciPy 1.4.0的发行说明中阅读有关更改的更多信息,但这里有一个快速摘要:
scipy.fft 有一个改进的 API。
scipy.fft允许使用多个 worker,这可以在某些情况下提供速度提升。
scipy.fftpack被认为是遗留的,SciPy 建议scipy.fft改用。
除非您有充分的理由使用scipy.fftpack,否则您应该坚持使用scipy.fft.
scipy.fft 对比 numpy.fftSciPy 的javaweb项目源码搭建快速傅立叶变换 (FFT)实现包含更多功能,并且比 NumPy 的实现更可能修复错误。如果有选择,您应该使用 SciPy 实现。
NumPy 维护了 FFT 实现以实现向后兼容性,尽管作者认为像傅立叶变换这样的功能最好放在 SciPy 中。有关更多详细信息,请参阅SciPy 常见问题解答。
Fourier TransformFourier 分析是研究如何将数学函数分解为一系列更简单的三角函数的领域。傅立叶变换是该领域的一种工具,用于将函数分解为其分量频率。
好吧,这个定义非常密集。就本教程而言,傅立叶变换是一种工具,可让您获取信号并查看其中每个频率的功率。看看这句话中的重要术语:
一个信号是随时间变化的信息。例如,音频、视频和电压轨迹都是信号的例子。
甲频率是某物重复的速度。例如,时钟以一赫兹 (Hz) 的频率滴答,或每秒重复一次。
在这种情况下,功率仅表示每个频率的强度。
下图是一些正弦波的频率和功率的直观演示:
所述的峰值的高频正弦波比那些更靠近在一起低频正弦波,因为它们重复得更频繁。所述低功率正弦波具有比其它两个正弦波较小的峰。
为了更具体地说明这一点,假设您对某人同时在钢琴上弹奏三个音符的录音使用了傅立叶变换。结果频谱将显示三个峰值,每个音符一个。如果该人弹奏一个音符比其他音符更轻柔,那么该音符的频率强度将低于其他两个。
这是钢琴示例在视觉上的样子:
钢琴上最高的音符比其他两个音符更安静,因此该音符的频谱具有较低的峰值。
为什么需要Fourier Transform?傅立叶变换在许多应用中都很有用。例如,Shazam和其他音乐识别服务使用傅立叶变换来识别歌曲。
JPEG 压缩使用傅立叶变换的变体来去除图像的高频分量。语音识别使用傅立叶变换和相关变换从原始音频中恢复口语。小程序源码oem
通常,如果您需要查看信号中的频率,则需要进行傅立叶变换。如果在时域中处理信号很困难,那么使用傅立叶变换将其移动到频域中是值得尝试的。在下一节中,您将了解时域和频域之间的差异。
Time Domain vs Frequency Domain在本教程的其余部分,您将看到术语time domain和frequency domain。这两个术语指的是查看信号的两种不同方式,要么是其分量频率,要么是随时间变化的信息。
在时域中,信号是幅度(y 轴)随时间(x 轴)变化的波。您很可能习惯于在时域中看到图形,例如这个:
这是一些音频的图像,它是一个时域信号。横轴表示时间,纵轴表示幅度。
在频域中,信号表示为一系列频率(x 轴),每个频率都有相关的功率(y 轴)。下图是上述经过Fourier Transform 后的音频信号:
此处,之前的音频信号由其组成频率表示。底部的每个频率都有一个相关的功率,产生您看到的频谱。
有关频域的更多信息,请查看DeepAI 词汇表条目。
Fourier Transform的类型傅立叶变换可以细分为不同类型的变换。最基本的细分是基于变换操作的数据类型:连续函数或离散函数。本教程将仅处理离散傅立叶变换 (DFT)。
即使在本教程中,您也会经常看到 DFT 和 FFT 这两个术语互换使用。然而,它们并不完全相同。的快速傅立叶变换(FFT)是用于计算离散傅立叶变换(DFT)的算法,而DFT是变换本身。
您将在scipy.fft库中看到的另一个区别是不同类型的输入之间的区别。fft()接受复数值输入,并rfft()接受实数值输入。跳到使用快速傅立叶变换 (FFT) 部分以了解复数和实数。
另外两个变换与 DFT 密切相关:离散余弦变换 (DCT)和离散正弦变换 (DST)。您将在离散余弦和正弦变换部分中了解这些内容。
实际示例:从音频中去除不需要的噪音为了帮助您理解傅立叶变换以及您可以用它做什么,您将过滤一些音频。首先,您将创建一个带有高音嗡嗡声的音频信号,然后您将使用傅立叶变换去除嗡嗡声。
创建信号正弦波有时被称为纯音,因为它们代表单一频率。您将使用正弦波来生成音频,因为它们将在生成的频谱中形成不同的峰值。
正弦波的另一个优点是它们可以使用 NumPy 直接生成。如果您之前没有使用过 NumPy,那么您可以查看什么是 NumPy?
这是一些生成正弦波的代码:
importnumpyasnpfrommatplotlibimportpyplotaspltSAMPLE_RATE=#HertzDURATION=5#Secondsdefgenerate_sine_wave(freq,sample_rate,duration):x=np.linspace(0,duration,sample_rate*duration,endpoint=False)frequencies=x*freq#2pibecausenp.sintakesradiansy=np.sin((2*np.pi)*frequencies)returnx,y#Generatea2hertzsinewavethatlastsfor5secondsx,y=generate_sine_wave(2,SAMPLE_RATE,DURATION)plt.plot(x,y)plt.show()你以后导入与NumPy和Matplotlib,可以定义两个常量:
SAMPLE_RATE确定信号每秒使用多少个数据点来表示正弦波。因此,如果信号的采样率为 Hz,并且是 5 秒的正弦波,那么它就会有 * 5 = 数据点。
DURATION 是生成样本的长度。
接下来,您定义一个函数来生成正弦波,因为您将在以后多次使用它。该函数采用频率 ,freq然后返回用于绘制波形的x和y值。
正弦波的 x 坐标在0和之间均匀分布DURATION,因此代码使用 NumPylinspace()来生成它们。它需要一个起始值、一个结束值和要生成的样本数。设置endpoint=False对于傅立叶变换正常工作很重要,因为它假设信号是周期性的。
np.sin()计算每个 x 坐标处的正弦函数值。结果乘以频率,使正弦波在该频率振荡,乘积乘以 2π 以将输入值转换为弧度。
注意:如果您之前没有学过太多三角学,或者您需要复习,那么请查看可汗学院的三角学课程。
定义函数后,您可以使用它生成一个持续 5 秒的 2 赫兹正弦波,并使用 Matplotlib 绘制它。您的正弦波图应如下所示:
x 轴以秒为单位表示时间,由于每一秒的时间有两个峰值,您可以看到正弦波每秒振荡两次。此正弦波的频率太低而无法听到,因此在下一部分中,您将生成一些更高频率的正弦波,您将了解如何混合它们。
混合音频信号好消息是混合音频信号只包括两个步骤:
将信号相加
标准化结果
在将信号混合在一起之前,您需要生成它们:
_,nice_tone=generate_sine_wave(,SAMPLE_RATE,DURATION)_,noise_tone=generate_sine_wave(,SAMPLE_RATE,DURATION)noise_tone=noise_tone*0.3mixed_tone=nice_tone+noise_tone此代码示例中没有任何新内容。它生成分别分配给变量 nice_tone和 的中音和高音noise_tone。您将使用高音作为您不需要的噪音,因此它会乘以0.3降低其功率。然后代码将这些音调加在一起。请注意,您使用下划线 ( _) 来丢弃由x返回的值generate_sine_wave()。
下一步是归一化,或缩放信号以适应目标格式。由于您稍后将如何存储音频,您的目标格式是一个 位整数,范围从 - 到 :
normalized_tone=np.int((mixed_tone/mixed_tone.max())*)plt.plot(normalized_tone[:])plt.show()在这里,代码进行缩放mixed_tone以使其适合 位整数,然后使用 NumPy 的np.int. 除mixed_tone以其最大值将其缩放到-1和之间1。当这个信号乘以 时,它在-和之间缩放,大致是 的范围np.int。该代码仅绘制第一个样本,以便您可以更清楚地看到信号的结构。
你的情节应该是这样的:
信号看起来像失真的正弦波。您看到的正弦波是您生成的 Hz 音调,失真是 Hz 音调。如果仔细观察,您会发现失真呈正弦波形状。
要收听音频,您需要将其存储为音频播放器可以读取的格式。最简单的方法是使用 SciPy 的wavfile.write方法将其存储在 WAV 文件中。 位整数是 WAV 文件的标准数据类型,因此您需要将信号标准化为 位整数:
fromscipy.io.wavfileimportwrite#RememberSAMPLE_RATE=Hzisourplaybackratewrite("mysinewave.wav",SAMPLE_RATE,normalized_tone)此代码将写入mysinewave.wav您运行 Python 脚本的目录中的文件。然后,您可以使用任何音频播放器甚至Python收听此文件。您会听到较低的音调和较高的音调。这些是您混合的 Hz 和 Hz 正弦波。
完成此步骤后,您的音频样本就准备好了。下一步是使用傅立叶变换去除高音!
使用快速Fourier Transform (FFT)是时候在生成的音频上使用 FFT 了。FFT 是一种实现傅立叶变换的算法,可以计算时域中信号的频谱,例如您的音频:
fromscipy.fftimportfft,fftfreq#Numberofsamplesinnormalized_toneN=SAMPLE_RATE*DURATIONyf=fft(normalized_tone)xf=fftfreq(N,1/SAMPLE_RATE)plt.plot(xf,np.abs(yf))plt.show()此代码将计算生成的音频的Fourier Transform 并绘制它。在分解它之前,先看看它产生的情节:
您可以看到正频率中的两个峰值和负频率中这些峰值的镜像。正频率峰值位于 Hz 和 Hz,这对应于您输入音频的频率。
Fourier transform 已经将您复杂的、微弱的信号转化为它所包含的频率。因为你只输入了两个频率,所以只有两个频率出来了。负正对称性是将实值输入放入 Fourier transform 的副作用,但稍后您会听到更多相关信息。
在前几行中,您导入scipy.fft稍后将使用的函数,并定义一个变量N,用于存储信号中的样本总数。
在这之后是最重要的部分,计算 Fourier transform :
yf=fft(normalized_tone)xf=fftfreq(N,1/SAMPLE_RATE)代码调用了两个非常重要的函数:
fft() 计算变换本身。
fftfreq()计算 的输出中每个bin中心的频率fft()。没有这个,就无法在频谱上绘制 x 轴。
甲箱是已经被分组,就像在一个值的范围的直方图。有关bin 的更多信息,请参阅此信号处理堆栈交换问题。出于本教程的目的,您可以将它们视为单个值。
一旦您获得了 Fourier transform 的结果值及其相应的频率,您就可以绘制它们:
plt.plot(xf,np.abs(yf))plt.show()这段代码有趣的部分是您yf在绘制之前所做的处理。你呼吁np.abs()是yf因为它的价值是复杂的。
甲复数是一个数,其具有两个部分,即实部和虚部。定义这样的数字很有用的原因有很多,但您现在需要知道的是它们存在。
数学家通常以a + bi的形式书写复数,其中a是实部,b是虚部。b后面的i表示b是虚数。
注意:有时您会看到使用i编写的复数,有时您会看到使用j编写的复数,例如 2 + 3 i和 2 + 3 j。两者是一样的,但i被数学家用得更多,而j被工程师用得更多。
有关复数的更多信息,请查看可汗学院的课程或数学很有趣页面。
由于复数有两个部分,将它们与二维轴上的频率作图需要您从它们计算一个值。这就是np.abs()进来的地方。它计算复数的 √(a? + b?),这是两个数字的整体大小,重要的是单个值。
注意:顺便说fft()一句,您可能已经注意到,准确地说,返回的最大频率刚好超过 , 赫兹,即 Hz。这个值正好是我们采样率的一半,称为奈奎斯特频率。
这是信号处理中的一个基本概念,意味着您的采样率必须至少是信号最高频率的两倍。
让它更快 rfft()fft()输出的频谱绕y轴反射,因此负半部是正半部的镜子。这种对称性是由向变换输入实数(不是复数)引起的。
您可以使用这种对称性,通过只计算它的一半来使您的 Fourier transform 更快。scipy.fft以rfft().
很棒的一点rfft()是,它是fft(). 记住之前的 FFT 代码:
yf=fft(normalized_tone)xf=fftfreq(N,1/SAMPLE_RATE)换入rfft(),代码基本保持不变,只是有几个关键的变化:
fromscipy.fftimportrfft,rfftfreq#Notetheextra'r'atthefrontyf=rfft(normalized_tone)xf=rfftfreq(N,1/SAMPLE_RATE)plt.plot(xf,np.abs(yf))plt.show()由于rfft()只返回一半的输出fft(),它使用不同的函数来获取频率映射,rfftfreq()而不是fftfreq()。
rfft()仍然会产生复杂的输出,因此绘制其结果的代码保持不变。但是,该图应如下所示,因为负频率将消失:
您可以看到上图只是fft()产生的频谱的正侧。rfft()从不计算频谱的负半部分,这使得它比使用fft().
usingrfft()可以比 using 快两倍fft(),但某些输入长度比其他输入长度快。如果你知道你只会使用实数,那么这是一个值得了解的速度技巧。
现在您有了信号的频谱,您可以继续对其进行滤波。
过滤信号傅立叶变换的一大优点是它是可逆的,因此您在频域中对信号所做的任何更改都将在您将其变换回时域时应用。您将利用这一点来过滤音频并去除高频。
警告:本节中演示的过滤技术不适用于现实世界的信号。有关原因的解释,请参阅避免过滤陷阱部分。
返回的值rfft()代表每个频率仓的功率。如果您将给定 bin 的功率设置为零,则该 bin 中的频率将不再出现在生成的时域信号中。
使用 的长度xf、最大频率以及频率区间均匀分布的事实,您可以计算出目标频率的索引:
importnumpyasnpfrommatplotlibimportpyplotaspltSAMPLE_RATE=#HertzDURATION=5#Secondsdefgenerate_sine_wave(freq,sample_rate,duration):x=np.linspace(0,duration,sample_rate*duration,endpoint=False)frequencies=x*freq#2pibecausenp.sintakesradiansy=np.sin((2*np.pi)*frequencies)returnx,y#Generatea2hertzsinewavethatlastsfor5secondsx,y=generate_sine_wave(2,SAMPLE_RATE,DURATION)plt.plot(x,y)plt.show()0然后,您可以在目标频率周围的索引处设置yf为0以摆脱它:
yf[target_idx-1:target_idx+2]=0plt.plot(xf,np.abs(yf))plt.show()您的代码应生成以下图:
既然只有一个峰,看来是奏效了!接下来,您将应用Fourier Transform返回时域。
应用逆 FFT应用逆 FFT 类似于应用 FFT:
importnumpyasnpfrommatplotlibimportpyplotaspltSAMPLE_RATE=#HertzDURATION=5#Secondsdefgenerate_sine_wave(freq,sample_rate,duration):x=np.linspace(0,duration,sample_rate*duration,endpoint=False)frequencies=x*freq#2pibecausenp.sintakesradiansy=np.sin((2*np.pi)*frequencies)returnx,y#Generatea2hertzsinewavethatlastsfor5secondsx,y=generate_sine_wave(2,SAMPLE_RATE,DURATION)plt.plot(x,y)plt.show()2由于您正在使用rfft(),您需要使用irfft()来应用逆。但是,如果您使用了fft(),则反函数将是ifft()。你的情节现在应该是这样的:
如您所见,您现在有一个以 Hz 振荡的正弦波,并且您已成功消除了 Hz 噪声。
再一次,您需要在将信号写入文件之前对其进行标准化。你可以像上次那样做:
importnumpyasnpfrommatplotlibimportpyplotaspltSAMPLE_RATE=#HertzDURATION=5#Secondsdefgenerate_sine_wave(freq,sample_rate,duration):x=np.linspace(0,duration,sample_rate*duration,endpoint=False)frequencies=x*freq#2pibecausenp.sintakesradiansy=np.sin((2*np.pi)*frequencies)returnx,y#Generatea2hertzsinewavethatlastsfor5secondsx,y=generate_sine_wave(2,SAMPLE_RATE,DURATION)plt.plot(x,y)plt.show()3