使用for循环对子图像进行子采样

RN9*_*N95 0 matlab for-loop image image-processing matrix

我有一个关于对矩阵/图像进行二次采样的快速问题.我只是在使用for和/或while循环时尝试这样做.基本上问题是重申:

function output = subsample(img,2)

output = img(1:factor:end, 1:factor:end);
Run Code Online (Sandbox Code Playgroud)

但是,现在我试图重写函数来执行完全相同的过程但是使用for循环和/或while循环并且不使用两个或更多" :"(冒号)运算符而不使用冒号运算符访问矩阵/向量元素.这是我到目前为止:

function output = subsamplex(img,factor)

[r, c] = size(img);

output = zeros(r/factor,c/factor);

j = 1;

i = 1;

for x = 1:r;

    for y = 1:c;
        j = factor*j-1;
        i = factor*i-1;
        output(j,i) = img(x,y);
    end
end

end
Run Code Online (Sandbox Code Playgroud)

虽然我得到的是图像调整大小,它全是黑色的,我试图弄清楚我哪里出错或者我完全错了.任何正确方向的帮助将不胜感激.

ray*_*ica 5

罪魁祸首是嵌套for循环中的以下两个语句:

j = factor*j-1;
i = factor*i-1;
Run Code Online (Sandbox Code Playgroud)

例如,如果我们设置factor = 2,那么factor*j - 1更新操作j将始终j在每次for循环迭代时保持不变.具体来说,如果j = 1最初,有了j <- factor*j - 1,那么无论我们在循环中进行什么迭代,你都会得到j <- 2*1 - 1 = 1并且你将永远得到j = 1.因此,您只更新输出图像的左上角,此位置将一直覆盖,直到我们点击图像的最后一个像素,并且左上角最后是原始图像的最后一行和最后一列.这可能就是为什么你有一个黑色图像,因为你已经将输出图像初始化为全黑像素,但你只是更新图像中的一个像素.因此,您需要更改j(当然i)更新的方式.

我也将改变你接近问题的方式.相反,我们将迭代二次采样图像的尺寸,然后对于二次采样图像中的每个位置,我们将从原始图像中拉出右像素.给定(x,y)二次采样图像中的行和列位置以及子采样因子factor,(j,i)从原始图像访问的行和列位置为:

j = factor*(x-1) + 1;
i = factor*(y-1) + 1;
Run Code Online (Sandbox Code Playgroud)

这是假设,x并且y都从1开始.如果你替换的值xy1,2,...你开始,你可以看到上面的公式挑选出依赖于的正确像素factor.例如,如果factor = 2,替换值xyof 1,2,...将给出:

j = 1, 3, 5, ...
i = i, 3, 5, ...
Run Code Online (Sandbox Code Playgroud)

你可以看到我们正在跳过所有其他像素,这是有意义的,因为这是2的因素.我将把它留作练习,但如果你尝试使用任何其他值,你会发现我们正在跳过右边的像素从源中抓取正确的像素以复制到输出图像.

有了这一切,这是你修改过的代码:

function output = subsamplex(img,factor)

[r, c] = size(img);

output = zeros(r/factor,c/factor,class(img)); %// Cast to be sure
[rnew, cnew] = size(output); %// Change - get size of output

for x = 1:rnew %// Change for loop limits
    for y = 1:cnew
        j = factor*(x-1) + 1; %// Change
        i = factor*(y-1) + 1;
        output(x,y) = img(j,i);
    end
end

end
Run Code Online (Sandbox Code Playgroud)

通过上面的代码,我运行了这个cameraman.tif,如果你有图像处理工具箱,它是MATLAB附带的示例图像的一部分.它看起来像这样:

在此输入图像描述

因此,如果我想要子代码为2,我们会:

img = imread('cameraman.tif');
out = subsamplex(img, 2);
imshow(out); %// Show the image
Run Code Online (Sandbox Code Playgroud)

我明白了:

在此输入图像描述