【问题标题】:Displaying .mat format grayscale image in R在 R 中显示 .mat 格式的灰度图像
【发布时间】:2016-05-28 23:14:11
【问题描述】:

我阅读了this post,并天真地试图显示一个灰度图像,其中包含从.mat 格式的矩阵中随机抽取的 100 个手写数字,该矩阵包含 5000 行,每行对应一个手写数字。我使用以下代码:

library(R.matlab)
data <- readMat('data.mat')
X = data$X
X = X[sample(nrow(X), size=100, replace=F),]

par(mar = rep(0, 4))
image(X, axes = FALSE, col = grey(seq(0, 1, length = 256)))

结果并不好,因为事实证明矩阵中的每个 400 元素行向量都为一个像素的 20 x 20 像素图像提供了信息;因此,如果我们想让它们并排显示,则必须先验地设置各个数字的单独显示图像的高度和宽度。这就是我的编码“技能”不足的地方。

我已保存dataset here。需要明确的是,图像位于 R str(data) 列表的 X 对象中:

List of 2
 $ X: num [1:5000, 1:400] 0 0 0 0 0 0 0 0 0 0 ...
 $ y: num [1:5000, 1] 10 10 10 10 10 10 10 10 10 10 ...
 - attr(*, "header")=List of 3
  ..$ description: chr "MATLAB 5.0 MAT-file, Platform: PCWIN64, Created on: Sat May 28 18:21:58 2016                                        "
  ..$ version    : chr "5"
  ..$ endian     : chr "little"

如果我在用它构建20 x 20 矩阵后限制自己只显示矩阵X 的一行,我就更接近目标了:

X = data$X
X = X[sample(nrow(X), size = 1 ,replace=F),]
X = matrix(X, nrow = 20, byrow= T)

par(mar = rep(0, 4))
image(X, axes = FALSE, col = grey(seq(0, 1, length = 256)))

matlab中将矩阵数据拆解成图像的代码是:

function [h, display_array] = displayData(X, example_width)
%DISPLAYDATA Display 2D data in a nice grid
%   [h, display_array] = DISPLAYDATA(X, example_width) displays 2D data
%   stored in X in a nice grid. It returns the figure handle h and the 
%   displayed array if requested.

% Set example_width automatically if not passed in
if ~exist('example_width', 'var') || isempty(example_width) 
    example_width = round(sqrt(size(X, 2)));
end

% Gray Image
colormap(gray);

% Compute rows, cols
[m n] = size(X);
example_height = (n / example_width);

% Compute number of items to display
display_rows = floor(sqrt(m));
display_cols = ceil(m / display_rows);

% Between images padding
pad = 1;

% Setup blank display
display_array = - ones(pad + display_rows * (example_height + pad), ...
                       pad + display_cols * (example_width + pad));

% Copy each example into a patch on the display array
curr_ex = 1;
for j = 1:display_rows
    for i = 1:display_cols
        if curr_ex > m, 
            break; 
        end
        % Copy the patch

        % Get the max value of the patch
        max_val = max(abs(X(curr_ex, :)));
        display_array(pad + (j - 1) * (example_height + pad) + (1:example_height), ...
                      pad + (i - 1) * (example_width + pad) + (1:example_width)) = ...
                        reshape(X(curr_ex, :), example_height, example_width) / max_val;
        curr_ex = curr_ex + 1;
    end
    if curr_ex > m, 
        break; 
    end
end

% Display Image
h = imagesc(display_array, [-1 1]);

% Do not show axis
axis image off

drawnow;

end

导致:

【问题讨论】:

    标签: r image matlab


    【解决方案1】:

    这会将矩阵行重塑为块。不能保证非常高效,但对于您的示例中的 100x400 矩阵来说已经足够快了。

    # get 100 random rows of X
    X <- data$X
    X <- X[sample(nrow(X), size=100, replace=FALSE),]
    
    # allocate empty image matrix (200 by 200 pixels)
    Z <- matrix(rep(0, length(X)), nrow=200)
    
    # fill empty image matrix
    for (row in 0:9) {
        rmin <- 1 + (row)*20
        for (col in 0:9) {
            cmin <- 1 + (col)*20
            Z[rmin:(rmin+19), cmin:(cmin+19)] <- X[row * 10 + col + 1,]
        }
    }
    # plot (after rotating matrix 90 degrees)
    image(t(apply(Z, 2, rev)))
    

    【讨论】:

    • 谢谢。不过,我得到了一个非常不同的图像。检查我编辑的 OP 上的图像。
    • 看起来有很多零。也许训练数据中的数字是有序的……你做了随机化步骤吗?
    • 是的,我更改了X 的名称,但我严格地保留了最后一个X,绕过sample() 过程。代码末尾缺少括号。请添加它。我冒昧地发布生成的图像 - 您可以留下它,或者在插入最后一个括号时将其删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多