Reputation: 1429
I have a large set of images from which I wish to extract image patches from. The patches are uniform in size and extracted from each image at regular grid points. I can do this with the following code:
for n = 1:nImages
% Read image
imageFile = imageFiles{n};
I = imread(imageFile);
% Grid point locations
height = size(I, 1);
width = size(I, 2);
border = floor(patchSize/2);
centres = gridPoints(height, width, nPointsX, nPointsY, border);
% Extract and process patches
for p = 1:nPatches
% Patch location
x = centres(p, 1);
y = centres(p, 2);
% Top-left point of patch
x = x - floor(patchSize/2) + 1;
y = y - floor(patchSize/2) + 1;
% Extract patch -- BOTTLENECK!
patch = imcrop(I, [x y patchSize-1 patchSize-1]);
% Process patch
% ...
end
end
This code is highly inefficient, especially given both the large number of images and the large number of grid points (I am also doing this at different scales for each image). I have run Matlab's profiler and found that imcrop is the cause of this inefficiency. Running on only 50 images (but with 100 x 100 grid points at 3 scales) took 756 seconds.
Is there an alternative way to extract image patches in Matlab without incurring such a huge processing overhead?
Upvotes: 4
Views: 6081
Reputation: 1504
you may want to ensure that the patch will never go out of the image boundary:
patch = I(max(1,y):min(y+patchSize-1,size(I,1)), max(1,x):min(x+patchSize-1,size(I,2)), :);
Upvotes: 1
Reputation: 30589
Subscript indexing is a natural operation in MATLAB.
patch = I(y:y+patchSize-1, x:x+patchSize-1);
Given the counterintuitive use of imcrop
in the question with rect = [x y patchSize-1 patchSize-1]
giving a square dimension of patchSize-1
x patchSize-1
the output size of the above command should be confirmed as correct for your purposes.
EDIT: For RGB (or any planar multi-channel format):
patch = I(y:y+patchSize-1, x:x+patchSize-1, :);
Upvotes: 5