I want to find a method to eliminate the repeating frames from a video. If I consider a video which will repeatedly show the same frame for 5 seconds, I want to include only one frame of that in the video and make it visible for 5 seconds. In here I am looking forward to minimize the file size by eliminating duplicate frames. Is there a method to do this using Matlab?
If your movie is just a series of stills that you wish to show as a slideshow/presentation with a fixed five second delay, then you should be able to used the 'FrameRate' property for the VideoWriter class. Try something like this example:
writerObj = VideoWriter('peaks.mp4','MPEG-4');
writerObj.FrameRate = 0.2; % One frame every 5 seconds
open(writerObj);
Z = peaks;
surf(Z);
for k = 1:4:20
surf(sin(2*pi*k/20)*Z,Z);
writeVideo(writerObj,getframe);
end
close(writerObj);
However, the frame-rate property cannot be varied over the course of your movie, so the more general form of your question is fundamentally an issue of encoder support for variable frame-rate encoding. Most modern encoders (e.g., H.264 implementations) are not designed to explicitly handle this, but rather have heuristics that can detect when content is not changing and efficiently encode the data (particularly if multi-pass encoding is used). Unfortunately, Matlab (I'm assuming that you've been using the VideoWriter class) doesn't really provide great deal of fidelity in this respect. I'm not even sure what inter-frame encoding settings are used for MPEG-4 with H.264 videos.
If the MPEG-4 with H.264 videos produced by VideoWriter are unacceptable, I'd recommend exporting your video in the highest quality possible (or lossless) and then learn to use a full-fledged encoding framework/library (ffmpeg, libav, x264) or application to encode to the quality and size you desire. Apparently Handbrake has support for variable frame-rate encoding, though it's not necessarily designed for what you may want I've not tested it. Or export your individual still frames and use actually video editing software (e.g. iMovie on OS X). There are also likely dedicated applications that can create a movie from a slideshow/presentation (both PowerPoint and Keynote can do this).
Within Matlab, another alternative, is to use a codec that explicitly supports variable frame rates – QuickTime's image-based codecs: Photo JPEG (not to be confused with Motion-JPEG), Photo PNG (a.k.a. Apple PNG), and Photo TIFF (a.k.a. Apple Tiff). You can encode content directly using these codecs with my QTWriter, which is available on Github. Note however, that on OS X 10.9+, QuickTime Player converts lossless variable frame-rate Photo PNG and Photo TIFF movies to lossy fixed frame-rate H.264 (Photo JPEG movies are not converted). See my note towards the bottom of this page for further details and a workaround.
Related
The Logitech C910 webcam spec indicates image and video capture. Because image and video capture are listed separately, I am assuming that they are encoded and sent differently: effectively forming two different 'channels' to select from. If this understanding is incorrect, please respond with an explanation of the true nature.
This reference indicates a maximum frame-rate of 15 because of windows.
My search returned webcam video acquisition that comprises a series of time lapsed images 'stitched' together
% Connect to the webcam.
cam = webcam
% Open Video File
vidWriter = VideoWriter('frames.avi');
open(vidWriter);
% Write images file
for index = 1:20
% Acquire frame for processing
img = snapshot(cam);
% Write frame to video
writeVideo(vidWriter,img);
end
%Close file and cam
close(vidWriter);
clear cam
MATLAB has captured successfully images with the C910.
Question
If possible within MATLAB, how does one configure the webcam's **video* frame rate and save the video stream to .avi or the like? (not writing still images to video file as depicted above).
Perhaps someone with experience or sharper Google skills can provide an example of bridging the webcam's video (vs the image) stream into MATLAB. Any example that can be tested is greatly appreciated.
A good way to 'jumpstart' or accelerate newbie familiarity is with the image acquisition tool:
imaqtool
The tool seems to be GUI wrapper that reduces the command-line syntax to a GUI. Note that the bottom right panel shows the command line equivalent of a GUI interaction.
Configurable video capture paramaters comprise:
Resolution & ROI (Region of Interest)
Frame Rate
Video type (.avi .mp4) etc.
when I use ffmpeg to scale a H264 video. It seems that the video is decoded to the raw graph then scaled then encoded again. But if the speed is very critical,is there a faster way if I specify a “good" ratio like 2:1, as if I want to pick up one pixel in every four?
I know a bit how h264 works, 8*8/4*4 pixels are coded as a group,so it's not easy to pick up 1/4 pixels in its range. But is there a way to merge 4 group into one quickly?
When you use ffmpeg for scaling purpose, there is no way you can avoid re-encoding to any part of the video. For scale operation, ffmpeg works in pipeline fashion as below:
Decoder ----> Scaler -----> Encoder
Scaler does scale operation only after a completely decoded frame is available to it. Since every packet passes through this pipeline, encoder receives video frames in decompressed (YUV format) form only. So, every YUV frame gets re-encoded after scale operation. I guess it clarifies why there is no way to avoid re-encoding.
The scaling ratio do play a role in complexity. I guess scale ratio 2:1 is OK, scale ratio affects the number of taps (filter coefficients) used in scale algorithm. Also, the scaling algorithm that you may choose add another layer of complexity. Least complex scaling algorithm in ffmpeg is "fast_bilinear". But be aware of the video quality trade-off.
Of course, encoding speed is another factor to consider. It seems you know fairly about it. One thing, see if you can make use of HW decoder & encoder that may be available in your system. If HW codec is available, it greatly improves the speed of this entire pipeline. You can try with -hwaccel dxva2 option for ffmpeg
I've been working on a project that reads in video frames, stores them in an array and then performs operations on them. The frames are each split into 6 subsections that I have to analyze individually.I had previously been cropping the video beforehand and then was loading it in. I now have the program allow the user to load in the whole movie and then crop each 6th themselves and then the program runs consecutively on each 6th. The problem is that matlab just crashes when loading this now 6-times more pixel dense video in (It's about 120k frames). assuming I can get the user to specify the 6 cropping areas before, is there anyway to load in only a specific area of the movie at a time? Rather than storing the whole frame, only store a 6th? (Unlike how I currently store the whole and THEN crop out a 6th, just store a 6th right off the bat).
VideoReader does not allow you to load in part of a frame into memory. However, it allows you to load in only certain frames from the video into MATLAB instead of loading in the entire video. Agree with sam that loading in 120K frames of video into MATLAB is a very bad idea. Consider using the READ syntax that allows you to specify the start and stop frames to only read in the video in chunks after which you can use array indexing to slice each frame into 6 portions.
Dinesh
I have a video which is represented as AVURLAsset. It comes from Camera Roll and is at full resolution.
Now if I only need it with 380 pixels width, what would be the fastest and most efficient way to get a downsampled copy of the video?
Is AVAssetExportSession the way to go? It also looks like AVAssetExportSession only works with presets. But in this case I want to specify custom pixel dimensions.
"An AVAssetExportSession object transcodes the contents of an AVAsset
source object to create an output of the form described by a specified
export preset."
Or must I look at other classes in AVFoundation? Or other frameworks even?
AVMutableVideoComposition has a renderSize property or AVAssetWriter/WriterInput has an ability to resize frame as you want, as well as other tweaks are possible (you are supplying output size/settings in dictionary), but it comes with necessity to set the whole stuff up (asset reader, feeding frames etc.). If you find better solution, let me know :)
I'm trying to track objects in separated frames of a video. If I do a background subtraction before storing the images the size of the images will be much smaller (like one fifth). so I was wondering if I can also read these images faster since most of the pixels are zero. Still simple imread didn't make any difference.
I also tried the pixelregion option for loading only the location of objects and that didn't work either since there are like ten objects in each frame.
It may be faster to store the frames as a video file, rather than individual images. Then you can read them using vision.VideoFileReader from the Computer Vision System Toolbox.