【问题标题】:Subsample an image using a for loop使用 for 循环对图像进行二次采样
【发布时间】:2015-05-03 07:50:31
【问题描述】:

我有一个关于对矩阵/图像进行二次采样的快速问题。我正在尝试仅使用for 和/或while 循环来执行此操作。基本上这个问题是重申:

function output = subsample(img,2)

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

但是,现在我正在尝试重写函数以执行完全相同的过程,但使用 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

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

【问题讨论】:

    标签: image matlab for-loop image-processing matrix


    【解决方案1】:

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

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

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

    我还将改变您处理问题的方式。相反,我们将迭代 subsampled 图像的尺寸,然后对于 subsampled 图像中的每个位置,我们将从原始图像中提取正确的像素。给定子采样图像中的行和列位置(x,y)和子采样因子factor,从原始图像访问的行和列位置(j,i)是:

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

    这是假设 xy 都从 1 开始。如果您替换从 1,2,... 开始的 xy 的值,您可以看到上述公式根据factor。例如,如果factor = 2,将xy 的值替换为1,2,... 将得到:

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

    如您所见,我们正在跳过所有其他像素,这是有道理的,因为这是 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
    

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

    因此,如果我想以 2 倍子采样,我们这样做:

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

    我明白了:

    【讨论】:

    • 非常感谢,您的解释是一流的!
    • 没问题 :) 这是我的荣幸。祝你好运!
    • @RohanNair - 我已经添加了一些关于如何计算正确位置以获取像素以放置在二次采样结果中的更多解释。祝你好运!
    • 再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    相关资源
    最近更新 更多