I have an image and I have to take the average of the color of 2x2 pixel.
take the average color of a 2x2 pixel block, then compute the distance between the colors in the image and the colors available for our use.
I have no idea what taking the average of 2x2 pixel block means. How to solve this?
Thank you.
You can process non-overlapping blocks of an image using blockproc
Im = imread('coins.png'); %// example image fun = @(block_struct) mean( block_struct.data(:) ); %// anonymous function to get average of a block B = blockproc(Im,[2 2],fun); %// process 2 by 2 blocks imshow(B,[]); %// show resulting image
One other method I can suggest is to use combination of colfilt
with the 'sliding'
flag and mean
as the function to operate on. The 'distinct'
flag is what you actually need to use, but if you see the conversation between myself and @eigenchris, we couldn't get it to work. Still, eigenchris has shown that this is 300x faster than blockproc
.
Therefore, assuming your image is stored in im
, you can simply do:
out = uint8(colfilt(im, [2 2], 'sliding', @mean)); out2 = out(1:2:end,1:2:end);
The reason why you would need to subsample the results is because when we apply a sliding
option, you have overlapping blocks processing the image at a time. Because you want distinct blocks, you only need 1/4 of the image because you have decomposed the image into 2 x 2 blocks. Within a 2 x 2 block, if you did the sliding option, you would have three other results that are not required, and so doing the subsampling above by a factor of two eliminates those three other blocks that give results.
Note that you'll need to cast the result as the output will be of type double
.
Going with the discussion between myself and eigenchris, you can replace colfilt
with the canonical imfilter
to replicate the first line of the above code. I managed to get an 8x speedup on my machine when comparing the two together. Therefore:
out = imfilter(im, [0.25 0.25; 0.25 0.25], 'replicate'); out2 = out(1:2:end,1:2:end);
In terms of speedup, I wrapped each call in an anonymous function, then used timeit
to time the functions:
>> f = @() uint8(colfilt(im, [2 2], 'sliding', @mean)); >> g = @() imfilter(im, [0.25 0.25; 0.25 0.25], 'replicate'); >> T = timeit(f); >> T2 = timeit(g); >> T/T2 ans = 7.5421
As you can see, there is roughly a 8x speedup over colfilt
... most likely because it's calling im2col
and col2im
under the hood.
Using loops: (another method, just for knowing)
A = imread('cameraman.tif'); i = 1; j = 1; [rows, cols] = size(A); C(rows/2,cols/2) = 0; for x = 1:2:rows for y = 1:2:cols block = [A(x,y),A(x+1,y),A(x,y+1),A(x+1,y+1)]; C(i,j) = mean(block(:)); j = j+1; end i = i+1; j = 1; end C = uint8(C); figure; imshow(A); %// show original image figure; imshow(C); %// show resulting image