【问题标题】:Singular value decomposition (svd) and mean does not exclude masked values during computation奇异值分解 (svd) 和均值在计算过程中不排除掩码值
【发布时间】:2015-08-02 14:51:36
【问题描述】:

我是 python 编程的新手,如果我的问题太基本,请原谅我。之前这个论坛给了我很多帮助,感谢你们的所有贡献。

这次我有一组 12,000 个图像数据,我正在对其执行奇异值分解 (svd) 并计算它们的平均值。一些图像的像素具有非常高的正值或负值,我不想在计算过程中使用,所以我使用了 numpy.ma.masked_array 将它们从 svd 和均值计算中排除。有些图像比其他图像小,它们被填充零值以使所有图像具有相同的(像素)尺寸。但我也不希望在计算过程中使用“零填充”,所以我使用numpy.ma.masked_array 将它们从 svd 和均值计算中排除。

以下是一些示例图片:

问题是,当我同时执行 svd 和均值计算时,在计算过程中不会排除屏蔽值(数组元素)。我已经尝试了我所知道的一切来解决这个问题,但没有成功。以下是我采取的步骤。

from numpy.linalg import svd
import numpy as np
from numpy.ma import masked_array


n, x, y = images.data.shape
Z = []
meanimage = []

for icount in range(n):
    image = images[icount,:,:] # current image

    # creating a mask for too positively or negatively high values
    mask = (np.abs(image) > 2).astype(int); 
    yindex = 0; xindex = 0; 

    # --- creating a mask for zero padded values
    for i in range(y/2): # get the index of the first none zero pixel
        if image[i,x/2] != 0: 
            yindex = i
            break
    for i in range(x/2): # get the index of the first none zero pixel
        if image[y/2,i] != 0: 
            xindex = i
            break
    mask[:yindex,:] = 1;mask[-yindex:,:] = 1;
    mask[:xindex,:] = 1;mask[-xindex:,:] = 1;
    # --- 

    image = masked_array(images[icount,:,:], mask)

    Z.append(image.ravel())  # accummulating matrix for svd computation
    meanimage.append(image)  # accummulating matrix for for mean computation

# calc. SVD
u,s,v = svd(masked_array(Z))

#calc. mean image
meanimage = masked_array(meanimage).mean(axis=0)

bimage = np.dot(np.dot(u[:,:2],np.diag(s[:2])),np.transpose(v)[:2,:])

eigenimage = bimage[2,:].reshape(x, y)

我得到的最终结果——eigenimagemeanimage——并没有从计算中排除屏蔽值。我不知道我做错了什么。拜托,我需要一些想法来帮助我解决这个问题。

以上是我正在使用的图像(光束)数据的一些示例。

在计算特征图像和平均图像后得到的最终图像是:

特征(光束)图像(带 SVD)

平均(光束)图像(masked_array mean)

从上图中,eigenimage 和 meanimage 都丢失了很多不想要的旁瓣信息。

但我期待最终的特征图像是这样的

【问题讨论】:

  • 许多线性代数运算尚不支持掩码数组(see here 获取支持的运算符列表)。虽然平均值应该有效,但 SVD 不会。一种解决方法是为您认为在所有图像中有效的像素构建一个布尔索引,并仅对这些像素执行 SVD。
  • 通常只有np.ma 子模块(和屏蔽的数组方法)中的函数才会考虑屏蔽。大多数其他 numpy 代码不知道掩码。掩码数组是带有“附加”掩码和相关参数的常规数组。 svddot 只适用于常规数组。
  • 如何使用掩码filled 将某种中性值放入数组中?根据您的尝试,它可能是10nan 或其他东西。屏蔽应该如何影响svd
  • 为了更好地传达我想要存档的内容,以下是我正在使用的图像数据的大约 5 个样本(我有大约 12,000 张图像)。 ![图 1]:/home/kela/Documents/work/sample_images.png 在上图中,我想屏蔽每个图像中的所有零像素,用于填充它们以使所有图像具有相同的 128 尺寸128,因此在svd 计算期间不应使用这些填充像素。因为如果不掩盖它们,它们会影响最终得到的特征图像。
  • 请@ali_m,详细说明我如何构建(和使用)“所有图像中有效像素的布尔索引”以及如何指示 SVD 仅使用它们进行计算。

标签: python numpy linear-algebra svd


【解决方案1】:

masked_array 均值实际上从均值计算中排除了掩码像素(“零填充”)。我通过将此结果与不带掩码计算的结果进行比较来确认这一点,并注意到一个显着的差异,这证实了numpy.ma.masked_array mean 非常适合我的情况。

在 SVD 特征图像上: 问题在于转置v (np.transpose(v))。我从文档 (1) 中发现numpy.linalg.svd 返回了v 的转置,所以我只需要执行点积而不转置v

bimage = np.dot(np.dot(u[:,:2],np.diag(s[:2])),v[:2,:])

【讨论】:

    猜你喜欢
    • 2011-06-30
    • 2010-10-31
    • 2015-04-16
    • 2010-10-06
    • 2016-01-10
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多