【问题标题】:Using the SVD rather than covariance matrix to calculate eigenfaces使用 SVD 而不是协方差矩阵来计算特征脸
【发布时间】:2019-03-24 04:47:46
【问题描述】:

我正在使用来自 AT&T (http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html) 的 n = 40 个面孔的集合来尝试通过 SVD 生成特征面孔。

首先我计算平均向量:

然后我从训练集中的每个向量中减去它,将新向量重新整形为 n x (p*q) 矩阵 x 的 1 x (p*q) 列向量,并计算矩阵 X 使得 @987654326 @。 (这就是问题所在:我在 X 中的所有结果都四舍五入为 0,导致特征脸的黑色图像结果如下所示)

然后我计算这个矩阵 X 的 SVD 并尝试通过将其重新整形为 p x q 矩阵来获得酉矩阵第一列的第一个特征面

但是,这是我的结果:

谁能在下面的代码中发现我的错误?任何答案都非常感谢

n = 40;
%read images
A = double(imread('faces_training/1.pgm'));
f(:, :, 1) = A;
for j = 2:n
    f(:, :, j) = double(imread(['faces_training/',num2str(j),'.pgm']));
    A = A + f(:, :, j);
end
%calculate average
a = (1/n)*A;
%imshow(uint8(a))
for i = 1:n
%subtract from images
    x_vector(:, i) = reshape(f(:, :, i) - a, [], 1);
end
X = (1/sqrt(n))*x_vector;
%svd
[U S V] = svd(X);
B = reshape(U(:, 1), [size(a, 1) size(a, 2)]);
imshow(uint8(B))

【问题讨论】:

  • 它是否适用于 imshow(B) 而不是 imshow(uint8(B))
  • 不,因为 B 基本上只是一个双精度数组
  • 如果它是一个介于 0 和 1 之间的双精度数组,则不应应用 uint8,因为您将得到全零。 imshow(B)imshow(uint8(255*B)) 应该可以工作
  • 对不起,我应该指定的。每个双精度数都明显小于 1(实际上,整个向量中的最大值为 0.0271),因此它们最终都为 0。为了确定,我再次尝试了你的两个代码 sn-ps,是的,它们都是黑色的。
  • 那么这可能是计算B时的规范化问题。我添加了图像处理标签,以便您获得更多帮助

标签: matlab image-processing computer-vision svd


【解决方案1】:

做同样的事情,遇到同样的问题。简短的回答是你必须标准化你的特征向量才能得到一个好的图像。在规范化之前,您会注意到您的向量值非常接近 0(可能是因为 svd 的处理方式),这可能意味着它们接近黑色。

无论如何,在你想变换的特征向量上使用这个方程: newpixel[i,j]=(oldpixel[i,j]-min(oldpixel[:,j]))/(max(oldpixel[:,j])--min(oldpixel[:,j]))

【讨论】:

  • 谢谢!我隐约记得这也是我发现的问题——像素值太接近 0,所以我不得不在事后对其进行转换。感谢您简洁明了的回答! (欢迎来到 SO :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 2018-08-25
  • 2011-11-25
  • 2015-03-31
  • 2016-06-02
相关资源
最近更新 更多