Comparing several webcam snapshots and saving Them when there is motion Using matlab - matlab

My question is how would i get live snapshots from my webcam and only save an image when there is motion, I would like to save several images i.e whenever there is motion the images do not overwrite so that at the end i will be able to see various captured motions

well i was able to come up with a simple solution for my problem as below; it saves images only when there is motion and also adds a time stamp
clear;
clc;
vid = videoinput('winvideo', '1');
set(vid, 'ReturnedColorSpace', 'RGB');
start(vid)
%preview(vid)
while true;
img = getsnapshot(vid);
pause(2)
img1 = getsnapshot(vid);
img12 = rgb2gray(img1);
img13 = rgb2gray(img);
diff1 =sum(sum(img12 - img13));
if diff1>100000;
display ('motion')
counter = 1;
baseDir = 'H:\';
fname = [baseDir ,'Wysla_', num2str((strrep(datestr(clock),':','-'))),'.jpg'];
% make a file name
while exist(fname,'file')
counter = counter + 1;
fname = [baseDir ,'Wysla_', num2str(counter),'.jpg'];
end
imwrite(img1, fname);
else
display('No motion')
end;
end
This is all and it was very simple only thing i can mention is the strrep(datestr(clock),':','-') this a way of saving the image time stamped and since there are semi colons in the date string the strrep() replaecs them with the hyphen or anything else
av fun.

Related

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.

Matlab Code to Convert Video to Sequence of Frames

hi can someone tell me whats wrong with my Matlab Code to Convert Video to Sequence of Frames . it doesn't work.
clc
clear all
close all
file=aviinfo('test.avi');
frm_cnt=file.NumFrames
FileExtension='.bmp'
h = waitbar(0,'Please wait');
for i=1:frm_cnt
% Read the Frame of the Video file
frm(i)=VIDEOREADER ('test1.avi',i);
% Convert Frame to image file
frm_name=frame2im(frm(i));
%Create Filename to store
Filename=strcat(strcat(num2str(i)),FileExtension);
% Write image file to the current folder
imwrite(frm_name,Filename);
waitbar(i/frm_cnt,h)
end
%Close Progress bar
close(h)
Try this :
shuttleVideo = VideoReader('shuttle.avi');
ii = 1;
while hasFrame(shuttleVideo)
img = readFrame(shuttleVideo);
filename = [sprintf('%03d',ii) '.jpg'];
fullname = fullfile(workingDir,'images',filename);
imwrite(img,fullname) % Write out to a JPEG file (img1.jpg, img2.jpg, etc.)
ii = ii+1;
end

Matlab - combine two videos into a single split-screen video

I have 2 videos I would like to play side by side in a split screen. They are same duration and dimensions. I found a code developed few years back to do the job. The problem is, it is full of errors maybe due to the fact I am using a newer Matlab version (2014a). The errors start from (%name of the new avi file) onward.
Can anyone please try and fix it:
% select two files:
[filename1,pathname1] = uigetfile('.avi','pick first AVI file');
[filename2,pathname2] = uigetfile('.avi','pick second AVI file');
file1 = fullfile(pathname1,filename1);
file2 = fullfile(pathname2,filename2);
pdMovie1 = aviread(file1);
pdMovie2 = aviread(file2);
fileinfo1 = aviinfo(file1);
fileinfo2 = aviinfo(file2);
% check if AVI files have the same length and height:
if fileinfo1.NumFrames~=fileinfo2.NumFrames || ...
fileinfo1.Height~=fileinfo2.Height
errordlg('files are not compatible!')
else
% inspired by Herbert Ramoser in Message-ID:
% <art0c0$l9fip$1#ID-148798.news.dfncis.de>
for i=1:size(pdMovie1,2)
output(i).cdata = [pdMovie1(i).cdata, pdMovie2(i).cdata];
output(i).colormap = pdMovie1(i).colormap;
end;
% name of the new avi file:
[pathstr,name,ext,versn] = fileparts(filename1);
newmoviename = [pathname1,name,'_combined', ...
num2str(fileinfo1.FramesPerSecond;),ext];
% create the avi file:
movie2avi(output, newmoviename, ...
'fps', fileinfo1.FramesPerSecond;, ...
'compression', 'none');
close
end
If it is just for playing the videos side-by-side, this simplker code will work,
close all
clc
clear
vid1 = vision.VideoFileReader('video1.avi');
vid2 = vision.VideoFileReader('video2.avi');
vidP = vision.VideoPlayer;
while ~isDone(vid1)
frame1 = step(vid1);
frame2 = step(vid2);
frame = horzcat(frame1, frame2);
step(vidP,frame);
end
release(vid1);
release(vid2);
release(vidP);
UPDATE:
I'm assuming both input videos have the same length and frame dimension.
Ok, now if you want to record a new video from the first 2, with the same frame rate of the previous, it is better to use the following code,
close all
clc
clear
vid1 = VideoReader('video1.avi');
vid2 = VideoReader('video2.avi');
videoPlayer = vision.VideoPlayer;
% new video
outputVideo = VideoWriter('newvideo.avi');
outputVideo.FrameRate = vid1.FrameRate;
open(outputVideo);
while hasFrame(vid1) && hasFrame(vid2)
img1 = readFrame(vid1);
img2 = readFrame(vid2);
imgt = horzcat(img1, img2);
% play video
step(videoPlayer, imgt);
% record new video
writeVideo(outputVideo, imgt);
end
release(videoPlayer);
close(outputVideo);
If you have two video clips with different frame rates and resolutions or you would like to join/cut pairs of video clips, use the code below.
For example: My dashcam is able to record video in the front and the rear of the car at the same time. But the front and rear videos come in separate files. I want to show them side by side as well as to join 6 files (3 pairs) into a single file.
%Read video
clc
clear
vidObj_f = VideoReader('video1.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video2.mp4');
FrameRate_b = vidObj_b.FrameRate;
%New video
outputVideo = VideoWriter('combinedvideo.avi');
outputVideo.FrameRate = 24;
open(outputVideo);
skip = 95; %first seconds
j=skip*24;
try
while 1
front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
front = imresize(front,[720 1280]);
videoframe = [front;back];
writeVideo(outputVideo, videoframe);
j = j+1;
end
catch
disp('...end 1');
end
vidObj_f = VideoReader('video3.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video4.mp4');
FrameRate_b = vidObj_b.FrameRate;
skip = 0; %first seconds
j=skip*24;
try
while 1
front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
front = imresize(front,[720 1280]);
videoframe = [front;back];
writeVideo(outputVideo, videoframe);
j = j+1;
end
catch
disp('...end 2');
end
vidObj_f = VideoReader('video5.mp4');
FrameRate_f = vidObj_f.FrameRate;
vidObj_b = VideoReader('video6.mp4');
FrameRate_b = vidObj_b.FrameRate;
skip = 0; %first seconds
j=skip*24;
cut = 30; %after playing 'cut' seconds
try
while 1
front = read(vidObj_f,1+round(j*FrameRate_f*1/24));
back = read(vidObj_b,1+round(j*FrameRate_b*1/24));
front = imresize(front,[720 1280]);
videoframe = [front;back];
writeVideo(outputVideo, videoframe);
if j>cut*24
disp('...end 3 (cut)');
break
end
j = j+1;
end
catch
disp('...end 3');
end
close(outputVideo);

reading and displaying video file frame by frame

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

live video with matlab

This code is supposed to take live video draw 2 lines, but when we run the code, the cam will take a live video but the 2 lines appear in different windows.
Can anyone please figure out what's the problem?
clear;
dev_info = imaqhwinfo('winvideo',1);
celldisp(dev_info.SupportedFormats);
vid1 = videoinput('winvideo',1);
%out = imaqhwinfo(vid);
%This is for triggering:
num_frames=5;
triggerconfig(vid1, 'Manual')
set(vid1,'FramesPerTrigger',num_frames)
start(vid1);
trigger(vid1)
%frame = getsnapshot(vid1);
%image(frame);
%here it will acquire 5 frames
%now move the data acquired to the workspace
[data1 time1] = getdata(vid1,num_frames);
kk=length(time1);
elapsed_time = time1(kk) - time1(1);
%frame = getsnapshot(vid1); %this is to get a single frame
for i=1:500
line([27,1523],[1753,1753]);
line([7,1531],[1395,1395]);
preview(vid1);
end
delete(vid1);
clear vid1;
aviobj = avifile('example.avi');
for i=1:kk
F=data1(:,:,:,i);
aviobj = addframe(aviobj,F);
end
aviobj = close(aviobj);
%then we can see the whole video clip
mov = mmreader('example.avi');
%................
%Also, we can directly play the video from the video file
mplay('example.avi');