Chapter 7: Video I/O and Sources

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import cv2.cv as cv

capture = 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 stream

fps = cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FPS)

wait = int(1/fps * 1000/1)

duration = (nbFrames * fps) / 1000

print 'Num. Frames = ', nbFrames
print 'Frame Rate = ', fps, 'fps'
print 'Duration = ', duration, 'sec'

for f in xrange( nbFrames ):

    frameImg = cv.QueryFrame(capture)

    print cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_POS_FRAMES)

    cv.ShowImage("The Video", frameImg)
    cv.WaitKey(wait)

b. Webcam

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:

1
2
3
4
5
6
7
8
9
10
import cv2.cv as cv

capture = cv.CaptureFromCAM(0)

while True:
    frame = cv.QueryFrame(capture)
    cv.ShowImage("Webcam", frame)
    c = cv.WaitKey(1)
    if c == 27: #Esc on Windows
        break

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import cv2.cv as cv
from time import time

capture=cv.CaptureFromCAM(0)
temp=cv.QueryFrame(capture)

startat=10
sum = 0
count=0

t1= time()
t2 = 0

while count<30:
    print count
    image=cv.QueryFrame(capture)
    t2 = time()
    val = t2 - t1
    print val
    #I ignore the ten first frames because tests shows that the elapsed time value is anormaly too low
    if count > startat:
        sum += val #Add the current value
        print "Avg: ", sum / (count - startat) #Compute the temp average
    t1 = t2
    count+=1

avg = 1/ (sum / (count - startat))
fps = cv.Round(avg)

print fps, "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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import cv2.cv as cv

capture=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 fourcc

count=0
while count<50:
    print count
    image=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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import cv2.cv as cv
capture = 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 query

duration = (nbFrames * fps) / 1000 #Compute duration

print 'Num. Frames = ', nbFrames
print 'Frame Rate = ', fps, 'fps'

writer=cv.CreateVideoWriter("img/new.avi", int(codec), int(fps), (width,height), 1) #Create writer with same parameters

cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_POS_FRAMES,80) #Set the number of frames

for f in xrange( nbFrames - 80 ): #Just recorded the 80 first frames of the video

    frame = cv.QueryFrame(capture)

    print cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_POS_FRAMES)

    cv.WriteFrame(writer, frame)

    cv.WaitKey(wait)

<<Object Detection | Home | Operations On Videos>>