Record Video with OpenCV and C#

Categories: C#, Computer Vision, OpenCV, Programming, Software Development

OpenCV LogoIn yesterday’s article, I showed you how to do eye tracking with OpenCV and C#. In that article, I mentioned that you can also save your video feed to a stream and write it to a file. So, it’s time for me to show you how to do that exactly. Plus, at the same time, I’m going to show you how to draw text on top of your video feed. In the example, I’m going to simply draw the frames per second (FPS) on top of the video feed and record the entire video stream to a file. If you haven’t read my articles for “OpenCV Eye Tracking with C#” and “OpenCV Edge Detection and Video Capture with C#“, you need to go read those first as this article will be built off of those articles. It will only take you a few minutes to read both of those and at the end, you should have a basic idea of how OpenCV works and how to talk to your standard USB webcam with OpenCV and C#. Besides, in order to use the example in this article, you will need to download the OpenCV wrappers for C# which I’ve included in a ZIP file in the article “OpenCV Edge Detection and Video Capture with C#“.

Just like our OpenCV articles before, we will begin by building a CvCapture that we will use to communicate with our camera. We will also need to construct a new CvWindow in which we will display the video feed as it is received from the CvCapture. In the example below, you will notice that before I build my CvCapture or CvWindow, I have declared a variable called “fps” and gave it a value of 30. I went with 30 since standard televisions run at 30 frames per second. We will be using this variable to tell our video writer how many frames per second to record our video in. So, if your computer seems to be running fairly slow with this example, you can also lower the “fps” variable to speed things up a bit. However, you should keep in mind that the lower the number you set for frames per second, the more “choppy” your recorded video will appear.

After you’ve built your CvCapture and CvWindow, it’s time to introduce a new object called the “CvVideoWriter”. This is the object that will be writing our video feed to a file. As you can see in the example, the CvVideoWriter takes 4 parameters. The first parameter is simply the name of the file you want to write your video stream to. I called mine “cap.avi” since I’ll be using an AVI codec for my video encoding format. You can learn more about video codecs over at the Wikipedia – Codec page found here. The second parameter that the CvVideoWriter needs is the codec itself. The FourCC object gives us plenty of codecs to choose from, but I preferred setting my codec as “FourCC.Prompt” so that every time I run the program, I will be prompted to select which codec I want to use. This allows me the opportunity to test with different codes without having to make any code changes. Plus, this also allows me to run this program on other computers that might not have the same codecs installed that I have installed on my computer.

The third parameter that is required my the CvVideoWriter constructor is the frames per second. This is where we will pass the “fps” variable we declared at the beginning of the app. This parameter is what tells the CvVideoWriter how many frames per second it should write the video file as. The last parameter that is required by the CvVideoWriter constructor is the video frame size. You can choose to hard code a size for your video to be saved as or you can do like I did and simply grab the width and height from our capture device (CvCapture) and pass it to a new CvSize object.

If you’re planning on writing text on top of your video feed like I am in the example below, you’re going to need to instantiate a new font to use. You can do this by using the CvFont object. The CvFont takes 3 parameters. The first parameter is the font face. You can pick from several different font faces with use of the FontFace object. The second and third parameters that are required by the CvFont constructor are for horizontal scale and vertical scale. These variables are what tell the CvFont how big or small to be.

After you’ve setup your objects for CvCapture, CvWindow, CvVideoWriter, and CvFont, it’s now time to use them. Just like in my last 2 articles, you will need to create a while loop that will listen for key input and not close until it has received input from the user. Inside the while loop, you will need to create a temporary frame that you will use to write your text to and finally write that image to your video file using the CvVideoWriter you built earlier. Once you have your temporary IplImage frame, you can write text to it using the PutText method from IplImage. The PutText method accepts 4 parameters. The first parameter is the text that you want to overlay on your video. The second parameter is the location that you want the text to appear on the video. The third parameter is the font you built earlier. And finally, the fourth parameter is the color you want the text to appear in.

The last things you have to do to make this example work is to write each frame to your video file and then display those frames in your CvWindow. You can pass each frame to your writer with the WriteFrame method. And, as always, you can display your video feed in your CvWindow using the ShowImage method and passing it the frame that contains the text overlay.

And that’s all folks! You now have yourself a working video capture & recording application using OpenCV and C#. If you did everything correctly, you should be presented with a prompt asking for your codec of choice when you run the application. Once you run the app and pick your codec, you should see the text you picked on top of your video image and you should find a new video file in the same directory that your application is located. Here is the complete code that I used for testing.

using System;
using OpenCvSharp;

namespace EdgeDetect
{
    class WriteVideo
    {
        public WriteVideo()
        {
            int fps = 30;

            using (CvCapture cap = CvCapture.FromCamera(2)) // device type + camera index
            using (CvWindow w = new CvWindow("OpenCV Example"))
            using (CvVideoWriter writer = new CvVideoWriter("cap.avi", FourCC.Prompt, fps, new CvSize(cap.FrameWidth, cap.FrameHeight)))
            using (CvFont font = new CvFont(FontFace.HersheyComplex, 0.7, 0.7))
            {
                int i = 0;
                while (CvWindow.WaitKey(10) < 0)
                {
                    using (IplImage src = cap.QueryFrame())
                    {
                        IplImage frame = cap.QueryFrame();
                        string str = string.Format("{0}[frame]", i);
                        frame.PutText(str, new CvPoint(10, 20), font, new CvColor(0, 255, 100));
                        writer.WriteFrame(frame);
                        w.ShowImage(frame);
                    }
                    i++;
                }
            }
        }
    }
}

Originally posted at http://www.prodigyproductionsllc.com/articles/programming/record-video-with-opencv-and-c/