绘制图像的功率谱密度与x/y轴的关系

3
一位研究教授要求我为几个视频生成2D空间频谱密度图。 我有两个问题:
  1. 如何绘制PSD vs x、y轴?
  2. 我知道如何为图像生成PSD,但不确定如何在视频中执行相同操作。 我想对视频中的每个帧获取PSD并取平均值,但我在Python中实现时遇到了困难。
以下是我的代码:
curr_dir = os.getcwd()
img = cv2.imread(curr_dir+'/test.jpg',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
mag = 20*np.log(np.abs(fshift))
plt.subplot(121), plt.imshow(img,cmap='gray')
plt.subplot(122), plt.imshow(mag,cmap='gray')
plt.show()

这将生成类似于这样的内容:

输入图像描述

我想要得到类似于这样的内容:

输入图像描述

非常感谢您的任何帮助和建议!

1
你是想为视频中的每一帧生成一个二维空间谱密度图,从而形成一个随时间变化的 PSD 立方体吗?还是想为每一帧生成一个一维 PSD,制作一个瀑布图,其中一个轴是 PSD,另一个轴是时间? - Engineero
@Engineero 你好,我正在尝试为视频生成空间谱密度图(我知道这听起来很奇怪,但这是要求我的)。我想绘制PSD的x(顺风)和y(横风)分量与频率的图。 - Gao
1个回答

2
由于您展示了两个一维光谱图,因此似乎您正在寻找以下内容。
我们读取图像,沿一个轴进行傅里叶变换,然后在另一个轴上将每个箱中的功率相加。由于输入是实值,因此我们使用rfft(),以便不必移动频谱,并使用rfftreq()计算每个箱的频率。我们绘制结果,省略0频率箱中的信号(对应于基线),以便有用的部分出现在方便的比例尺上。
#!/usr/bin/python3
import cv2
import os
import math
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

curr_dir = os.getcwd()
img = cv2.imread(curr_dir+'/temp.png',0)
print( img.shape )

# Fourier Transform along the first axis

# Round up the size along this axis to an even number
n = int( math.ceil(img.shape[0] / 2.) * 2 )

# We use rfft since we are processing real values
a = np.fft.rfft(img,n, axis=0)

# Sum power along the second axis
a = a.real*a.real + a.imag*a.imag
a = a.sum(axis=1)/a.shape[1]

# Generate a list of frequencies
f = np.fft.rfftfreq(n)

# Graph it
plt.plot(f[1:],a[1:], label = 'sum of amplitudes over y vs f_x')

# Fourier Transform along the second axis

# Same steps as above
n = int( math.ceil(img.shape[1] / 2.) * 2 )

a = np.fft.rfft(img,n,axis=1)

a = a.real*a.real + a.imag*a.imag
a = a.sum(axis=0)/a.shape[0]

f = np.fft.rfftfreq(n)

plt.plot(f[1:],a[1:],  label ='sum of amplitudes over x vs f_y')

plt.ylabel( 'amplitude' )
plt.xlabel( 'frequency' )
plt.yscale( 'log' )

plt.legend()

plt.savefig( 'test_rfft.png' )
#plt.show()

将这个应用于您问题中发布的照片,会产生以下结果: enter image description here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接