使用for循环对图像进行子采样 [英] Subsample an image using a for loop

查看:235
本文介绍了使用for循环对图像进行子采样的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于对矩阵/图像进行二次采样的快速问题。我试图在和/或时只使用循环时执行此操作。基本上问题是重复:

I have a quick question about subsampling a matrix / image. I am trying to do this while only using for and/or while loops. Basically the question is a reiteration of:

function output = subsample(img,2)

output = img(1:factor:end, 1:factor:end);

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

However, now I am trying to rewrite the function to do the exact same process but with using for loops and/or while loops and without using two or more ":" (colon) operators and without accessing matrix/vector elements using the colon operator. This is what I have so far:

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

虽然是什么我得到的是图像调整大小,它全是黑色的,我正在试图弄清楚我哪里出错了,或者我是完全错了。非常感谢任何正确方向的帮助。

Though what I'm getting is the image resized, it's all black and I'm trying to figure out where I am going wrong or if I am completely wrong. Any help in the right direction will be greatly appreciated.

推荐答案

罪魁祸首是嵌套<$ c $中的以下两个语句c> for loops:

The culprit is the following two statements within your nested for loops:

j = factor*j-1;
i = factor*i-1;

例如,如果我们设置 factor = 2 ,你做 factor * j - 1 来更新 j 总是让 j 在每个循环迭代中保持不变。具体来说,如果 j = 1 最初,使用 j< - factor * j - 1 ,您将获得 j< - 2 * 1 - 1 = 1 并且无论循环内的迭代次数如何,您总是得到 j = 1 我们在。因此,您只更新输出图像的左上角,此位置将一直覆盖,直到我们到达图像的最后一个像素,并且左上角最后是原始图像的最后一行和最后一列。这可能就是为什么你有一个黑色图像,因为你已经将输出图像初始化为全黑像素,但你只是更新图像中的一个像素。因此,您需要更改 j (当然还有 i )的更新方式。

For example, if we set factor = 2, you doing factor*j - 1 to update j will always make j remain the same at each for loop iteration. Specifically, if j = 1 initially, with j <- factor*j - 1, you will get j <- 2*1 - 1 = 1 and you will always get j = 1 no matter what iteration within the loop we are at. Therefore, you only update the top-left corner of the output image and this location will keep overwriting itself until we hit the last pixel of the image, and the top-left corner is finally the last row and last column of the original image. That's probably why you have a black image as you have initialized an output image to be all black pixels, but you're only updating one pixel in the image. As such, you need to change how j (and of course i) is being updated.

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

I'm also going to change the way you're approaching the problem. Instead, we are going to iterate over the dimensions of the subsampled image, then for each location in the subsampled image, we will pull the right pixel from the original image. Given a row and column location (x,y) in the subsampled image and a subsampling factor factor, the row and column location (j,i) to access from the original image is:

j = factor*(x-1) + 1;
i = factor*(y-1) + 1;

假设 x y 均从1开始。如果替换 x y 从 1,2,... 开始,您可以看到上面的公式选择了依赖于因子。例如,如果 factor = 2 ,则替换 x y 1,2,... 会给:

This is assuming that x and y both start at 1. If you substitute values of x and y starting from 1,2,... you can see that the above formula picks out the right pixels dependent on factor. For example, if factor = 2, substituting values of x and y of 1,2,... would give:

j = 1, 3, 5, ...
i = i, 3, 5, ...

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

As you can see we are skipping every other pixel, which makes sense as this is a factor of 2. I'll leave it as an exercise, but if you try with any other values, you will see that we are correctly skipping over the right pixels to grab the correct ones from the source to copy over to the output image.

所有这些,这是你修改过的代码:

With all of this, here's your modified code:

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

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

With the above code, I ran this through with cameraman.tif which is part of the sample images that MATLAB comes with if you have the image processing toolbox. It looks like this:

因此,如果我想以2倍的方式进行子采样,我们会这样做:

As such, if I want to subsample by a factor of 2, we do:

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

我得到:

这篇关于使用for循环对图像进行子采样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆