1

I am trying to create a movie in Matlab using series of functions under VideoWriter function. My code is somewhat like one shown below:

vidObj=VideoWriter('movie.avi');
open(vidObj);

for i=1:N %N is number of frames

[nx,ny]=coordinates(Lx,Ly,Nx,Ny,[x(i),-y(i)]);
%Lx and Ly refer to the length and height in meters. 
%Nx and Ny are number of pixels (boxes) and fit into the respective L's. 
%If Lx=10e-6 , with Nx=5, there will be 5 pixels in x dimension,
%each of length 2e-6 m.
[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)
rectangle('Position',[-rad(end),-rad(end),dia(end),dia(end)],'Curvature',[1,1]);
axis image;
axis off;
currFrame=getframe(gcf);
writeVideo(vidObj,currFrame);
end
close(vidObj);
return

This generated a movie called movie.avi. However, the movie (and the tif images generated from command window) has the dimensions of "420x560x3".

edit: the tif's are generated from the movie.avi using the following code:

obj = VideoReader('movie.avi');
vid = read(obj);
frames = obj.NumberOfFrames;
for x = 1 : frames
    imwrite(vid(:,:,:,x),strcat('frame-',num2str(x),'.tif'));
end

I am trying to use these images in another software, IDL, following: read Part 1 of this link

However, when runs on IDL, it detects the dimensions as [3x420x560], and therefore generates a really weird image when I run the normalization.

  1. How do I fix this? Is using imwrite going to help?
  2. I was able to successfully open the .tif in IDL, but it shows that the 420x560 is actually an image including an external grey boundary. frame-1.tif

How do I remove this boundary? I tried seeing through my functions and they were fine. (I think)

I apologize in advance for asking so many questions. I am very new to this and need help. Thank you once again

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96

2 Answers2

2

I think that the grey boundary around your image is due to the fact that when the code grabs the frame (using getframe) it is being passed the handle to the current figure (gcf) which includes the grey boundary around the image. Try instead using the handle to the current axis

currFrame=getframe(gca);

I tried this and with gca there was no grey boundary around the image when I tried the

image(currFrame.cdata);

When I retrieved the frame, the data within that corresponded to the image was reduced in dimension. I'm not sure why the code does this but an alternative to getframe is to do the following

I           = imread('someImage.jpg');
h           = imagesc(I);
imageScData = get(h,'CData');
frameData   = im2frame(imageScData);

Naturally, you won't have the first two lines since you are building your image at each iteration of the for loop. But I did notice that size(frameData.cdata)==size(I) - so no reduction.

You also mention how IDL (which I've never used) is reading in the files incorrectly or rather that the image dimensions are detected incorrectly. How are you writing out the image to a tif file? (I didn't see any MATLAB code above, like imwrite, indicating this.)

Geoff
  • 1,603
  • 11
  • 8
  • Thank you for a quick reply. I have made an edit to show how I created the .tif. Please look into my procedure. Thank you! – Nitsorn Wongsajjathiti Jun 04 '14 at 15:46
  • I have made changes you suggested using currFrame and image(). It works fine except I continuously receive dimension error: `Error using VideoWriter/writeVideo (line 383) Frame must be 344 by 343 Error in finalmiescatter (line 72) writeVideo(vidObj,currFrame);` Any help with that too? Thank you – Nitsorn Wongsajjathiti Jun 04 '14 at 15:55
  • For the error message `Frame must be 344x343..` that probably means that the first frame being written to the video object is of size 344x343x3 and subsequent ones are not. Try stepping through the code and check the size of each frame being written to the video. You may have to resize the image (see `imresize`) or perhaps `imagesc(nx/rad,ny/rad,Ecc)` was guaranteeing that when you called `getframe` that the frames would all be the same dimension. What happens if you use go back to using `imagesc` and `currFrame=getframe(gca);`? – Geoff Jun 04 '14 at 16:06
  • As for your tif writing code, it looks fine. I created a video, read all frames and wrote to the tif files as you did above and all was okay in the sense that they were mxnx3 frames written to the tif files as mxnx3 and then read back into MATLAB (via `imread`) with the same dimension (I don't have IDL to test that end out). It could have been that the frame was being extracted incorrectly as a 3xnxm image and then written out in that manner. This is why stepping through the code with the debugger is valuable - you can see what is being written to file and ask yourself if it makes sense. – Geoff Jun 04 '14 at 16:24
  • @GoeffHayes I only received the 344x343 error when I simply changed gcf to gca. I do not fully understand the "alternative to `get frame`' part you mentioned, and attempted but received an error. Can you elaborate more on this? PS: Also, the reduced dimensions from 460x560 to 344x343 is expected (and desired) since the prior is including the grey box. – Nitsorn Wongsajjathiti Jun 04 '14 at 17:43
  • I had thought maybe you had switched the code to use `im2frame` as well. But if your only change was to use `gca` then I recommend that you step through the code and check the dimensions of the frames being written to file. If they are not all of the same size, then you will have to resize it. You can also add the following line to your script or type it in the command window to automatically open the debugger if there is an error: `dbstop if error`. – Geoff Jun 04 '14 at 18:23
1

To fix interleave problem, i.e., 3 x 420 x 560 vs 420 vs 3 x 560 vs 420 x 560 x 3, when reading in IDL, use the INTERLEAVE keyword to READ_TIFF to specify how you want the result:

IDL> im = read_tiff(filename, interleave=2)
mgalloy
  • 2,356
  • 1
  • 12
  • 10