how to divide an RGB image using blockproc function

i want to resize an RGB image from 512X512 to 256X256 + i want to divide it into 4 equal blocks and take each block and change it from RGB to HSV, all of this using blockproc function or if you can tell me another effective way, here is my code in matlab:
f= imread ('lena_rgb.tiff');
h= rgb2hsv(f);
fun = @(block_struct) imresize(block_struct.data,h);
I2 = blockproc(f,[2 2],fun);
figure(1),imshow(f);
figure(2),imshow(I2);
i had all these errors:
??? Function BLOCKPROC encountered an error while evaluating the user supplied function handle,
FUN.
The cause of the error was:
Error using ==> imresize>scaleOrSize at 393
Invalid scale or size input argument.
Error in ==> imresize>parsePreMethodArgs at 364
[scale, output_size] = scaleOrSize(next, next_arg);
Error in ==> imresize>parseInputs at 257
[params.A, params.map, params.scale, params.output_size] = ...
Error in ==> imresize at 141
params = parseInputs(varargin{:});
Error in ==> @(block_struct)imresize(block_struct.data,h)
Error in ==> blockprocFunDispatcher at 14
output_block = fun(block_struct);
Error in ==> blockprocInMemory at 71
[ul_output fun_nargout] = blockprocFunDispatcher(fun,block_struct,...
Error in ==> blockproc at 248
result_image = blockprocInMemory(a,block_size,fun,border_size,...
Error in ==> ff4 at 12
I2 = blockproc(f,[2 2],fun);

1 Comment

ok i want to resize the whole RGB image and divide it into 4 blocks using block proc then convert each block to HSV

Sign in to comment.

 Accepted Answer

Why not just do something simple like
rgbSmall = imresize(rgbBig, 0.5);
hsv = rgb2hsv(rgbSmall);
As far as the 4 equal blocks - I have no idea what you're talking about. The whole image gets converted to hsv - every single pixel. So since every single pixel gets converted into hsv, of course each block (quadrant) will also get converted. There is nothing extra that you need to do.

9 Comments

Resizing a large image to smaller is not generally the same as breaking the image up in to four blocks each of which is resized individually. Yes, it comes out the same for simple resizing methods such as "take every second pixel", but if you think in terms of something like fft, the information from the quarters influence the other quarters if you resize the entire image at once, but clearly cannot if you resize quarter-by-quarter.
I'm not really sure what she meant about the "4 equal blocks" It appears that she wanted to do that *after* the resizing when she said "+ i want to divide it ...." not as part of the resizing procedure itself. Further explanation by yasmine might get answers closer to what was asked (or wanted), or suggestions of better approaches.
it is not that simple because i need to divide the resized image into 4 blocks then convert each block to HSV
any idea ???
i used the mat2cell but still have problems with it
Thank you
What is a "block"? Is it an array of, say 256x256 pixels, or are your blocks something else, say the 4 means of the 128x128 quadrants of the resized 256x256 image? Come on, you can do better at explaining the ambiguities than that. Because otherwise, like I said, converting the image into HSV has nothing to do with blocks.
ok
if a resized the image to 256X256X3 so the 4 blocks are of size: 128X128X3
Thank you
then convert these blocks(arrays) individually to hsv color space
Use the code above then do
hsvBlock1 = hsv(1:128, 1:128, :);
hsvBlock2 = hsv(1:128, 129:256, :);
hsvBlock3 = hsv(129:256, 1:128, :);
hsvBlock4 = hsv(129:256, 129:256, :);
this worked well thank you
ok now i want to quantize these HSV values before I build my histogram to reduce memory consumption and processing time. I would like to quantize them to 8(H) x 3(S) x 3(V) bins. Can someone please help me with this? Thanks a lot
Find the max value in each array, then divide the pixel value by the max, multiply by the number of levels, and take the ceil. See demo below:
% Generate sample data.
S = magic(6);
% Specify the number of quantization levels.
numberOfLevels = 3;
% Find the max.
maxValue = max(S(:));
% Put all pixels into one of the "numberOfLevels" levels.
for row = 1:size(S, 1)
for col = 1 : size(S, 2)
quantizedValue(row, col) = ceil(numberOfLevels * S(row, col)/maxValue);
end
end
% Display it
quantizedValue

Sign in to comment.

More Answers (4)

The second argument to imresize() should be the scale factor that you want to use, such as 0.5
would you help me to use blockproc() as i tried everything else and didn't work for me
@ Image Analyst: i tried your method but i need the code to be parametric, i don't want to use constant numbers.
Thank you
yasmine: I'm still not sure what you want to do. Sure, I can give you a blockproc demo, if that's what you want. I really don't see why it would be necessary in order to (1) convert your image to hsv, (2) quantize your image into a discrete number of levels, or (3) quantize your histograms into a certain number of bins. I don't even know why you said you want to do those things. You haven't given us the context or "big picture" or what you're trying to do at all, so I can only guess if what you're asking to do is even necessary (my guess is that they're not). Moreover, why pick so few bins: 8(H) x 3(S) x 3(V) bins? I'd make each dimension at least 10 times that big. Why are you higtogramming them anyway? Is it to visualize the histogram so you can pick a threshold? Finally you can replace any constants by variables where you assign the variable to whatever constant you want like instead of hsvBlock1 = hsv(1:128, 1:128, :); you would have col1=1; col2 = 128; row1=1; row2=128; hsvBlock1 = hsv(row1:row2, col1:col2, :); hsvBlock1 = hsv(1:128, 1:128, :);

7 Comments

ok i need to make a content based image retrieval model. i am now trying to make an existent model which you can find it in this paper: http://www.ijcaonline.org/volume15/number7/pxc3872619.pdf
and after that i will make my model and compare between them.
my problem is that i need to divide the jpg images ( with different dimensions) to 2by3 or 3by2 blocks in a parametric way (not constant values)then convert each block into HSV, quantize the HSV then bring the histogram.
i hope my words are clear enough so that you can help me
Thank you alot
blockproc is restricted to dividing in consistent ways.
If the orientation of the blocks can be calculated without reference to the image contents, then you could possibly do the splitting using mat2cell, but that will depend upon how complex the splitting is.
I looked over the paper briefly, but I did not find anything in there that called for blocks of different sizes. The closest I found was that the Experimental Setup allowed for images of two different sizes, X by Y and Y by X, but the next clause requires that the Y by X be resized to X by Y so the images seen by the work code would always be X by Y and would always be divided into 2 by 3 blocks.
What section of the paper are you looking at that allows for 3 x 2 blocks?
My answer still seems applicable. Just figure out what row1, row2, col1, and col2 are for each image, then get 6 subimages. For each subimage, convert to hsv and get the histograms (one each for h, s, and v) using histc() to specify the boundaries that the authors want for each bin. The rest should be straightforward.
i used this :
if (sizeOI(1)==256) % 2 by 3
hsvblock1=hsvimage(1:128,1:128,:);
hsvblock2=hsvimage(1:128,129:256,:);
hsvblock3=hsvimage(1:128,257:384,:);
hsvblock4=hsvimage(129:256,1:128,:);
hsvblock5=hsvimage(129:256,129:256,:);
hsvblock6=hsvimage(129:256,257:384,:);
end
if (sizeOI(1)==384) % 3 by 2
hsvblock1=hsvimage(1:128,1:128,:);
hsvblock2=hsvimage(1:128,129:256,:);
hsvblock3=hsvimage(129:256,1:128,:);
hsvblock4=hsvimage(129:256,129:256,:);
hsvblock5=hsvimage(257:384,1:128,:);
hsvblock6=hsvimage(257:384,129:256,:);
end
but for the image 2by3:
it gave me an error:
??? Index exceeds matrix dimensions.
Error in ==> fg at 22
hsvblock3=hsvimage(1:128,257:384,:);
and for block6 also, i can't see an error so what do you think?
Section 3.1 of that paper says,
"3.1 Data set: Wang's [15] dataset comprising of 1000 Corel images with ground truth. The image set comprises 100 images in each of 10 categories. The images are of the size 256 x 384 or 384X256. But the images with 384X256 are resized to 256X384."
Therefore your code only has to deal with images of size 256 x 384, and you should be resizing the 384x256 images to 256 x 384 before entering the part of your code that needs to divide the image up in to blocks.
The question of how to divide up parametrically is thus irrelevant, and a straight blockproc() or mat2cell() can be used.
yes i forgot that part, thank you
would you please you help me with matlab code example how to use the blockproc() function ?

Sign in to comment.

yasmine: What I was hoping you'd figure out is that you can just do something like
[rows columns numberOfColorBands] = size(hsvimage);
halfRows = floor(rows/2);
thirdCols = floor(columns/3);
block1 = hsvimage(1:halfRows, 1:thirdCols , :);
block2 = hsvimage(1:halfRows, thirdCols +1:thirdCols *2, :);
block3 = hsvimage(1:halfRows, thirdCols *2+1:end, :);
block4 = hsvimage(halfRows+1:end, 1:thirdCols , :);
block5 = hsvimage(halfRows+1:end, thirdCols +1:thirdCols *2, :);
block6 = hsvimage(halfRows+1:end, thirdCols *2+1:end, :);
Now set up your histogram edges as in the paper and call histc(block1(:), histEdges), or whatever the calling protocol is, for each of the 6 blocks.

3 Comments

ok thank you so much for your help
i used your code, and now for each block i will do some kind of quantization before calling the histc() function.
I need to make a for loop that repeats the quantization for every block so how to make this for these numeric arrays:
for i=1:6
block(i)(row, col)= "code of quantization"
end
how to make that part "block(i)(row, col)" using matlab ?
Thanks alot
I tried this:
for i=1:6
h = ['Hueblock' int2str(i)];
eval(h)
end
%Quantizing the HUE
for row=1:BRows
for col=1:BCols
if (h(row,col) >= 316 && h(row,col) <= 20)
h(row,col) = 0;
elseif (h(row,col) >= 21 && h(row,col) <= 40)
h(row,col) = 1;
elseif (h(row,col) >= 41 && h(row,col) <= 75)
h(row,col) = 2;
elseif (h(row,col) >= 76 && h(row,col) <= 155)
h(row,col) = 3;
end
but gave me this error:
Attempted to access h(1,10); index out of bounds because size(h)=[1,9].
Error in ==> fg6 at 85
if (h(row,col) >= 316 && h(row,col) <= 20)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!