How to reduce an image given a factor?

Hello, can someone help me how to make an image be reduced given a factor. For example I have to do the following To reduce we will form blocks of (factor x factor) pixels, we will add their gray values and we will divide by the number of summed values. In this way, we will apply super-sampling with a medium low pass filter. How do I make the blocks and the average? I do not get it. One help please Thanks

Answers (1)

You can use imresize(), to resize your image by a given factor. You can specify the interpolation method, using 'method' property as follow
resizedImage = imresize(image, factor, 'method', 'bicubic');
the available methods are listed here.

14 Comments

But I can not use that function it has to be otherwise

If you want to code it from scratch, then the simplest way is to loop over entire image, ectract blocks and do average as you explained in the question. Following resources will help you to do this.

https://www.mathworks.com/help/matlab/ref/for.html

https://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html

https://www.mathworks.com/help/matlab/ref/mean.html

I have made this code but the image comes out in black.

Thank you very much for the help

function [output]=reduce(input, factor)
  input = double(input);
  image=size(entrada);
  output=zeros(image(1)/factor,image(2)/factor);
  for i=1:factor:image(1)
      for j=1:factor:imagen(2)
          mean = sum(sum(input(i:factor,j:factor)));
          output(i,j)=mean/(factor*factor);
      end
  end
   output=zeros(image(1)/factor, image(2)/factor, class(input));

@Carlos, Although there can much efficient implementations, based on the code you gave, here is one implementation from top of my head,

function [output]=im_sample(input, factor)
input = double(input);
% image=size(entrada);
output = nan(size(input, 1), size(input,2));
for i=1:factor:size(input, 1)-factor
    for j=1:factor:size(input, 2)-factor
        output(i,j)= mean(mean(input(i:i+factor,j:j+factor)));
    end
end
nans = isnan(output);
output(all(nans'), :) = [];
output(:, all(nans)) = [];
output = uint8(output);

But this will only work with integer values of factor. For better implementation, you might want to look into some other algorithms.

Here is a better implementation based on interp2 function and can take real numbers as factor input.

function [output]=im_sample(input, factor)
  rows = size(input, 1);
  cols = size(input, 2);
  rowsFactor = resample(1:cols, floor(cols/factor), cols);
  colsFactor = resample(1:rows, floor(rows/factor), rows);
    [x, y] = meshgrid(1:cols, 1:rows);
    [x_, y_] = meshgrid(rowsFactor, colsFactor);
    output = interp2(x, y, double(input), x_, y_, 'nearest');
    output = uint8(output);
end
Thank you very much, you have helped me a lot. I have another question for a color image, do I have to use a "for" loop that runs through each channel of the image? Something like this:
if length(size(input))==3
for k=i:3
for i=1:factor:size(input, 1)-factor
for j=1:factor:size(input, 2)-factor
output(i,j,k)= mean(mean(input(i:i+factor,j:j+factor)));
end
end
end
end
No necessary, all channels are independent. You can average them together using colon (:) operator like this
if length(size(input))==3
for i=1:factor:size(input, 1)-factor
for j=1:factor:size(input, 2)-factor
output(i,j,:)= mean(mean(input(i:i+factor,j:j+factor, :)));
end
end
end
I have a problem when I run a color image it reduces it to me in gray scale and I also get an error that says: "Assignment has more non-singleton rhs dimensions than non-singleton subscripts " in this line of code: This is the code:
output(i,j,:)= mean(mean(input(i:i+factor,j:j+factor,:)));
function [output]=reduccion(input, factor)
input = double(input);
output = nan(size(input, 1), size(input,2));
if length(size(input))==3
for i=1:factor:size(input, 1)-factor
for j=1:factor:size(input, 2)-factor
output(i,j,:)= mean(mean(input(i:i+factor,j:j+factor,:)));
end
end
else
for i=1:factor:size(input, 1)-factor
for j=1:factor:size(input, 2)-factor
output(i,j)= mean(mean(input(i:i+factor,j:j+factor)));
end
end
end
nans = isnan(output);
output(all(nans'), :) = [];
output(:, all(nans)) = [];
output = uint8(output);
end
And another thing because you eliminate a row and column in the output image?
Although you are trying to use this code for the color image, you haven't updated the dimensions of output matrix. It is still 2D and you are getting a grayscale image. You should change the line as
output = nan(size(input, 1), size(input,2), size(input,3));
or more compact
output = nan(size(input));
Now everything goes well but I have a problem in this part of the code says that I can not do transposed in "ans"
nans = isnan(output);
output(all(nans'), :) = []; <- here
output(:, all(nans)) = [];
output = uint8(output);
Another detail which I missed in last comment is that you need to modify last lines like this to make it work for both grayscale and color images.
nans = isnan(output(:,:,1));
output(all(nans'), :, :) = [];
output(:, all(nans), :) = [];
output = uint8(output);
Now everything works correctly but one last question in the exercise I do this warning although the result I get is not bad but there says to apply a low pass filter but when I apply the filter the image is blurred a bit but without filter goes well. The warning reads as follows:
At the time of the formation of the blocks, it must be taken into account that within the limits of image it is possible that blocks of pixels can not be formed (factor x factor). In In that case, you must consider how many pixels really add up so that applying the low pass filter does not obscure the image in the limit.
It is normal for a filter to get blur on applying a low pass filter.
It appears warning is talking about the fact that the blocks will not always fit inside the complete image e.g. if the number of columns is odd and you are using 2*2 block then at least one column will be left out. More problem will happen if you will use a large n*n block. In that case you will need to decide how to handle those pixels.

Sign in to comment.

Asked:

on 24 Apr 2018

Commented:

on 25 Apr 2018

Community Treasure Hunt

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

Start Hunting!