Matlab-Making video from images - matlab

Im trying to make a video from a file with 95 images in matlab.When i run the program,i get this error:
Error using VideoWriter/writeVideo (line 383)
Frame must be 481 by 272
Error in savenew (line 14)
writeVideo(writerObj,im2frame(Frame)
Although when the number of images that i use for making the video is under 11 i have no problem and the program is constructing the video that i want.Do you know how i can fix the problem?
Thanks in advance
Here is my update code:
ImagesFolder=uigetdir;
jpegFiles = dir(strcat(ImagesFolder,'\*.jpg'));
S = [jpegFiles(:).datenum];
[S,S] = sort(S);
jpegFilesS = jpegFiles(S);
VideoFile=strcat(ImagesFolder,'\MyVideo');
writerObj = VideoWriter(VideoFile);
fps= 10;
writerObj.FrameRate = fps;
open(writerObj);
for t= 1:length(jpegFilesS)
Frame=imread(strcat(ImagesFolder,'\',jpegFilesS(t).name));
B = imresize(Frame, 1.0);
C=im2double(B);
writeVideo(writerObj,im2frame(C));
end
close(writerObj);
implay('C:\Program Files\MATLAB\R2013a\bin\sfalmata neo\MyVideo.avi');

All frames of a video must have the same size. Resize your frames using 'imresize'. In case of different data types also apply 'im2double'

Related

Read in mp4 video file with audio, edit the frames and write them to a new file with the audio

I am reading a filename.mp4 video file in MATLAB. I want to edit the images, however, I want to keep the audio intact. Using VideoReader and VideoWriter only does the images part. I used vision.VideoFileReader and 'vision.VideoFileWriter'. I read the video and audio files, then take the image and add a picture next to it. Then write the frame and the audio associated with it. The final video shows the picture I added, but not the original image. Any help appreciated.
v = VideoReader('movie.mp4');
nfr = v.NumberofFrames;
clear v;
vR = vision.VideoFileReader('movie.mp4','AudioOutputPort',1);
fr = vR.info.VideoFrameRate;
vW = vision.VideoFileWriter('filename.avi','AudioInputPort',1,'FrameRate',fr);
pic = imread('picture.png');%read picture
[a1,b1,~] = size(pic);% get picture size to be resized.
for i = 1:nfr
[I,audio] = vR();
I = permute(I,[2,1,3]);%rotate 90 degrees
if i == 1%resize the picture
[a,b,~] = size(I);
pic = imresize(pic,[a,a/a1*b1]);
end
I = [I pic];%combine picture and movie frame
vW(I,audio);%write frame and audio
end
release(vR);
release(vW);
I figured it out.
v = VideoReader('movie.mp4');
nfr = v.NumberofFrames;
clear v;
vR = vision.VideoFileReader('movie.mp4','AudioOutputPort',1,'VideoOutDataType','uint8');
%default of VideoOutDataType is 'single', converting it to a similar format is essential
fr = vR.info.VideoFrameRate;
vW = vision.VideoFileWriter('filename.avi','AudioInputPort',1,'FrameRate',fr);
pic = imread('picture.png');%read picture
[a1,b1,~] = size(pic);% get picture size to be resized.
for i = 1:nfr
[I,audio] = vR();
I = permute(I,[2,1,3]);%rotate 90 degrees
if i == 1%resize the picture
[a,b,~] = size(I);
pic = imresize(pic,[a,a/a1*b1]);%resizing the pic to same height as movie frame %with proportional width
end
I = [I pic];%combine picture and movie frame
vW(I,audio);%write frame and audio
end
release(vR);
release(vW);

Most efficient way to track multiple small objects in MATLAB?

I am relatively new to image processing, and have never attempted to do anything with images in MATLAB, so forgive me if i am making some very rookie errors.
I am attempting to make a program that will track ants in a video. The video is taken from a stationary camera, and records the ants from a birds-eye perspective. I am having issues making reliable tracks of the ants however. Initially, i used the ForegroundDetection function, however there were multiple issues:
1.) Stationary ants were not detected
2.) There was too much overlap between objects (high levels of occlusion)
A friend of mine recommended having a larger gap between compared frames, so instead of subtracting frame 1 from frame 2, do frame 1 from frame 30 instead (1 second apart), as this will make the ants that do not move as much more likely to appear on the subtracted image.
Below is the code i have so far. It is a bit of a shot-in-the-dark attempt to solve the problem, as i am running out of ideas:
i = 1;
k = 1;
n = 1;
Video = {};
SubtractedVideo = {};
FilteredVideo = {};
videoFReader = vision.VideoFileReader('001.mp4',...
'ImageColorSpace', 'Intensity', 'VideoOutputDataType', 'uint8');
videoPlayer = vision.VideoPlayer;
blobby = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
'AreaOutputPort', true, 'CentroidOutputPort', true, ...
'MinimumBlobArea', 1);
shapeInserter = vision.ShapeInserter('BorderColor','White');
while ~isDone(videoFReader) %Read all frame of video
frame = step(videoFReader);
Video{1, i} = frame;
i = i+1;
end
%Perform subtraction
for j=1: 1: numel(Video)-60
CurrentFrame = Video{1,j};
FutureFrame = Video{1,j+60};
SubtractedImage = imsubtract(CurrentFrame, FutureFrame);
SubtractedVideo{1,j} = SubtractedImage;
ImFiltered = imgaussfilt(SubtractedImage, 2);
BWIm = im2bw(ImFiltered, 0.25);
FilteredVideo{1,j} = BWIm;
end
for a = n:numel(FilteredVideo)
frame = Video{1, n};
bbox = step(blobby, FilteredVideo{1, k});
out = step(shapeInserter, frame, bbox);
step(videoPlayer, out);
k = k+1;
end
currently, when i run the code, i get the following error on the line out = step(shapeInserter, frame, bbox):
'The Points input must be a 4-by-N matrix. Each column specifies a different rectangle and is of the form [row column height width].'
My questions is:
1.) Is this the best way to try and solve the problem I'm having? Is there potentially an easier solution?
2.) What does this error mean? How do i solve the issue?
I appreciate any help anyone can give, thank you!

Create video with identical frames in matlab

I am creating a video for a presentation with matlab. The video shows a optimization algorithm moving towards the minimum of a costfunction. I want the last seconds of the video to be a freeze-frame, which means that I use the writevideo function to write a couple of identical frames. However when I play the video with VLC player or with powerpoint the correct length of the video is shown, but the identical frames of the video are "skipped". Is there any way I can stop this?
My Code looks like this:
graph = figure('units','pixels','position',[0 0 1920 1080]);
scatter3... %(first frame)
v = VideoWriter('Presentation.avi');
v.Quality = 95;
v.FrameRate = 1;
open(v);
frame = getframe(graph);
writeVideo(v,frame);
for i = 1:10
plot3... %(changing frames)
frame = getframe(graph);
writeVideo(v,frame);
end
for j = 1:5
%(identical frames)
frame = getframe(graph);
writeVideo(v,frame);
end
close(v);
Thank you for answering!

imshow shows rotated image

I'm using Matlab to show the frames in a video sequence , below is my code:
seq=sprintf('walk%d.avi',v); % video's name
videoReader = vision.VideoFileReader(seq);
vidObj = VideoReader(seq);
numFrames = vidObj.NumberOfFrames
for i = 1:numFrames
frame = step(videoReader); % read the next video frame
imshow(frame)
end
Actually it worked fine previously, and i have no idea since when and what caused it to show rotated image . Hope you guys can help me. thank you.
Most updated Matlab function to vertically flip back the frame is:
FlippedFrame = flip(frame,1);

Detecting frames for which a face appears in a video

I need to detect the number of frames for which a face is appearing in a video. I looked into the sample code using CAMShift algorithm provided in the MathWorks site(http://www.mathworks.in/help/vision/examples/face-detection-and-tracking-using-camshift.html). Is there a way of knowing whether a face has appeared in a particular frame?
I'm new to MatLab. I'm assuming the step function will return a false value if no face is detected (condition fails - similar to C). Is there a possible solution? I think using MinSize is also a possible solution.
I am not concerned about the computational burden - although a faster approach for the same would be appreciated. My current code is given below:
clc;
clear all;
videoFileReader = vision.VideoFileReader('Teapot.mp4', 'VideoOutputDataType', 'uint8', 'ImageColorSpace', 'Intensity');
video = VideoReader('Teapot.mp4');
numOfFrames = video.NumberOfFrames;
faceDetector = vision.CascadeObjectDetector();
opFolder = fullfile(cd, 'Face Detected Frames');
frameCount = 0;
shotCount = 0;
while ~isDone(videoFileReader)
videoFrame = step(videoFileReader);
bbox = step(faceDetector, videoFrame);
framCount = frameCount + 1;
for i = 1:size(bbox,1)
shotCount = shotCount + 1;
rectangle('Position',bbox(i,:),'LineWidth', 2, 'EdgeColor', [1 1 0]);
videoOut = insertObjectAnnotation(videoFrame,'rectangle',bbox,'Face');
progIndication = sprintf('Face has been detected in frame %d of %d frames', shotCount, numOfFrames);
figure, imshow(videoOut), title(progIndication);
end
end
release(videoFileReader);
You can use the vision.CascadeObjectDetector object to detect faces in any particular frame. If it does not detect any faces, its step method will return an empty array. The problem is that the face detection algorithm is not perfect. Sometimes it detects false positives, i. e. detects faces where there are none. You can try to mitigate that my setting the MinSize and MaxSize properties, assuming you know what size faces you expect to find.