Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

Manipulating a video in Matlab (video processing)

Asked by James on 22 Jun 2011

Hi

I have been able to read my sample video one frame at a time on Matlab.

I would now like to re-size each frame (by averaging adjacent rows/columns)

Can someone explain how to do this? And how can I find out the number of rows or columns of the frames?

0 Comments

James

Products

No products are associated with this question.

3 Answers

Answer by Walter Roberson on 22 Jun 2011
[number_of_rows, number_of_columns, number_of_channels] = size(YourFrame);

and provided rows and columns are even,

t1 = double(YourFrame(1:2:end,:,:)) + double(YourFrame(2:2:end,:,:));
t2 = t1(:,1:2:end,:) + t1(:,2:2:end,:);
MeanFrame = cast(t2 ./ 4, class(Yourframe));

1 Comment

Walter Roberson on 22 Jun 2011

By the way, there are many other ways to implement this.

Walter Roberson
Answer by James on 22 Jun 2011

Hi

Is it possible to explain this written commands as I have literally only started looking at Matlab yesterday.

Thanks for your quick reply

1 Comment

Walter Roberson on 22 Jun 2011

Images are often 8 bit unsigned integers, but if you add together enough 8 bit unsigned integers that the total would exceed 255 then the total "saturates" to 255 instead of to the total you want. You need to switch representation before you do the totaling.

double() applied to a value finds the numerical equivalent of that value, but as a double precision floating point number. Examples of double precision numbers are 7.0, 1.414, 3.14159265358979. So if the value in the image was the unsigned 8 bit integer (say) 142, then double() of it would be the floating point number 142.0 . You can add floating point numbers without worrying about going over 255.

FirstNumber:Step:LastNumber constructs a vector of values from the first number, not exceeding the last number, at intervals of the the middle number. For example 1:2:5 stands for the vector [1,3,5] and 2:2:5 stands for the vector [2 4].

When used as an index in to an array, a range like the above can include "end", which stands for the last element number in that dimension. 1:2:end applied in the first dimension thus means you wan the first row, the third row, the fifth row, and so on up to the last odd-numbered row. Likewise 2:2:end applied in the first dimension is the even-numbered rows.

The code above adds the odd-numbered rows with the even-numbered rows directly below them, and stores the result in the matrix named "t1".

Then the code adds the odd-numbered columns of t1 with the even-numbered columns of t1, and stores the result in the matrix named "t2". "t2" is thus now a matrix in which each element is the sum of a 2x2 submatrix, such as A(5,9)+A(5,10)+A(6,9)+A(6,10).

As t2 is the totals, t2 ./ 4 is the average, and so is very nearly what you asked for about averaging adjacent rows and columns. But t2 is floating point numbers, and might include the fractions 1/4, 1/2, and 3/4, depending on what the values totaled.

You want to convert this average with fractions back to the same numeric representation system as was used for the original image. For example if the original image was uint8 (unsigned 8 bit integers) then you want the output to be uint8 as well, for consistency. We no longer have to worry about overflowing uint8 because the average value cannot be larger than the largest possible original value that was stored before.

The call to class() returns a string which is the data type used to store the original image, and the call to cast() numerically converts the array to that data type.

James
Answer by Teja Muppirala on 22 Jun 2011

There is a function IMRESIZE in the Image Processing Toolbox that is designed to do exactly this, and it will take into account the datatypes for you.

A = uint8(magic(6))
imresize(A,0.5,'box')
imresize(A,[2 2],'box')
imresize(A,[1 6],'box')

Here the 'box' argument tells it to just resize using block averages as you mentioned. There are other ways to resize as well. Just look at the help for IMRESIZE if you have it avaliable to you.

3 Comments

James on 23 Jun 2011

what is uint8?

I have seen this on my video frames, with value <120x320x3 uint8>?

Walter Roberson on 23 Jun 2011

uint8 is unsigned 8 bit integers -- integer values only, 0 to 255 representable.

Walter Roberson on 23 Jun 2011

By the way, in my Answer above, I already guessed your image was uint8 and the code was written to handle that.

Teja Muppirala

Contact us