我试图在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不允许将两次索引到矩阵/数组中,如何在不进行复制的情况下循环使用它?
答案 0 :(得分:3)
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>
作为一种纯粹的基于索引的方法,预计这将是内存效率和性能良好的。
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
。对另外两个随机数做同样的事。