8

The Project: Add a running date/time stamp on each and every frame of a video. (The result of digital video camera, and my father asked me how can he add the timestamp(to the milliseconds resolution) permanently to the video.

A friend pointed me to opencv (emgucv actually) , and because of my preferences I tried my luck with opencv in python.

The documentation is lame, and I had even hard time(took me like 5 hours or so) just to install the package. Sources:

I am working on Windows 7 x64 , so I had to downgrade my python to work with numpy(no numpy version for win64)

Working with PyCharm IDE.

The resulting installation got me to have the file C:\Python27\Lib\site-packages\cv2.pyd

I am trying to find documentation to start working with, but I am very confused and have no clue where to start from, all the examples are confusing - ie:

My Questions:

  1. Am i doing something wrong? Is this not the way to install opencv?
  2. Where can i find good documentation?
  3. Suppose i have my text ready(in a string) can somebody try to help me with a start to my application?

Thanks

Community
  • 1
  • 1
Yoav R.
  • 531
  • 1
  • 3
  • 15
  • 1
    Look into [SimpleCV](http://simplecv.org/docs/) as as a possible alternative. – Blender Sep 05 '12 at 21:28
  • I will try it, but i already overviewed their website and it looks like there is too little documentation. and i don't really understand the thing with the interactive shell(do i need to work with that? can i work only through a python script?) – Yoav R. Sep 05 '12 at 21:43
  • I don't use the interactive shell. The documentation is just there to show you that functions exist, but the rest of the functionality is pretty self-explanatory. – Blender Sep 05 '12 at 21:44
  • ahhhh. the simple cv installation pack installed it self incorrectly( some packages in my 2.7.2 and some in the new 2.7.3 python library) – Yoav R. Sep 06 '12 at 05:45

2 Answers2

18

Your task should be relatively easy to accomplish using OpenCV and Python. It seems that you are new to OpenCV, so I will try and keep my explanation thorough, but feel free to ask if you need any clarity.

I am not sure if you are getting your data from a live camera video feed, or are post-processing recorded footage. Either way...

Get data. If using a live feed:

capture = cv2.VideoCapture(0)

If using recorded footage:

capture = cv2.VideoCapture("your_reading_file.avi")

Initialise video writer. Look at this question for help with codecs- finding a working codec is not trivial. I am also using Windows 7 x64, and the below-mentioned codec was the only one that worked for me. Also, set the variable fps as close to the actual incoming video framerate as possible- you can not change it once you have started writing frames.

flag, frame = capture.read() # **EDIT:** to get frame size
width = np.size(frame, 1) #here is why you need numpy!  (remember to "import numpy as np")
height = np.size(frame, 0)
writer = cv2.VideoWriter(filename="your_writing_file.avi", 
fourcc=cv2.cv.CV_FOURCC('I', 'Y', 'U', 'V'), #this is the codec that works for me
fps=15, #frames per second, I suggest 15 as a rough initial estimate
frameSize=(width, height))

Process this data and add your text. Lastly, write the edited frame to a video file.

while True:
    flag, frame = capture.read() #Flag returns 1 for success, 0 for failure. Frame is the currently processed frame

    if flag == 0: #Something is wrong with your data, or the end of the video file was reached
        break 
    x = width/2
    y = height/2 #change to the desired coordinates
    text_color = (255,0,0) #color as (B,G,R)
    cv2.putText(frame, "your_string", (x,y), cv2.FONT_HERSHEY_PLAIN, 1.0, text_color, thickness=1, lineType=cv2.CV_AA)

    writer.write(frame) #write to the video file

As simple as that! I use the above code to write text to video files almost daily, so it definitely works. The only potential problems I can foresee are with the codecs, which I unfortunately do not know a lot about. I hope that this may solve your problem, feel free to ask more questions.

EDIT: Answers to your comment's questions.

1.) As far as I know, you can only use .avi because you have to use an uncompressed format with OpenCV. I am afraid I have no knowledge of using other (compressed) formats. Maybe you could use a third-party program to do pre/post-conversion? The reason for the frame exception was my mistake, I have edited the answer to include the missing line.

2.) I'm afraid I have no idea how to read metadata. If I find out I will let you know. My own hackish solution for finding video framerate is to let OpenCV run through the video once, using the Time module to calculate the average framerate. This estimate can then be used when writing the video file.

3.) I have found that the size of the resulting video may differ significantly from the original depending on several factors, the most important being how close the chosen fps was to the actual original framerate.

4.) As for other fonts, there are several available. I can refer you to this question for a quick overview. Here is the relevant documentation:

fontFace – Font type. One of FONT_HERSHEY_SIMPLEX, 
FONT_HERSHEY_PLAIN, 
FONT_HERSHEY_DUPLEX, 
FONT_HERSHEY_COMPLEX, 
FONT_HERSHEY_TRIPLEX, 
FONT_HERSHEY_COMPLEX_SMALL, 
FONT_HERSHEY_SCRIPT_SIMPLEX, or 
FONT_HERSHEY_SCRIPT_COMPLEX, 
where each of the font ID’s can be combined with FONT_HERSHEY_ITALIC to get the slanted letters.
Community
  • 1
  • 1
hjweide
  • 11,893
  • 9
  • 45
  • 49
  • Great! This is very close to what i need. some questions: 1. why only AVI Files are able to be opened?(throws exception when i try to read the frame's width/height), 2. How can i read meta data of the file (and to be exact - time/date of creation, and FPS) 3. why the resulting video is 3 or 4 times larger(space, not frame of course), 4. what more fonts, styles do i have for the font? – Yoav R. Sep 08 '12 at 22:11
  • I have edited my answer to include some of your new questions. Please also note that there was a mistake in my original code, but that it has now been fixed. Please ask if anything is still unclear! – hjweide Sep 09 '12 at 09:38
  • Hey, can you help me?, i don't understand what happend to the audio of the video – Yoav R. Sep 11 '12 at 08:35
  • This approach does not include the audio, as we are only writing the video's frame to the new file after adding the text. It might be possible to extract the audio from the original video using third-party software and then add it to the new video file. However, this would fail if the frame rates were different as it would cause the audio to be unsynchronised. [This question](http://stackoverflow.com/questions/8187745/audio-output-with-video-processing-with-opencv) shows how it can be done, but I am afraid it is in C++. Maybe you could port it? – hjweide Sep 11 '12 at 09:01
  • 1
    Heads up unless you also have 'import cv2.cv as cv' the codec is loaded as 'fourcc=cv2.cv.CV_FOURCC('i','Y', 'U', 'V')' – Jon Oct 29 '13 at 20:04
  • In your `cv.putText()` you have non-keyword arguments after a keyword argument. Also although iYUV produced a file for me, it does not play in VLC so it is probably not the best choice! Edit: Because it should be IYUV not iYUV. – Timmmm Dec 04 '13 at 11:49
  • You can also use MJPEG as the fourcc. It works on Windows 7 and will produce *much* smaller files than YUV. Unfortunately there does not seem to be a way to control the quality and the default is on the low side. – Timmmm Dec 04 '13 at 12:23
  • @Timmmm I can play the files using VLC without any problems. – hjweide Dec 04 '13 at 12:24
  • @casper This will add a time stamp to the file that is being saved which I can later access? – praxmon Mar 13 '14 at 11:15
  • @PrakharMohanSrivastava As far as I know, no it will not. I'm afraid I do not know how to add a timestamp to the video file. – hjweide Mar 13 '14 at 15:15
1

Used hachoir-metadata to read metadata of video file(including Framerate, height and width .

importing:

from hachoir_core.error import HachoirError
from hachoir_core.cmd_line import unicodeFilename
from hachoir_parser import createParser
from hachoir_core.tools import makePrintable
from hachoir_metadata import extractMetadata
from hachoir_core.i18n import getTerminalCharset
from hachoir_metadata.metadata_item import QUALITY_BEST

function:

def metaDataFile(filePath):
    filename, realname = unicodeFilename(filePath), filePath
    parser = createParser(filename, realname)
    try:
        metadata = extractMetadata(parser, QUALITY_BEST)
    except HachoirError, err:
        print "Metadata extraction error: %s" % unicode(err)
        metadata = None
    if not metadata:
        print metadata
        print "Unable to extract metadata"
        exit(1)
    return metadata

usage:

metadata = metaDataFile(videoPath)
width = metadata.get('width')
height = metadata.get('height')
fps = metadata.get('frame_rate')

to see relevant properties:

for data in sorted(metadata):
    if len(data.values ) > 0:
        print data.key, data.values[0].value
David Planella
  • 2,313
  • 2
  • 25
  • 30
Yoav R.
  • 531
  • 1
  • 3
  • 15