矩阵数组到多维 RGB 图像数组并使用 imresize 重塑图像

Matrix array to multidimensional RGB image array and using imresize to reshape image

我正在使用 Octave 5.2 并且可以使用 meshgridreshape 从 RGB 值数组创建一个 640 x 480 x 3 的图像但是有更好的方法吗? ( 代码在 下方)我尝试使用 catimresize with nearest 但数组是 640x480 而不是 640x480x3 并且由于数组不在一个 640x480x3 的格式可以解决这个问题以获得彩色条形图吗?

f(:,:,1)=[255;0;0;0;0];
f(:,:,2)=[0;255;0;0;255];
f(:,:,3)=[0;0;255;0;2];

num_of_colors=numel(f(:,:,1));
img_resize_height=640
img_resize_height_tmp=round(img_resize_height/num_of_colors); %create the height wanted

%1) create size of array wanted 
[r_im_tmp_x r_im_tmp_y]=meshgrid((f(:,:,1)),1:img_resize_height_tmp)
[g_im_tmp_x g_im_tmp_y]=meshgrid((f(:,:,2)),1:img_resize_height_tmp);
[b_im_tmp_x b_im_tmp_y]=meshgrid((f(:,:,3)),1:img_resize_height_tmp);

%2) reshape grid to evenly space out colors (in one column)
r_resize_tmp=reshape(r_im_tmp_x,[1,numel(r_im_tmp_x)])';
g_resize_tmp=reshape(g_im_tmp_x,[1,numel(g_im_tmp_x)])';
b_resize_tmp=reshape(b_im_tmp_x,[1,numel(b_im_tmp_x)])';

%3 make array size wanted 480
img_resize_len=480;
r_resize_tmp2=repmat(r_resize_tmp,([1,img_resize_len]));
g_resize_tmp2=repmat(g_resize_tmp,([1,img_resize_len]));
b_resize_tmp2=repmat(b_resize_tmp,([1,img_resize_len]));

img_resize_rgb(:,:,1)=r_resize_tmp2;
img_resize_rgb(:,:,2)=g_resize_tmp2;
img_resize_rgb(:,:,3)=b_resize_tmp2;

figure(1);
imshow(img_resize_rgb);

它创建的图像是正确的,似乎有更简单/更好的编码方法。

我尝试使用 imresize 命令来做同样的事情来改进代码。 (见下面的代码)。

pkg load image

f(:,:,1)=[255;0;0;0;0];
f(:,:,2)=[0;255;0;0;255];
f(:,:,3)=[0;0;255;0;2];

height_wanted=640;
width_wanted=480;

repmat_rgb=cat(2,f,f); %add another column to array to get imresize to work
reshaped_output = imresize(repmat_rgb, [height_wanted, width_wanted],'nearest'); %reshape swatch to large output
imshow(reshaped_output);

创建的图像 不正确 并且是黑白的(很可能是因为数组是 640x480 而不是 640x480x3(我该如何解决这个问题?)

它看起来像是 imresize Octave 图像包实现中的错误(在 MATLAB 中,代码可以正常工作)。

imresize的输入是RGB(3D矩阵)时,输出也应该是RGB(3D矩阵)。
在您的示例中,输出为灰度(2D 矩阵而不是 3D 矩阵)。
这是 imresize 实现中的一个 错误 !


该功能是“开源”的,我们可以使用调试器对其进行调试。
逐步执行代码(进入imresize)让我们得到以下代码:

  elseif (strcmpi (method, "nearest") && all ([int_row_scale int_col_scale]))
    ## we are matlab incompatible here on purpose. We can the stuff here in 2
    ## ways. With interp2 or by clever indexing. Indexing is much much faster
    ## than interp2 but they return different results (the way we are doing it
    ## at least). Matlab does the same as we are doing if the both columns and
    ## rows go the same direction but if they increase one and decrease the
    ## other, then they return the same as if we were using interp2. We are
    ## smarter and use indexing even in that case but then the results differ
    if (int_row_scale == 1)
      row_idx = (1:rows (im))(ones (1, scale_rows), :);
    elseif (int_row_scale == -1)
      row_idx = ceil (linspace (floor (1/(scale_rows * 2)) + 1, inRows, outRows));
    endif
    if (int_col_scale == 1)
      col_idx = (1:columns (im))(ones (scale_cols, 1), :);
    elseif (int_col_scale == -1)
      col_idx = ceil (linspace (floor (1/(scale_cols * 2)) + 1, inCols, outCols));
    endif
    im = im(row_idx, col_idx);

错误在上面部分的最后一行。

而不是 im = im(row_idx, col_idx); 应该是:

im = im(row_idx, col_idx, :);

如果您不想编辑“image package”代码,您可以使用以下解决方法:
调整每个颜色通道的大小并连接调整大小的通道。

reshaped_output = imresize(repmat_rgb, [height_wanted, width_wanted], 'nearest'); 替换为:

out_r = imresize(repmat_rgb(:, :, 1), [height_wanted, width_wanted], 'nearest');
out_g = imresize(repmat_rgb(:, :, 2), [height_wanted, width_wanted], 'nearest');
out_b = imresize(repmat_rgb(:, :, 3), [height_wanted, width_wanted], 'nearest');
reshaped_output = cat(3, out_r, out_g, out_b);

注:
f的class是double,取值范围应该是[0, 1].
使用 imshow.

时,所有高于 1 的值都被剪裁为 1

您可以将 f 初始化为:

f(:,:,1)=[1;0;0;0;0];
f(:,:,2)=[0;1;0;0;1];
f(:,:,3)=[0;0;1;0;1];

或转换为 uint8:

f(:,:,1)=[255;0;0;0;0];
f(:,:,2)=[0;255;0;0;255];
f(:,:,3)=[0;0;255;0;255];
f = uint8(f);