实现最近邻居的失真结果图像在Octave中调整大小

时间:2013-01-22 14:43:01

标签: image-processing octave image-resizing

我在Octave中实现了这个算法,根据输入矩阵(c),输出矩阵(o)与预期一致,但imshow()中显示的输出与输入图像不相似。

你能帮我说明这有什么问题吗?

我正在使用在Ubuntu 12.10上运行的GNU Octave 3.6.2。

在下面的例子中,图像的大小为2×2。

来源图片:

输出图片

来源矩阵

ans(:,:,1) =

  237  255   34
  237  255   34
  255  255  255
  255  255  255
    0  255    0
    0  255    0

ans(:,:,2) =

   28  242  177
   28  242  177
  242  242  242
  242  242  242
  162  242    0
  162  242    0

ans(:,:,3) =

   36    0   76
   36    0   76
    0    0    0
    0    0    0
  232    0    0
  232    0    0

输出矩阵

ans(:,:,1) =

   237   237   255   255    34    34
   237   237   255   255    34    34
   237   237   255   255    34    34
   237   237   255   255    34    34
   255   255   255   255   255   255
   255   255   255   255   255   255
   255   255   255   255   255   255
   255   255   255   255   255   255
     0     0   255   255     0     0
     0     0   255   255     0     0
     0     0   255   255     0     0
     0     0   255   255     0     0

ans(:,:,2) =

    28    28   242   242   177   177
    28    28   242   242   177   177
    28    28   242   242   177   177
    28    28   242   242   177   177
   242   242   242   242   242   242
   242   242   242   242   242   242
   242   242   242   242   242   242
   242   242   242   242   242   242
   162   162   242   242     0     0
   162   162   242   242     0     0
   162   162   242   242     0     0
   162   162   242   242     0     0

ans(:,:,3) =

    36    36     0     0    76    76
    36    36     0     0    76    76
    36    36     0     0    76    76
    36    36     0     0    76    76
     0     0     0     0     0     0
     0     0     0     0     0     0
     0     0     0     0     0     0
     0     0     0     0     0     0
   232   232     0     0     0     0
   232   232     0     0     0     0
   232   232     0     0     0     0
   232   232     0     0     0     0

源代码

function out_img = nneig(in_img, x_scale, y_scale);

    in_img_height = size(in_img, 1);
    in_img_width = size(in_img, 2);
    in_img_channels = size(in_img, 3);

    out_img_height = round(in_img_height * y_scale);
    out_img_width = round(in_img_width * x_scale);
    out_img_channels = in_img_channels;

    out_img = zeros(out_img_height, out_img_width, out_img_channels);

    tf_mtx = zeros(3, 3); 
    tf_mtx(1, 1) = 1 / x_scale; 
    tf_mtx(2, 2) = 1 / y_scale; 
    tf_mtx(3, 3) = 1;

    for out_channel = 1:out_img_channels
        for out_line = 1:out_img_height
            for out_col = 1:out_img_width
                org_coord_mtx = floor(tf_mtx * [out_col - 1; out_line - 1; 1]) + [1; 1; 0];
                    org_coord_line = org_coord_mtx(2, 1);
                    org_coord_col = org_coord_mtx(1, 1);
                out_img(out_line, out_col, out_channel) = in_img(org_coord_line, org_coord_col, out_channel);
            end
        end
    end

endfunction

1 个答案:

答案 0 :(得分:1)

问题出在图像的类中。由于您使用zeros创建了它,因此它将为double类。它应该是uint8。您可以使用zeros (x, y, z, "uint8")或最后转换类来完成此操作。更好的选择是使用已经为你思考的imresize()(你可能需要循环通过RGB通道,但我不确定)。

关于你的代码,你应该避免这些循环。当您拥有可能更大的实际图像时,它会真正达到您的性能。只要比例因子是整数,以下代码应该可以更好地工作:

function b = nearestresize (a, row_scale, col_scale)
  row_idx = (1:rows (a))(ones (1, row_scale), :);
  col_idx = (1:columns (a))(ones (col_scale, 1), :);
  b = a(row_idx, col_idx, :);
endfunction

无论如何,您应该使用“最近”方法从图像包中使用imresize(我不确定它对RGB图像的效果如何):

b = imresize (im, [rows cols], "nearest")

请参阅imresize中的代码以了解它是如何工作的(我上面粘贴的代码实际上来自其开发版本)。 Basicall; y,最后使用“最近”的方法归结为interp2()