How to divide a bmp image into blocks?

I want to divide a bmp image to a 8*8 blocks. Is there any way out? 'resize' only resizes the image but does not divide the image into blocks. Also, when I read the image( using imread), it should give me a 8*8 matrix.

 Accepted Answer

Guillaume
Guillaume on 18 Jul 2017
Edited: Guillaume on 18 Jul 2017
Assuming your image size is a multiple of 8:
img = imread('C:\somewhere\someimage.bmp');
numblockheight = size(img, 1) / 8;
numblockwidth = size(img, 2) / 8;
assert(all(mod([numblockwidth, numblockheight], 1) == 0), 'Image size is not a multiple of 8')
imageblocks = mat2cell(img, ones(1, numblockheight) * 8, ones(1, numblockwidth) * 8, size(img, 3))
And to save all these:
destinationfolder = 'C:\somewhere';
for col = 1:size(imageblocks, 2)
for row = 1:size(imageblocks, 1)
imwrite(imageblocks{row, col}, fullfile(destinationfolder, sprintf('block%03d_%03d.bmp', row, col)));
end
end

10 Comments

Is imageblocks our final image? If yes, I am not able to view it. Can you please help me with this?
I'm not sure what you call the final image. You asked for an image divided into 8x8 blocks. That makes for a lot of images.
imageblocks is a cell array containing all these 8x8 blocks. If you want to see the 3rd block from the top and 2nd from the left:
imshow(imageblocks{3, 2}) %it's going to be tiny!
I understood how to view a tiny cell. but can we see an image like the one attached? Is it possible to view such an image. By final image, I mean exactly what shown in the attached image. This image shows the orignal image divided into blocks.
What your attachment shows is an image with an 8x8 square drawn on it. If all you want to do is display a grid of 8x8 square on your image:
himage = imshow(yourimage);
haxes = himage.Parent;
set(haxes, {'Visible', 'XGrid', 'YGrid', 'XTick', 'YTick', 'GridColor', 'GridAlpha'}, {'on', 'on', 'on', 0:8:size(yourimage, 2), 0:8:size(yourimage, 1), 'k', 1})
haxes.XAxis.Visible = 'off';
haxes.YAxis.Visible = 'off';
Size of himage is coming out to be 1*1. can this be possible? And for image compression do we need to find inverse DCT after this step?
img = imread('C:\somewhere\someimage.bmp');
numblockheight = size(img, 1) / 8;
numblockwidth = size(img, 2) / 8;
assert(all(mod([numblockwidth, numblockheight], 1) == 0), 'Image size is not a multiple of 8')
imageblocks = mat2cell(img, ones(1, numblockheight) * 8, ones(1, numblockwidth) * 8, size(img, 3))
This code was earlier given by you. But what if our image is not a multiple of 8? What changes do we need to make?
img = imread('C:\somewhere\someimage.bmp');
blockdistheight = [ones(1, floor(size(img, 1) / 8)) * 8, mod(size(img, 1), 8)];
blockdistwidth = [ones(1, floor(size(img, 2) / 8)) * 8, mod(size(img, 2), 8)];
if blockdistheight(end) == 0
blockdistheight(end) = [];
end
if blockdistwidth(end) == 0
blockdistwidth(end) = [];
end
imageblocks = mat2cell(img, blockdistheight, blockdistwidth, size(img, 3))
See the documentation of mat2cell
If you use blockproc(), like in my attached demos, it does not matter if there are an integer number of blocks across the image.
@Guillaume Your code shows error as shown in the image attached. How can it be resolved?
Please copy and paste errors instead of posting screenshots.
There was a missing bracket in my code. You (or matlab suggestion) added it in the wrong spot. I've fixed it above
Spending some time trying to understand what the code is doing would have allowed you to fix it yourself.

Sign in to comment.

Asked:

on 18 Jul 2017

Edited:

on 21 Jul 2017

Community Treasure Hunt

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

Start Hunting!