首先我要说的是im2col http://www.mathworks.com/help/images/ref/im2col.html仅适用于二维矩阵。事实上,它有时会起作用(我的意思是返回结果而不抛出错误)只是一个令人高兴的巧合。
现在我看了一眼edit im2col.m
,并且无需过多研究代码,每个的第一行distinct
and sliding
方法应该让您直观地了解正在发生的事情:
...
if strcmp(kind, 'distinct')
[m,n] = size(a);
...
elseif strcmp(kind,'sliding')
[ma,na] = size(a);
...
end
...
首先回想一下[s1,s2] = size(arr)
where arr
是一个 3d 数组,会将第二维和第三维的大小折叠为一个大小。这是相关的doc size http://www.mathworks.com/help/matlab/ref/size.html:
[d1,d2,d3,...,dn] = size(X)
返回数组维度的大小X
,提供输出参数的数量n
equals ndims(X)
. If n < ndims(X)
, di
等于第 i 维的大小X
for 0<i<n
, but dn
等于其余尺寸大小的乘积X
,即尺寸n
通过ndims(X)
.
所以基本上对于一个大小的数组M-by-N-by-P
,该函数反而认为它是一个大小矩阵M-by-(N*P)
。现在 MATLAB 有一些奇特的索引规则,可以让您执行以下操作:
>> x = reshape(1:4*3*2,4,3,2)
x(:,:,1) =
1 5 9
2 6 10
3 7 11
4 8 12
x(:,:,2) =
13 17 21
14 18 22
15 19 23
16 20 24
>> x(:,:)
ans =
1 5 9 13 17 21
2 6 10 14 18 22
3 7 11 15 19 23
4 8 12 16 20 24
我认为这就是这里最终发生的事情。这是一个确认行为的示例im2col
在 RGB 图像上:
% normal case (grayscale image)
>> M = magic(5);
>> B1 = im2col(M, [3 3], 'sliding');
% (RGB image)
>> MM = cat(3, M, M+50, M+100);
>> B2 = im2col(MM, [3 3], 'sliding');
>> B3 = im2col(reshape(MM, [5 5*3]), [3 3], 'sliding');
>> assert(isequal(B2,B3))
注意B2
and B3
是相等的,所以基本上想想结果im2col
在数组上arr = cat(3,R,G,B)
与...相同arr = cat(2,R,G,B)
(水平连接)。
有趣的是,使用“不同”块方法你不会那么幸运:
>> B1 = im2col(M, [3 3], 'distinct') % works
% ..snip..
>> B2 = im2col(MM, [3 3], 'distinct') % errors
Subscripted assignment dimension mismatch.
Error in im2col (line 59)
aa(1:m,1:n) = a;
现在我们了解了发生了什么,让我们考虑如何正确地对 3D 数组执行此操作。
我认为要实施im2col
对于彩色图像,我只需在每个颜色通道上单独运行它(每个通道都是一个二维矩阵),然后沿第三维连接结果。所以像这样的包装函数:
function B = im2col_rgb(img, sz, varargin)
B = cell(1,size(img,3));
for i=1:size(img,3)
B{i} = im2col(img(:,:,i), sz, varargin{:});
end
B = cat(3, B{:});
end