As you will see the video processing is almost the same as image processing. The only critical thing is that we have to deal with a lot of image in row so the processing should be optimised not to slow down the video stream. Basically there are two possible sources of video either a video file either a webcam. What we are interested in this section is reading video file (which is harder than a webcam) and writing a video.
a. Read a video
To read a video you have to retrieve the Capture object from the CaptureFromFile function. From this object you can get the width the height of the video and the number of frame by second(FPS). the number of FPS allow to calculate the time to wait between each frame to show.
importcv2.cvascvcapture=cv.CaptureFromFile('myvideo.avi')nbFrames=int(cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_COUNT))#CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream#CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video streamfps=cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FPS)wait=int(1/fps*1000/1)duration=(nbFrames*fps)/1000print'Num. Frames = ',nbFramesprint'Frame Rate = ',fps,'fps'print'Duration = ',duration,'sec'forfinxrange(nbFrames):frameImg=cv.QueryFrame(capture)printcv.GetCaptureProperty(capture,cv.CV_CAP_PROP_POS_FRAMES)cv.ShowImage("The Video",frameImg)cv.WaitKey(wait)
To show the webcam stream you just have to call the CaptureFromCAM which take the camera number in argument and return the capture object from which you can query image indefinitely. The following example is straightforward:
importcv2.cvascvcapture=cv.CaptureFromCAM(0)whileTrue:frame=cv.QueryFrame(capture)cv.ShowImage("Webcam",frame)c=cv.WaitKey(1)ifc==27:#Esc on Windowsbreak
c. Write a Video
To write a video to a file you can either take the webcam as a source or another video as source. In order to do it, you have to call the CreateVideoWriter function with the ouptput filename, the fourcc code of the format of the video. The problem is you have to provide the number of fps to the video writer and (of what I know) there is nowhere to get it. If you put an arbitrary value once recorded the video will play faster or slower than the real time. If you know any way to get it feel free to tell me. But to solve this small problem I have written a small script that calculate the elapsed time between to frames, calculate an average and just deduct the number of frames per second from it.
importcv2.cvascvfromtimeimporttimecapture=cv.CaptureFromCAM(0)temp=cv.QueryFrame(capture)startat=10sum=0count=0t1=time()t2=0whilecount<30:printcountimage=cv.QueryFrame(capture)t2=time()val=t2-t1printval#I ignore the ten first frames because tests shows that the elapsed time value is anormaly too lowifcount>startat:sum+=val#Add the current valueprint"Avg: ",sum/(count-startat)#Compute the temp averaget1=t2count+=1avg=1/(sum/(count-startat))fps=cv.Round(avg)printfps,"fps"
Now that we have the FPS of our webcam we can create the VideoWriter and start recording. The example below show how to record images from the webcam. For the test I just record 50 frames. So with 5 fps the video should last 10 seconds. Note that with my webcam and this encoding this small samples of 10 seconds weigh nevertheless 45 Mo.
importcv2.cvascvcapture=cv.CaptureFromCAM(0)temp=cv.QueryFrame(capture)writer=cv.CreateVideoWriter("output.avi",cv.CV_FOURCC("D","I","B"," "),5,cv.GetSize(temp),1)#On linux I used to take "M","J","P","G" as fourcccount=0whilecount<50:printcountimage=cv.QueryFrame(capture)cv.WriteFrame(writer,image)cv.ShowImage('Image_Window',image)cv.WaitKey(1)count+=1
Finally let’s try to read a video from file and re-write it to another file. The main difference with webcam recording is that we can get in meta-data the encoding o the video the fps the width and height of the video and the number of frames that allow use to calculate the duration. So we will retrieve all these informations and configure our VideoWriter with the sames parameters. Note that in this example we just re-write in the new file the first 80 frames.
importcv2.cvascvcapture=cv.CaptureFromFile('img/mic.avi')nbFrames=int(cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_COUNT))width=int(cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH))height=int(cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT))fps=cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FPS)codec=cv.GetCaptureProperty(capture,cv.CV_CAP_PROP_FOURCC)wait=int(1/fps*1000/1)#Compute the time to wait between each frame queryduration=(nbFrames*fps)/1000#Compute durationprint'Num. Frames = ',nbFramesprint'Frame Rate = ',fps,'fps'writer=cv.CreateVideoWriter("img/new.avi",int(codec),int(fps),(width,height),1)#Create writer with same parameterscv.SetCaptureProperty(capture,cv.CV_CAP_PROP_POS_FRAMES,80)#Set the number of framesforfinxrange(nbFrames-80):#Just recorded the 80 first frames of the videoframe=cv.QueryFrame(capture)printcv.GetCaptureProperty(capture,cv.CV_CAP_PROP_POS_FRAMES)cv.WriteFrame(writer,frame)cv.WaitKey(wait)