Nitsorn Wongsajjathiti
Nitsorn Wongsajjathiti

Reputation: 317

Writing a greyscale video using Videowriter/avifile

I am writing a function that generates a movie mimicking a particle in a fluid. The movie is coloured and I would like to generate a grayscaled movie for the start. Right now I am using avifile instead of videowriter. Any help on changing this code to get grayscale movie? Thanks in advance.

close all;
clear variables;
colormap('gray');

vidObj=avifile('movie.avi'); 
for i=1:N    
[nx,ny]=coordinates(Lx,Ly,Nx,Ny,[x(i),-y(i)]);
[xf,yf]=ndgrid(nx,ny);
zf=zeros(size(xf))+z(i);    

% generate a frame here
[E,H]=nfmie(an,bn,xf,yf,zf,rad,ns,nm,lambda,tf_flag,cc_flag);
Ecc=sqrt(real(E(:,:,1)).^2+real(E(:,:,2)).^2+real(E(:,:,3)).^2+imag(E(:,:,1)).^2+imag(E(:,:,2)).^2+imag(E(:,:,3)).^2);
clf
imagesc(nx/rad,ny/rad,Ecc); 
writetif(Ecc,i);
    if i==1
    cl=caxis;
    else
    caxis(cl)
    end
axis image;
axis off;
frame=getframe(gca);
cdata_size = size(frame.cdata);  
data = uint8(zeros(ceil(cdata_size(1)/4)*4,ceil(cdata_size(2)/4)*4,3));
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata];
frame.cdata = data; 
vidObj = addframe(vidObj,frame);
end
vidObj = close(vidObj);

Upvotes: 1

Views: 830

Answers (1)

rayryeng
rayryeng

Reputation: 104555

For your frame data, use rgb2gray to convert a colour frame into its grayscale counterpart. As such, change this line:

data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = [frame.cdata]; 

To these two lines:

frameGray = rgb2gray(frame.cdata);
data(1:cdata_size(1),1:cdata_size(2),1:cdata_size(3)) = ...
     cat(3,frameGray,frameGray,frameGray);

The first line of the new code will convert your colour frame into a single channel grayscale image. In colour, grayscale images have all of the same values for all of the channels, which is why for the second line, cat(3,frameGray,frameGray,frameGray); is being called. This stacks three copies of the grayscale image on top of each other as a 3D matrix and you can then write this frame to your file.

You need to do this stacking because when writing a frame to file using VideoWriter, the frame must be colour (a.k.a. a 3D matrix). As such, the only workaround you have if you want to write a grayscale frame to the file is to replicate the grayscale image into each of the red, green and blue channels to create its colour equivalent.

BTW, cdata_size(3) will always be 3, as getframe's cdata structure always returns a 3D matrix.

Good luck!

Upvotes: 1

Related Questions