reading and displaying video file frame by frame - matlab

I am newly working with Matlab. I want to read a video file and do some calculations every frame and display every frame. I wrote the following code but every time it only displays the first frame. can anybody please help.
mov=VideoReader('c:\vid\Akiyo.mp4');
nFrames=mov.NumberOfFrames;
for i=1:nFrames
videoFrame=read(mov,i);
imshow(videoFrame);
end

Note: mmreader API has been discontinued by MATLAB so prefer using VideoReader.
See comment by #Vivek.
I usually do this:
obj=mmreader('c:\vid\Akiyo.mp4');
nFrames=obj.NumberOfFrames;
for k=1:nFrames
img=read(obj,k);
figure(1),imshow(img,[]);
end
As far as your code is concerned, I saw MATLAB's documentation. You should do the things in following order:
mov=VideoReader('c:\vid\Akiyo.mp4');
vidFrames=read(mov);
nFrames=mov.NumberOfFrames;
for i=1:nFrames
imshow(vidFrames(:,:,i),[]); %frames are grayscale
end

Function read() and the field NumberOfFrames() are now deprecated, Matlab suggests using
xyloObj = VideoReader(file);
vidHeight = xyloObj.Height;
vidWidth = xyloObj.Width;
mov = struct('cdata',zeros(vidHeight, vidWidth, 3,'uint8'), 'colormap',[]);
while hasFrame(xyloObj)
mov(k).cdata = readFrame(xyloObj,'native');
end
In case you want to estimate a number of frames in the video, use nFrames = floor(xyloObj.Duration) * floor(xyloObj.FrameRate);

Below suggested code is showing only one frame
imshow(vidFrames(:,:,i),[]);
I am doing following things to store each frame
obj = VideoReader('path/to/video/file');
for img = 1:obj.NumberOfFrames;
filename = strcat('frame',num2str(img),'.jpg');
b = read(obj,img);
imwrite(b,filename);
end
This will store all the frames in your home directory.And yes, as also suggested by Vivek and Parag
You need to use VideoReader as mmreader has been discontinued by
MATLAB.

*=I was making a function to play any .avi file as a set of frames in a figure. Here's what a did. A bit of a combo of what you've done, except my NumberOfFrames wasn't working: (noteL this also shows it in colour)
function play_video(filename)
% play_video Play a video file
% play_video(filename) plays the video file specified by filename in a MATLAB Figure window.
figure
set(figure, 'Visible', 'on')
mov=VideoReader(filename);
vidFrames=read(mov);
duration = mov.Duration;
frame_rate = mov.FrameRate;
total_frames = duration .* frame_rate
for i=1:1:total_frames
imshow(vidFrames(:, :, :, i), []);
drawnow
end

Related

Undefined function or variable 'mmreader'

I try to use matlab 2016a to read avi videos, however, I get the following problems:
undefined funciton or variable 'mmreader';
The code is as following:
clc;
clear;
%% this to read avi by using mmread to get every frame
video = mmreader('D:\My Documents\MATLAB\My\fire.avi');
nFrames = video.NumberOfFrames;
H = video.Height;
W = video.Width;
Rate = video.FrameRate;
% Preallocate movie structure.
mov(1:nFrames) = struct('cdata',zeros(H,W,3,'uint8'),'colormap',[]);
%read one frame every time
for i = 1:nFrames
mov(i).cdata = read(video,i);
P = mov(i).cdata;
disp('current frame number:'),disp(i);
imshow(P),title('original picture');
% P2=rgb2gray(P);
end
Why? Could anyone help me? Thanks in advance.
The function mmreader was deprecated in version R2010b, removed in version R2014a, and removed from the documentation altogether in version R2015b. It was replaced by the VideoReader function, so use that in its place.

How to save all sequentially captured image in MATLAB?

I need to save all the captured images in MATLAB but I am able to save one picture at a time.
mycam = webcam();
img = snapshot(mycam);
imwrite(img,'img.jpg');
If somebody knows how to save all the pictures taken at a time in MATLAB, please help me with the code.
I would save the images as a movie and then access the frames later. This is untested but it would work like this.
mycam = webcam();
% if you know the number of images use that here
% a movie is just a collection of frames
% if not then just don't initialize F
F(nFrames) = struct('cdata', [], 'colormap, []);
for i = 1:nFrames
F(i) = im2frame(snapshot(mycam));
end
% save F
movie2avi(F, 'MyMovie.avi', 'compression', 'None');
Then you can load the movie and look at the frames. This example uses the older movie2avi but VideoWriter is also an option
v = VideoWriter('MyMovie.avi');
open(v);
for i = 1:nFrames
writeVideo(v, snapshot(mycam));
end
close(v);
Again untested as I don't have a webcam attached to this computer. But it works for animated graphs. See doc readFrame for the way to read frames
As they have already told you, you should use a for loop with the sprintf function in order to not overwrite the previous images. Try with the following command:
%capture the frames
for i =1:n;% n is the number of frames you want to capture
frames{i} = getsnapshot(mycam);
end
%save in the current folder
for i = 1:n;
imwrite(frames{i}, sprintf('imageName%d.jpg',i))
end
You will have all the captured frames saved in the Current Folder.

Repeating trials in MatLab

i'm am very new to Matlab but really want improve. For my experiment i want to show a picture which the participant response yes/no to, using two different keys (f&g) and then the next picture is presented and it repeats so onward.
Presenting the picture, using the keys works for far, but i can't get it to repeat the trial. Thus my question is how can i get the program to repeat/loop my trial?
Is there something wrong in my code so far or is there additional coding i should use?
this is my code so far
function try1_6()
cleanupObj= onCleanup(#() myCleanupFxn);
% PRETEST
% Initialize screen with black background
winID = Screen('openWindow',0, [0 0 0]);
%Parameter
backcol=255;
textcol=0;
% Load image file(s)
structimages= [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i=1: length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structimages(end+1).filename=TheImagesdir(i).name;
structimages(end).destRect= destRect;
structimages(end).texture= myTexture;
end
%Make triallist
numberOfItems= [5]; %list of all possible items
Nrepeats=4;
Response=0;
TrialList=HH_mkTrialList({numberOfItems Response},Nrepeats);
%PRESENTATION
for trialnum=1:size(TrialList,1)
nitems = TrialList(trialnum,1);
Screen('FillRect', winID,backcol); % makes the screen blank
%displays text
DrawFormattedText(winID,'dkjfghaslkdfglksdjgfh','center','center',textcol);
Screen('Flip', winID)
HH_waitForKeyPress({'space'}); % waits for spacebar to be pressed
Screen('FillRect',winID,backcol);
Screen('Flip',winID);
WaitSecs(1);
%display picture
whichTheImages= randi(length(TheImagesdir)); % randomly selects image for directory
Screen('FillRect',winID,backcol);
Screen('DrawTexture', winID, myTexture, [], destRect);
Screen('Flip', winID);
HH_waitForKeyPress({'f','j'},5)
if resp==-1
break
end
TrialList(trialnum,4)= response; %records response
end
end
function myCleanupFxn()
Screen('CloseAll')
end
There are a number of problems with you code that you need to address. First of all, TrialList is used before it is declared/initialized. The Make triallist block of code seems out of place in the body of the for loop, and should probably be placed before you loop TrialList.
Your second problem is the inner for loop that loads images. Right now, it loads every image found in the directory, on every trial! There is no reason for you to be doing this, and you should be placing this for loop outside the trial loop as well. Furthermore, your original code never worked as intended, because you never save the loaded texture anywhere; myTexture is overwritten by the last image in your folder and that's the only texture you're ever gonna get. So in addition to pre-loading the images before the loop, you need to save them in a data structure so that you can use them later in your trial loop. A simple struct will work nicely here:
structImages = [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i = 1:length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structImages(end+1).filename = TheImagesdir(i).name;
structImages(end).destRect = destRect;
structImages(end).texture = myTexture;
end
There are other inconsistencies in your code:
whichTheIamges is defined but not used
resp is used in the comparison if resp==-1 but is not defined
response is saved into TrialList before it is defined
Finally, the biggest problem is Screen('CloseAll', winID); is inside the trial loop, so you tear down your whole presentation platform after the first trial.
FYI, as noted in my comment wrapping your entire script in a try block is really poor practice. I suspect you do this because you want to be able to Ctrl+C mid-task, but there's a better way to do this. If you make your entire script a function then you can use the onCleanup method to execute code whenever your function exits (whether normally, by error, or by interruption). The method goes like this:
function myScript()
%//make your script a function. There is an additional advantages to doing this:
%//function performance is better than script performance.
%//blah-blah-blah
%//setup the cleanup object before opening screen
cleanupObj = onCleanup(#() myCleanupFxn);
%//open the screen
winID = Screen('openWindow',0, [0 0 0]);
%//blah-blah-blah
end
function myCleanupFxn()
%//local function, not visible outside of this file
Screen('CloseAll');
end

MatLAB loading image and showing it correctly

I am trying to load an image and show it in MATLAB. It used to work on my other computer a while ago but on this computer the picture looks completely wrong and I am not sure why.
Thanks for all the help in advance.
This is the image I am loading:
https://dl.dropboxusercontent.com/u/13524574/(1).png
This is how MatLAB shows it:
https://dl.dropboxusercontent.com/u/13524574/WrongImage.png
Here is my code:
function main()
workingDir = 'E:\MASTERS\MatLAB\FullVideo_R_OF_HOF\Images';
S4A = zeros(360,640,3,256);
%getting 256 frames of the images
for ii = 1:256
S4A(:,:,:,ii) = imread(fullfile(workingDir,'S4A',strcat('(',int2str(ii),').png')));
end
%showing first frame only
imshow(S4A(:,:,:,1));
end
I'm not exactly sure what's going on in there with all those indices but I think I may be able to offer an alternative. Check out the third paragraph of the documentation, here, for return value information. I suggest using a cell array for clarity.
function main()
workingDir = 'E:\MASTERS\MatLAB\FullVideo_R_OF_HOF\Images';
S4A = zeros(360,640,3,256);
%getting 256 frames of the images
for ii = 1:256
A{ii} = imread(fullfile(workingDir,'S4A',strcat('(',int2str(ii),').png')));
end
%showing first frame only
imshow(A{1});
end

How to make and save a video(avi) in matlab

I am learning matlab myself andI have made an animated plot using matlab;now i want to save it as an video file.can you tell me how to convert my animation into a video file in matlab.Below is my code
x=[1:2];
for i=1:25,
m=randi([3,5]);
n=randi([3,5]);
y=[m n];
bar(x,y)
axis equal
A(i) = getframe;
end
matlab version 7.8 R2009a
use avifile:
aviobj = avifile('example.avi','compression','None');
x=[1:2];
for i=1:25,
m=randi([3,5]);
n=randi([3,5]);
y=[m n];
bar(x,y)
axis equal
aviobj = addframe(aviobj,gcf);
drawnow
end
viobj = close(aviobj)
If Matlab's avifile doesn't work (it might have problems with codecs of 64-bit OS), then use mmwrite.
http://www.mathworks.com/matlabcentral/fileexchange/15881-mmwrite
It's simple, and it works. I used it to create *.wmv files simply by:
mmwrite(filename, frames);
Edit: code example
% set params
fps = 25;
n_samples = 5 * fps;
filename = 'd:/rand.wmv';
% allocate frames struct
fig = figure;
f = getframe(fig);
mov = struct('frames', repmat(f, n_samples, 1), ...
'times', (1 : n_samples)' / fps, ...
'width', size(f.cdata, 2), ...
'height', size(f.cdata, 1));
% generate frames
for k = 1 : n_samples
imagesc(rand(100), [0, 1]);
drawnow;
mov.frames(k) = getframe(fig);
end
% save (assuming mmwrite.m is in the path)
mmwrite(filename, mov);
One way to do this is to print the figure to an image, and then stitch the resulting image sequence into a video. ffmpeg and mencoder are great tools for doing this. There are some great resources for describing this if you know the right search terms. I like this one
In mencoder, you could stitch your images together with a command like:
mencoder "mf://*.jpg" -mf fps=10 -o test.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=800
Have a look at VideoWriter or see this forum discussion