如何在不制作副本的情况下循环播放matlab图像?

时间:2014-09-08 04:39:03

标签: matlab

我试图在MATLAB中循环一个图像,但我的代码运行缓慢。我对MATLAB很了解,但我怀疑是因为它正在复制我随机选择的图像。我的代码是:

function patches = sampleIMAGES()
load IMAGES;    % load images from disk 
patchsize = 8;  % we'll use 8x8 patches 
numpatches = 10000;
patches = zeros(patchsize*patchsize, numpatches); 

size_img = size(IMAGES);
num_rows_img = size_img(1);
num_cols_img = size_img(2);
num_images = size_img(3);
for i=1:numpatches,
    %get random image
    rand_img_number = randi(num_images);
    rand_img = IMAGES(:, :, rand_img_number);
    %get random patch patchsizexpatchsize
    rand_row = randi(num_rows_img - patchsize);
    rand_col = randi(num_cols_img - patchsize);
    rand_patch = rand_img(rand_row:rand_row+patchsize-1, rand_col:rand_col+patchsize-1);
    patches(:, i) = rand_patch(:)';
end
end

如果MATLAB不允许将两次索引到矩阵/数组中,如何在不进行复制的情况下循环使用它?

2 个答案:

答案 0 :(得分:3)

方法#1 - im2col基于

numpatches = 10000; %//Number of patches
blksz = 8; %// Blocksize

[m,n,r] = size(IMAGES); %// Get sizes

%// Store blocks from IMAGES as columns, so that they could be processed in
%// a vectorized fashion later on
blks_col(blksz*blksz,(m-blksz+1)*(n-blksz+1),r)=0; %// Pre-allocate
for k1=1:r
    blks_col(:,:,k1) = im2col(IMAGES(:,:,k1),[blksz blksz],'sliding');
end
blks_col = reshape(blks_col,size(blks_col,1),[]);

%// Get rand row, column and dimension-3 indices to be used for indexing
%// into blks_col in one go
rand_row = randi(size(IMAGES,1)-blksz+1,numpatches,1);
rand_col = randi(size(IMAGES,2)-blksz+1,numpatches,1);
rand_dim3 = randi(size(IMAGES,3),numpatches,1);

%// Select the specific column from blks_col that represents the 
%// [blksz x blksz] used to make a single patch in each iteration from 
%// original code 
num_cols_im2col = (m-blksz+1)*(n-blksz+1);
col_ind = (rand_dim3-1)*num_cols_im2col + (rand_col-1)*(m-blksz+1) + rand_row;
patches = blks_col(:,col_ind);

示例

作为一个例子,我假设IMAGES是通过读取图像处理工具箱图像库中提供的一个图像获得的3D数据,并将补丁数量增加到100000,即 -

IMAGES = imread('peppers.png');
numpatches = 100000;

original code - 22.376446 seconds的运行时。

im2col based code - 2.237993 seconds

的运行时

然后,我将number of patches加倍到200000,其中original code的运行时间实际上翻了一倍,基于im2col的方法的运行时间保持在~2.3秒左右。< / p>

因此,当您使用大量补丁时,这种基于im2col的方法是有意义的,而不是处理大量图像时(放在IMAGES的第三维中)。 / p>


方法#2 - 基于索引

作为一种纯粹的基于索引的方法,预计这将是内存效率和性能良好的。

numpatches = 10000; %//Number of patches
blksz = 8; %// Blocksize
[m,n,r] = size(IMAGES); %// Get sizes

%// Get rand row, column and dimension-3 indices to be used for indexing
rand_row = randi(size(IMAGES,1)-blksz+1,numpatches,1);
rand_col = randi(size(IMAGES,2)-blksz+1,numpatches,1);
rand_dim3 = randi(size(IMAGES,3),numpatches,1);

%// Starting indices for each patch
start_ind = (rand_dim3-1)*m*n + (rand_col-1)*m + rand_row;

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

%// Get linear indices based on row and col indices
lin_rowcol = reshape(bsxfun(@plus,lin_row,[0:blksz-1]*m),blksz*blksz,[]);

%// Finally get the patches
patches = IMAGES(lin_rowcol);

答案 1 :(得分:2)

不再复制图像,而是复制这两行:

rand_img = IMAGES(:, :, rand_img_number);
rand_patch = rand_img(rand_row:rand_row+patchsize-1, rand_col:rand_col+patchsize-1);

将两者合并为一行:

rand_patch = IMAGES(rand_row:rand_row+patchsize-1, rand_col:rand_col+patchsize-1, rand_img_number);

提高性能的另一种方法:在onece生成100个随机数比生成1个100倍更快。在循环外生成所需的所有数字:

rand_img_number = randi(num_images,numpatches,1);

然后在循环中使用rand_img_number(i)而不是rand_img_number。对另外两个随机数做同样的事。