如何在不制作副本的情况下遍历Matlab图像? [英] How to loop over a matlab image without making copies?

查看:136
本文介绍了如何在不制作副本的情况下遍历Matlab图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在MATLAB中循环显示图像,但是我的代码运行缓慢.我对MATLAB非常了解,但我怀疑这是因为它正在复制我随机选择的图像.我的代码是:

I was trying to loop over an image in MATLAB but my code is running to slow. I am fairly knew to MATLAB but I suspect that it's because it's making a copy of my randomly selected image. My code is:

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不允许两次索引到矩阵/数组中,怎么可能不进行复制就遍历呢?

How is it possible to loop over this without making a copy if MATLAB does not allow to index twice into a matrix/array?

推荐答案

方法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是通过读取Image Processing Toolbox的图像库中提供的图像之一而获得的3D数据,并将色块的数量增加到100000,即-

As an example I assumed IMAGES as the 3D data obtained from reading one of the images provided in the image gallery of Image Processing Toolbox and increased the number of patches to 100000, i.e. -

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秒左右.

Then, I doubled the number of patches to 200000, for which the runtime with original code literally doubled and im2col based approach's runtime stayed around that ~2.3 sec mark.

因此,这种基于im2col的方法在处理大量修补程序时是有意义的,而不是处理大量图像(置于IMAGES的三维空间中)的情况.

Thus, this im2col based approach would make sense when you are working with lots of patches as opposed to when working with lots of images (that are put in the third dimension of IMAGES).

作为一种纯粹基于索引的方法,预计这将提高内存效率,并具有良好的性能.

Being a purely indexing based approach, this is expected to be memory-efficient and good with performance too.

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);

这篇关于如何在不制作副本的情况下遍历Matlab图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆