您可以使用图像处理工具箱中的im2col 将每个像素邻域转换为单列。像素邻域的选择使得每个块都是在column-basis上选择的,这意味着块是通过首先遍历行来构造的,然后继续到下一列并在那里得到邻域。
你这样打电话给im2col:
B = im2col(A, [M N]);
我假设您需要滑动/重叠邻域,而不是不同的邻域,这是执行任何类型的图像过滤时通常使用的。 A 是您的图像,您希望找到转换为列的 M x N 像素邻域。 B 将是每个邻域是单个列并且水平平铺在一起的输出。但是,您可能需要处理想要沿图像边界抓取像素邻域的情况。在这种情况下,您需要先填充图像。我们将假设M 和N 是奇怪的,以使填充更容易。具体来说,您要确保在图像顶部和底部填充有floor(M/2) 行,以及在图像左侧和右侧填充floor(N/2) 列。因此,我们应该首先使用padarray 填充A。假设将复制边框像素,这意味着填充的行和列将只是从顶部或底部行或左右列抓取的那些,具体取决于我们需要填充的位置。因此:
Apad = padarray(A, floor([M N]/2), 'replicate');
对于下一部分,如果您想选择指定邻域,您可以使用sub2ind 将您的 2D 坐标转换为线性索引,这样您就可以选择正确的列来获得正确的像素块。但是,由于您有一个彩色图像,您需要在每个颜色通道上执行im2col。不幸的是,im2col 仅适用于灰度图像,因此您必须对图像中的每个通道重复此操作。
因此,要为补丁采样做好准备,请执行以下操作:
B = arrayfun(@(x) im2col(Apad(:,:,x), [M N]), 1:size(A,3), 'uni', 0);
B = cat(3, B{:});
以上代码将创建im2col 的3D 版本,其中每个3D 切片将是im2col 为每个颜色通道生成的内容。现在,我们可以使用sub2ind 将您的(x,y) 坐标转换为线性索引,以便我们可以选择我们想要的像素邻域。因此,假设您的位置存储在向量x 和y 中,您将执行以下操作:
%// Generate linear indices
ind = sub2ind([size(A,1) size(A,2)], y, x);
%// Select neighbourhoods
%// Should be shaped as a MN x len(ind) x 3 matrix
neigh = B(:,ind,:);
%// Create cell arrays for each patch
patches = arrayfun(@(x) reshape(B(:,x,:), [M N 3]), 1:numel(ind), 'uni', 0);
patches 将是一个元胞数组,其中每个元素在您指定的(x,y) 的每个位置都包含您所需的补丁。因此,patches{1} 将是位于(x(1), y(1)) 的补丁,patches{2} 将是位于(x(2), y(2)) 的补丁等等。为了您的复制和粘贴的乐趣,我们有:
%// Define image, M and N here
%//...
%//...
Apad = padarray(A, floor([M N]/2), 'replicate');
B = arrayfun(@(x) im2col(Apad(:,:,x), [M N]), 1:size(A,3), 'uni', 0);
B = cat(3, B{:});
ind = sub2ind([size(A,1) size(A,2)], y, x);
neigh = B(:,ind,:);
patches = arrayfun(@(x) reshape(neigh(:,x,:), [M N 3]), 1:numel(ind), 'uni', 0);