how to take an average of a 2x2 pixel block?

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

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.

回答1:

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 


回答2:

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.



回答3:

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!