I am using a simple for
loop to crop a large amount of images and then storing them in a cell array. I keep getting the message:
The variable
croppedSag
appears to change size on every loop iteration. Consider preallocating for speed.
I have seen this several times before while coding in MATLAB. I have always ignored it and am curious how much preallocating will increase the runtime if I have, say, 10,000 images or a larger number?
Also, I have read about preallocating in the documentation and it says to use zeros()
for that purpose. How would I use that for the code below?
croppedSag = {};
for i = 1:sagNum
croppedSag{end+1} = imcrop(SagArray{i},rect);
end
I didn't quite follow the examples in the documentation.
Preallocating a Nondouble MatrixWhen you preallocate a block of memory to hold a matrix of some type other than double , avoid using the method. A = int8(zeros(100)); This statement preallocates a 100-by-100 matrix of int8 , first by creating a full matrix of double values, and then by converting each element to int8 ...
To pre-allocate an array (or matrix) of numbers, you can use the "zeros" function. To pre-allocate an array (or matrix) of strings, you can use the "cells" function. Here is an example of a script showing the speed difference. Make sure you "clear" the array variable if you try the code more than once.
I mean, suppose the matrix you want is M, then create M=[]; and a vector X=zeros(xsize,2), where xsize is a relatively small value compared with m (the number of rows of M). Then, fill X and when it is filled, just concatenate the matrix with M by doing M=[M; X]; and start filling X again from the first row on.
To preallocate a cell-array we can use the cell function (explicit preallocation), or the maximal cell index (implicit preallocation).
Pre-allocating an array is always a good idea in Matlab. The alternative is to have an array which grows during each iteration through a loop. Each time an element is added to the end of the array, Matlab must produce a totally new array, copy the contents of the old array into the new one, and then, finally, add the new element at the end. Pre-allocating eliminates the need to allocate a new array and spend time copying the existing contents of the array into the new memory.
However, in your case, you might not see as much benefit as you might expect. When copying the cell array to a new, enlarged cell array, Matlab doesn't actually have to copy the contents of the cell array (the image data), but only pointers to that data.
Nonetheless, there is no reason not to pre-allocate (unless you actually don't know the final size in advance). Here's a pre-allocated version of your loop:
croppedSag = cell(1, sagNum);
for ii = 1:sagNum
croppedSag{ii} = imcrop(SagArray{ii}, rect);
end
I also changed the index variable "i" to "ii" so that it doesn't over-write the imaginary unit.
You can also re-write this loop in one line using the cellfun function:
croppedSag = cellfun(@(im) imcrop(im, rect), SagArray);
Here's a blog entry that might be informative:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With