【发布时间】:2010-12-10 20:31:48
【问题描述】:
我有一个 256x256 的图像,我想将它分成 4 个 128x128 的块,并将它们作为 A1 到 A4 寻址。现在我想分别调用它们并对它们进行一些操作。我知道这可以使用blkproc 函数来完成——但具体如何?
我会这样打电话给blkproc吗?
B=blkproc(I,[4 4],?)
我应该用什么代替“?”,以及如何处理创建的 4 个块?
【问题讨论】:
我有一个 256x256 的图像,我想将它分成 4 个 128x128 的块,并将它们作为 A1 到 A4 寻址。现在我想分别调用它们并对它们进行一些操作。我知道这可以使用blkproc 函数来完成——但具体如何?
我会这样打电话给blkproc吗?
B=blkproc(I,[4 4],?)
我应该用什么代替“?”,以及如何处理创建的 4 个块?
【问题讨论】:
由于blockproc(以及已弃用的blkproc)都是Image Processing Toolbox 中的两个函数,我想我应该添加一个不需要额外工具箱的基本MATLAB 解决方案...
如果要将矩阵划分为子矩阵,一种方法是使用mat2cell 将矩阵分解并将每个子矩阵存储在元胞数组的一个元胞中。对于您的情况,语法如下所示:
C = mat2cell(I, [128 128], [128 128]);
C 现在是一个 2×2 元胞数组,每个元胞存储一个 128×128 的 I 子矩阵。如果要对每个单元格执行操作,则可以使用函数cellfun。例如,如果您想取每个子矩阵中的值的平均值,您可以执行以下操作:
meanValues = cellfun(@(x) mean(x(:)), C);
第一个参数是 function handle 到 anonymous function,它首先将每个子矩阵重塑为列向量,然后取平均值。输出是每个子矩阵的平均值的 2×2 矩阵。如果您传递给cellfun 的函数为每个单元格创建了不同大小或类型的输出,那么cellfun 将它们连接起来会出现问题并抛出错误:
??? Error using ==> cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
如果您在对cellfun 的调用末尾添加..., 'UniformOutput', false);,则上述情况下的输出将改为包含执行结果的2×2 元胞数组对每个子矩阵的操作。
【讨论】:
blockproc 是 blkproc 的新名称(已弃用)。它可用于将功能应用于图像中的每个块。例如,如果您想将矩阵 I 分成 8x8 块并计算每个块的平均值,您可以这样做:
B=blockproc(I, [8 8], @(x) mean(x.data(:)));
B 是一个包含块均值的矩阵。
这里需要注意两点:
说明符[8 8] 指定块的大小,而不是块的数量。
在传递给blockproc 的函数之外,您无法访问块本身。如果您需要积木本身,则必须按照 Adrien 的建议进行操作:
A1=I(1:128, 1:128);
A2=I(129:256, 1:128);
A3=I(1:128, 129:256);
A4=I(129:256, 129:256);
当然,在真正的程序中,您可能应该使用循环来执行此操作。
【讨论】:
B = blkproc(I, [8 8], @(x) mean(x(:)));
如果myImage 是您的 256x256 图像,不是吗
image_top_left = myImage(1:128,1:128);
image_top_right = myImage(1:128,129:256);
image_bottom_left = myImage(129:256,1:128);
image_bottom_right = myImage(129:256,129:256);
?
【讨论】:
让您的程序适用于所有尺寸的图像,而不仅仅是 256*256,这对您来说会更好。
[row, col]=size(your_image);
mr = round(row/2); % median of rows
mc = round(col/2); % median of columns
% Now divide your image and call each of them separately and do what ever you want
top_left = your_image(1:mr , 1:mc);
top_right = your_image(1:mr , (mc+1):col);
bot_left = your_image((mr+1):row , 1:mc);
bot_right = your_image((mr+1):row , (mc+1):col);
% final stage is to combining these parts again to return to its original shape
Back_to_original = [top_left,top_right ; bot_left,bot_right]; `
希望这对您有用。
【讨论】:
如果您想将图像分割成 gs 大小的正方形(例如 2,3,4,5,6,7,8,9,10,...),您可以使用以下代码。此函数从输入图像中按 gs 块提取 gs 并将它们存储到“patch”变量中。请注意,如果输入图像的宽度或高度不是 gs 的倍数,则块提取中不会覆盖等于除法残差的偏移量。
function [ patchim , npatchim ] = divideimage (im , gs)
imheight=size(im,1);
imwidth=size(im,2);
maxgsrow = floor( imheight / gs);
maxgscol = floor( imwidth / gs );
npatch = 1;
for i = 1 : maxgsrow
for j = 1 : maxgscol
rmin = ( i - 1 ) * gs + 1;
rmax = i * gs;
cmin = ( j - 1) * gs + 1;
cmax = j * gs;
%%%%%% do processes
patch ( : , : , : , npatch) = im( rmin : rmax , cmin : cmax , : );
npatch = npatch + 1;
endfor
endfor
npatchim = npatch - 1;
patchim = patch;
end
【讨论】: