我正在尝试根据 Python 中的 2D NPS 估计空间域中像素值的 SD。
我希望需要 NPS 值的总和除以像素总数。然而,我只能通过平均值除以像素总数来达到正确的估计。
任何人都可以指出我为什么会这样吗?
请参阅下面的代码示例。
“SUM: “
import numpy as np
from scipy.fftpack import fft2, fftshift
# Generate a random 128x128 image
image = np.random.rand(128, 128)*100
# Subtract the mean of the image
image = image - np.mean(image)
# Compute the 2D Fourier transform of the image
F = fft2(image)
# Shift the zero frequency component to the center
F_shifted = fftshift(F)
# Calculate the Noise Power Spectrum (NPS)
NPS = np.abs(F_shifted)**2
# Calculate the total power in the NPS
total_power = np.sum(NPS)
# The total power in the NPS corresponds to the sum of the squared deviations
# from the mean in the spatial domain. For an image of size NxN:
N = image.shape[0]
variance_from_nps = total_power / (N * N)
# Compute the standard deviation from the variance
sigma_from_nps = np.sqrt(variance_from_nps)
# Compute the standard deviation directly from the image
sd_direct = np.std(image)
print(f"Standard Deviation from NPS: {sigma_from_nps}")
print(f"Standard Deviation directly from the image: {sd_direct}")
NPS 的标准偏差:3692.2142651255785 直接来自图像的标准偏差:28.84542394629358
“平均值:”
import numpy as np
from scipy.fftpack import fft2, fftshift
# Generate a random 128x128 image
image = np.random.rand(128, 128)*100
# Subtract the mean of the image
image = image - np.mean(image)
# Compute the 2D Fourier transform of the image
F = fft2(image)
# Shift the zero frequency component to the center
F_shifted = fftshift(F)
# Calculate the Noise Power Spectrum (NPS)
NPS = np.abs(F_shifted)**2
# Calculate the total power in the NPS
total_power = np.mean(NPS)
# The total power in the NPS corresponds to the sum of the squared deviations
# from the mean in the spatial domain. For an image of size NxN:
N = image.shape[0]
variance_from_nps = total_power / (N * N)
# Compute the standard deviation from the variance
sigma_from_nps = np.sqrt(variance_from_nps)
# Compute the standard deviation directly from the image
sd_direct = np.std(image)
print(f"Standard Deviation from NPS: {sigma_from_nps}")
print(f"Standard Deviation directly from the image: {sd_direct}")
来自 NPS 的标准偏差:28.894608971414826 直接来自图像的标准偏差:28.894608971414826
的理解几乎是正确的,混淆源于如何处理二维 NPS 中的功率谱。是对的,空间域中方差(进而得到标准差)与 NPS 中的
总
功率有关。但是,仅仅取
np.mean(NPS)
并不能给出总功率,因为它代表了图像中
平均
噪声功率。
让我们分解一下原因:
-
帕塞瓦尔定理: 对于像图像这样的离散信号,帕塞瓦尔定理指出空间域中信号的总功率等于傅里叶域中信号的总功率(按合适的归一化因子)。这意味着图像像素值的平方和等于其傅里叶变换的平方幅值的总和(即 NPS)。
-
从 NPS 到方差:
-
np.sum(NPS)
给出了傅里叶域中的总功率。 -
要回到空间域中的方差,需要将该总功率除以像素总数 (
N * N
)。这是因为方差是这些平方偏差的 平均值 。
-
-
代码中的问题: 使用
np.mean(NPS)
时,实际上是在计算每个频率分量处的平均噪声功率,而不是总功率。这就是为什么的“平均值”版本偶然给出接近正确标准差值的原因,因为它有效地对 NPS 值求和,然后除以它们的总数(即 NPS 矩阵中的元素数)。
要更正代码并使之更清晰,应该坚持使用
np.sum(NPS)
来计算总功率,然后按照原始方法计算方差和标准差。
以下是更正后的代码:
import numpy as np
from scipy.fftpack import fft2, fftshift
# Generate a random 128x128 image
image = np.random.rand(128, 128) * 100
# Subtract the mean of the image
image = image - np.mean(image)
# Compute the 2D Fourier transform of the image
F = fft2(image)
# Shift the zero frequency component to the center
F_shifted = fftshift(F)
# Calculate the Noise Power Spectrum (NPS)
NPS = np.abs(F_shifted)**2
# Calculate the total power in the NPS
total_power = np.sum(NPS)
# Calculate the variance from the total power
N = image.shape[0]
variance_from_nps = total_power / (N * N)
# Compute the standard deviation from the variance
sigma_from_nps = np.sqrt(variance_from_nps)
# Compute the standard deviation directly from the image
sd_direct = np.std(image)
print(f"Standard Deviation from NPS: {sigma_from_nps}")
print(f"Standard Deviation directly from the image: {sd_direct}")
这将确保根据 NPS 正确计算标准差,并且应该与直接从图像中计算出的标准差相匹配。
标签:python,nps From: 78795596