How can i divide an image into Overlapping Blocks without using for loop?

Hi all, Lets suppose i have an image of size 64x48, i want to divide it into blocks of size 4x4 (or any size) with an overlap of 1 (or any size less than 4 incase of 4). I tried to read blockproc, but one they need some function to be applied on it which i don't have currently, and second they don't give option of overlapping.
How can i do that?
THanks in advance.

Answers (2)

myImage = rand(64,48);
x = 1:3:64;
y = 1:3:48;
[X,Y] = meshgrid(x,y);
subImages = arrayfun( @(x,y) myImage(x:min(end,x+3),y:min(end,y+3)), X, Y, 'UniformOutput', false )';
should give you a cell array containing 4*4 overlapping sub-images upto the final one which may be smaller due to the image size.
I tested that in a bit of a rush though so there may be some elements not quite right. Hopefully it gives you an idea though if it isn't a complete answer.

6 Comments

Thank you for your reply.
I tried it for 6x6, but it doesn't give the same, it gives me 4 cells, one containing a 4x4 (correct first 4x4 of image), in next it give me 4x3, and in third it gives me 3x4, and in last (last) 3x3.
I want that overlapping constant size of extracted block that is 4x4 for all.
You mean 6x6 still with overlap of 1?
That still works for me with that method. Obviously you have to change those hard-coded 3's to 5s though.
More generically:
myImage = rand(64,48);
xBlockSize = 6;
yBlockSize = 6;
xOverlap = 1;
yOverlap = 1;
x = 1:(xBlockSize - xOverlap):64;
y = 1:(yBlockSize - yOverlap):48;
[X,Y] = meshgrid(x,y);
subImages = arrayfun( @(x,y) myImage( x:min( end, x + xBlockSize - 1), y:min( end, y + yBlockSize - 1) ), X, Y, 'UniformOutput', false )';
Obviously you could be even more generic by replacing the hard-coded 64 and 48, but that part is trivial.
How can I divide an image into overlapping sub-blocks by sliding window?
You can use blockproc() (demos attached) or if the overlap is all but one pixel, you can use nlfilter().
You'd have to write your own code for that since blockproc only works with 2-D images.

Sign in to comment.

See the FAQ: http://matlab.wikia.com/wiki/FAQ#How_do_I_split_an_image_into_non-overlapping_blocks.3F. Neither of the two methods listed uses blockproc(). I'm pretty sure you can figure out how to adapt it from non-overlapping to overlapping by 1 pixel.

8 Comments

No this doesn't help, as i know met2cell, but it doesn't provide Overlapping, second i don't want to use Loops. I want technique that may work in vectorize form. With out using for loops… Sorry for being late in replying as it was weekend… and thanks for your reply
Why do you hate loops? You could do a million of them in less than a millisecond. If you don't like the indexing way, then you can use blockproc(). With the proper parameters, you can have the blocks overlap each other. Or you could use nlfilter() which slides over a pixel at a time.
Do you think 5 loops at a time, or 4 loops at a time will take milli seconds for hundred rather thousands of images. I have to wait for days for each cycle. I really need to avoid loops, and to optimize. Let me check this nfilter() as i tried with blocproc() but was not successful for overlap case. If you have any sample can you share. However i am going to try for filters as i didn't tried that.
I just did 100 million, yes one hundred million , for loop iterations and it took 0.2 seconds , so it's not the for loop that's taking up all the time. It will be the disk I/O, memory access (if indexing in an inefficient order), and image processing time rather than anything having to do with the for loop. Attached is a demo for nlfilter().
I agree, but this is the problem, i mean indexing, Forexample my function does something similar like convolution or correlation of two images (actually only dot product of suppose 4x4 area and than summing all ). Which results in another output image of reduced size. I have about 16000 images. and it takes about 2 hour for one complete phase. I am using simple for loops, But i want some fast function which can do that for me. Or any function which can give me blocks of the image and than i may do dot product in vector form. but till now unsuccessful
Convolution, done by conv2(), and correlation, done by xcorr2(), can do processing by overlapping block (windows) thought the overlap is by N-1 pixel where N is the window size. In other words, they slide over by one pixel at a time. If you want to do something custom, then use nlfilter() which is built for that.
pardon me for being childish. But i can't understand how can i use nfilter in my case. E.g
mat1 = rand(20,16);
mat2= rand(20,16);
Receptive_fieldsize = [4,3];
overlap = 1;
fun = sum(sum(RF_mat1 .* RF_mat2)); % RF_mat1 is taking block of 4x3 from mat1 and same indices from mat2 which becomes RF_mat2.
How can i use this so that i may get output image of size 6x5.
I'm attaching a demo for nlfilter(). See the function called LocalOtsu? Just rename it to whatever you want that describes the operations you want. Then put whatever custom operations you want inside it.
By the way, what you described is just a simple cross correlation and can be done with xcorr2().

Sign in to comment.

Asked:

on 18 Sep 2014

Edited:

on 22 Dec 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!