高效实现`im2col`和`col2im`

时间:2014-08-22 14:23:37

标签: matlab image-processing vectorization

在处理图像时,MATLAB的im2colcol2im对于MATLAB中的矢量化非常重要。
但他们需要MATLAB的图像处理工具箱。

我的问题是,是否有一种有效的(Vectorzied)方法来实现使用MATLAB的功能(没有工具箱)?
我需要slidingdistinct模式。

我不需要任何填充。

谢谢。

2 个答案:

答案 0 :(得分:17)

我只能希望Mathworks的人不要起诉你或我或Stackoverflow,试图创建他们的IP工具箱功能的矢量化实现,因为他们已经为这个工具箱付出了代价。但无论如何,忘记这些问题,这里是实现。

使用im2col选项替换'sliding'

在我坐下来写solution to another problem on Stackoverflow之前,我无法对此进行矢量化。所以,我强烈建议你也要考虑一下。

function out = im2col_sliding(A,blocksize)

nrows = blocksize(1);
ncols = blocksize(2);

%// Get sizes for later usages
[m,n] = size(A);

%// Start indices for each block
start_ind = reshape(bsxfun(@plus,[1:m-nrows+1]',[0:n-ncols]*m),[],1); %//'

%// Row indices
lin_row = permute(bsxfun(@plus,start_ind,[0:nrows-1])',[1 3 2]);  %//'

%// Get linear indices based on row and col indices and get desired output
out = A(reshape(bsxfun(@plus,lin_row,[0:ncols-1]*m),nrows*ncols,[]));

return;

使用im2col选项替换'distinct'

function out = im2col_distinct(A,blocksize)

nrows = blocksize(1);
ncols = blocksize(2);
nele = nrows*ncols;

row_ext = mod(size(A,1),nrows);
col_ext = mod(size(A,2),ncols);

padrowlen = (row_ext~=0)*(nrows - row_ext);
padcollen = (col_ext~=0)*(ncols - col_ext);

A1 = zeros(size(A,1)+padrowlen,size(A,2)+padcollen);
A1(1:size(A,1),1:size(A,2)) = A;

t1 = reshape(A1,nrows,size(A1,1)/nrows,[]);
t2 = reshape(permute(t1,[1 3 2]),size(t1,1)*size(t1,3),[]);
t3 =  permute(reshape(t2,nele,size(t2,1)/nele,[]),[1 3 2]);
out = reshape(t3,nele,[]);

return;

一些快速测试表明,对于小到适当大小的输入数据,这两个实现特别sliding,对于所有数据,distinct这两个实现在运行时性能方面比内置MATLAB函数实现要好得多

如何使用

With in-built MATLAB function - 
B = im2col(A,[nrows ncols],'sliding')

With our custom function - 
B = im2col_sliding(A,[nrows ncols])

%// ------------------------------------

With in-built MATLAB function - 
B = im2col(A,[nrows ncols],'distinct')

With our custom function - 
B = im2col_distinct(A,[nrows ncols])

答案 1 :(得分:3)

你可以在寻找GNU Octave image包时作弊。有im2col和col2im作为脚本语言实现:

据我所知,它在不同的评论风格(#而不是%)和不同的字符串样式(“而不是”)中差异最大。如果你改变它并删除底部的断言测试,它可能是可运行的如果没有,请使用调试器完成它。

此外,请注意许可证(GPLv3)。它是免费的,但你的更改也必须是免费的!