I've been trying to to read an MP4 file using VideoReader. Matlab is able to read the images, but the further the frame is along the video, the more time it takes.
tic;I=read(v,1);toc
Elapsed time is 0.264011 seconds.
tic;I=read(v,2000);toc
Elapsed time is 32.859614 seconds.
Also, I'm not sure if this is related, but Matlab cannot determine the number of frames in the file:
v=VideoReader('S1140007 (~200 cubes, large).MP4');
Warning: Unable to determine the number of frames in this file.
I've tried using two versions R2012b and R2015a, and the problem persists.
On a different machine, however, the number of frames can be determined and the reading times don't get longer, so obviously there's something configured wrong on my machine.
I there a known solution for this problem (can this be related to codecs somehow?), or maybe an alternative method of reading one image at a time (readFrame is not relevant for my needs).
Any help would be appreciated,
Aviram
OK, so this is not exactly an answer, but a workaround...
It seems that to set the NumberofFrames property in the videoreader object created for a video with an undetermined number of frames, one needs to read the last frame using the following code (as mentioned in the documentation of VideoReader):
v=VideoReader('path.mp4');
l=read(v,inf);
This sets the number of frames in the video, and allows for indexing and quick reading of single frames from the video. However, this only works in matlab r2012b. In 2015a, the NumberofFrames property is set by the read(v,inf) trick, but the reading is still very time-consuming, for some reason.
I'm not sure why this happens, and as I've said, some of the other machines I've checked were able to read my files properly (but some didn't), so this is far from completed. It is not clear why it cannot determine the number of frames, or why there's any variability between computers and why in some versions the last(v, inf) works and in others only partially.
Related
After a long time searching for an answer and not having found one, my last resort is asking a new question. I create multiple (N=1000) -mat v-6 files that are each about 100 MB in size and contain a single matrix. In a separate part of my code, I need to load in each file. The problem I'm running into is that loading the files in suddenly becomes very time consuming around file number 600 and I'm not sure why its happening. Thanks in advance for any suggestions.
I'm using Matlab R2014b on a Mac with 16GB of ram.
Sample code
c=nan(1,1000)
for h=1:1000
tic
filename=[basefilename,'_',num2str(h),'.mat'];
transition=load(filename,'P')
c(h)=toc;
end
Here is an image of the recorded loading times using the exact code above
I am getting some readings off an accelerometer connected to an Arduino which is in turn connected to MATLAB through serial communication. I would like to write the readings into a text file. A 10 second reading will write around 1000 entries that make the text file size around 1 kbyte.
I will be using the following code:
%%%%%// Communication %%%%%
arduino=serial('COM6','BaudRate',9600);
fopen(arduino);
fileID = fopen('Readings.txt','w');
%%%%%// Reading from Serial %%%%%
for i=1:Samples
scan = fscanf(arduino,'%f');
if isfloat(scan),
vib = [vib;scan];
fprintf(fileID,'%0.3f\r\n',scan);
end
end
Any suggestions on improving this code ? Will this have a time or Size limit? This code is to be run for 3 days.
Do not use text files, use binary files. 42718123229.123123 is 18 bytes in ASCII, 4 bytes in a binary file. Don't waste space unnecessarily. If your data is going to be used later in MATLAB, then I just suggest you save in .mat files
Do not use a single file! Choose a reasonable file size (e.g. 100Mb) and make sure that when you get to that many amount of data you switch to another file. You could do this by e.g. saving a file per hour. This way you minimize the possible errors that may happen if the software crashes 2 minutes before finishing.
Now knowing the real dimensions of your problem, writing a text file is totally fine, nothing special is required to process such small data. But there is a problem with your code. You are writing a variable vid which increases over time. That may cause bad performance because you are not using preallocation and it may consume a lot of memory. I strongly recommend not to keep this variable, and if you need the dater read it afterwards.
Another thing you should consider is verification of your data. What do you do when you receive less samples than you expect? Include timestamps! Be aware that these timestamps are not precise because you add them afterwards, but it allows you to identify if just some random samples are missing (may be interpolated afterwards) or some consecutive series of maybe 100 samples is missing.
I am using Matlab for a position tracking application wherein the position is extracted frame by frame from a ~20 minute .avi file. Right now to process a 20 minute video takes ~1 hour. The annoying thing is that the actual algorithmic computations are quite fast. The bottleneck is simply LOADING the .avi frames into Matlab, which we do 20 frames at a time. Here is our pseudocode:
vidobj = VideoReader(vidFile);
frmStep=20; %# of frames to load at a time
for k=1:frmStep:(numFrames-frmStep+1)
f = read(vidobj, [k (k+frmStep-1)]);
%%Do video processing
end
I was wondering whether there was any way to load this faster or do anything about the horribly long computation times....
Over the years I have tried a couple of alternatives to Matlab's native video processing procedures but I never profiled them so I can't tell you anything about the speed up.
The first alternative I've used extensively was mmread. This function uses ffmpeg to do the actual frame grabbing.
Currently I use the VideoCapture class in mexopencv. You will need opencv installed for that to compile. I have also managed to get most of the Matlab bindings in opencv3 to compile (on Mac OSX), which also gives you a VideoCapture class.
I am trying to read many video files from a database and process them. I am using Matlab and my problem is that when I want to read a 10 minutes long full HD video I should wait so much and my computer stops performing well. I use this command
VideoReader('movie.mp4')
I have seen that it takes 47 seconds to read a 30 seconds long video in the same format. I do not need to load all frames into my memory I just need 11 frames for each step of my process and really got stock here. Any help will be appreciated.
Also here is my output when I run this command
disp(videoObj);
output:
Summary of Multimedia Reader Object for 'movie.mp4'.
Video Parameters: 30.00 frames per second, RGB24 1280x720.
1482 total video frames available.
By the way I am running my code on Matlab R2014a and my OS is ubuntu 14.0.4.
Siavash,
The long loading time is because the entire file is scanned to determine the number of frames. This process is necessary to support frame indexed based access. In R2014b and higher, the frame counting during construction has been disabled. Additionally, you can seek to specific locations in the file using the CurrentTime property and use the hasFrame/readFrame methods for reading to avoid this performance penalty
Dinesh
I'm using version R2015b and I find the same slow processing of mp4 files with the VideoReader and readFrame functions. However, I find that those functions perform much faster on an avi file than an mp4, so I first convert the mp4 to avi using an independent program from https://www.ffmpeg.org. I don't know why there's such a difference in speed between the two...perhaps someone from MATLAB can provide some insight into that question.
I have a video in which the frame rate is not constant over the length of video. How can i get the actual time information from the video using MATLAB?
Use the function mmread() available from the file exchange: (link). More generally, the best way is to be using a Unix system and issue system calls to a better program, like ffmpeg or mencoder, which can give you frame-specific timing information. Doing this with Matlab only would be a real pain. There may be a toolbox function for it, but then your code only works for other people who also have the toolbox...