Image may be NSFW.
Clik here to view.A couple of days ago, I got an email from a reader asking about OpenCV in C#. He was interested in using OpenCV inside a Windows Form Application so that he could add standard form buttons to control the video feed and do other things like saving screenshots from the video feed and processing corner detection. As soon as I started feeling better (I’ve been sick all week), I threw together a starter app to get him going. I now want to share that application with the rest of you as I’m sure others would like to do something similar. So, here goes.
First off, if you haven’t read any of my other OpenCV articles, I would suggest doing that first. Those articles provide some of the basic functions of OpenCV and how to use the OpenCVSharp wrapper with Microsoft Visual C#. Here are those articles:
- OpenCV Edge Detection and Video Capture with C#
- OpenCV Head Tracking with C#
- Record Video with OpenCV and C#
- OpenCV Corner Detection with C#
- OpenCV Eye Tracking with C#
- OpenCV Skin Detector with C#
Alrighty. Now that you have a basic understanding of OpenCV and how to setup C# to work with the library wrapper, it’s time to use that knowledge for adding an OpenCV video feed to a Windows form. The first thing you will need to do is open Microsoft Visual C# and create a new Windows Form Application. Then, you will need to right click on References in the Solution Explorer panel and add references to the OpenCVSharp runtimes. I’ve provided those libraries in the ZIP file at the bottom of this article.
Once you have references to the OpenCV libraries, you will need to add an import reference with the using statement:
using OpenCvSharp;
Since this is a Windows form application, you will need to create a thread which the camera capture code will run in. So, go ahead and add a using statement for:
using System.Threading;
Setting up a thread for your camera capture is extremely important. Since this is a Windows Form Application, if you do not run the camera capture on a separate thread, your form will freeze up, preventing access to your buttons and other form controls. This would defeat the entire purpose of creating a Windows Form Application in the first place.
Back in the designer view, go ahead and add a picture box to your form. We will use this picture box for displaying the video feed from our camera. At this point, you can also go ahead and add any buttons or other form controls if you want. Or, you can wait and add them later. It’s completely up to you.
Now it’s time for some coding. Switch back to your code view and add a global variable for the thread that will run your camera capture. Then, create a void function which you will call to initialize the thread. Before you add any code to this function, create another empty void function which you’ll use as the callback target for your thread start. Back in your initialize thread function, go ahead and instantiate a new thread and pass it a new thread start with the empty thread callback function as its parameter. After that, call the “Start” method on your thread. You can do all of that like this:
private void CaptureCamera() { _cameraThread = new Thread(new ThreadStart(CaptureCameraCallback)); _cameraThread.Start(); }
Inside the empty thread callback function, setup your CvCapture device like you did in the other OpenCV articles above. Next, add a never ending while loop with something like:
while(true)
Don’t worry about this never ending while loop. We’ll take care of that in a minute by adding a start / stop button on our form. In order for us to display the video feed in our picture box, we first need to get it into a format that the picture box can understand. We’ll using a standard Image format to do this. So, inside the while loop, you’ll need to add a new Bitmap object which you’ll build using BitmapConverter.ToBitmap. You’ll need to pass the QueryFrame from your capture device to the “ToBitmap” function. After you’ve built your Bitmap object, it’s a good idea to resize the bitmap using the “SetResolution” function so that your video feed is resized to the same size of your picture box. Otherwise, your video feed will either be too big or too small for your picture box. Now the only thing you have left to add to your while loop is to assign the Image property of your picture box to the bitmap you just built. Here’s what the entire thread callback function should look like:
private void CaptureCameraCallback() { using (CvCapture cap = CvCapture.FromCamera(CaptureDevice.Any, 1)) { while (true) { Bitmap bm = BitmapConverter.ToBitmap(cap.QueryFrame()); bm.SetResolution(pctCvWindow.Width, pctCvWindow.Height); pctCvWindow.Image = bm; } } }
Now that we have a way to handle our camera capture, we need to add a way to tell the capture to begin. You can do this by calling your thread function in the Form Load function, but for this example, we want to add a button to our form which will take care of this for us. So, if you haven’t done it already, add a new button to your form and set its text property to “Start”. Double click the button to auto-create a button handler. Inside this handler, add an if / else check to see if the text of the button is equal to “Start” or not. If it is equal to “Start”, change the text to “Stop” and call the thread function you built earlier. Otherwise, set the text to “Start” and call the Abort function on your actual thread.
private void btnStart_Click(object sender, EventArgs e) { if (btnStart.Text.Equals("Start")) { CaptureCamera(); btnStart.Text = "Stop"; } else { _cameraThread.Abort(); btnStart.Text = "Start"; } }
While you’re at it, you might want to go ahead and add a check to your FormClosing event that checks to see if the thread is not null and “IsAlive”. It it meets this criteria, go ahead and call the “Abort” function on your thread. This will prevent your program from crashing when you close the application and your camera is still being used.
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (_cameraThread != null && _cameraThread.IsAlive) { _cameraThread.Abort(); } }
That’s all there is to it. At this point, you can run your application. When you run it, click the “Start” button. The text of that button should now change to “Stop” and you should see your video feed displayed on your Windows Form. If everything went correctly, you should see something like this:
Image may be NSFW.
Clik here to view.
You’ll notice in the example image above that I also added a button that you can click to save the current screen frame as an image on your file system. If you download the example application below, it already includes the Save Image code. By the way, this was all done using a cheap USB webcam. So, the quality is obviously poor. But, since it is inside a Windows Form, the quality changes as you resize the window. Plus, you can now minimize and maximize the window unlike the other OpenCV examples I’ve shown so far.
As I told the reader that emailed me about this project, feel free to use the example application for whatever you want. All I ask is that you come back here and leave some comments about what you use it for. Your feedback can help others. Plus, I like to keep up with what kinds of cool stuff other programmers work on as it’s inspiring for the rest of us. So, until next time, happy coding!
Download: OpenCV Windows Form Application Example (ZIP 5MB)
Originally posted at http://www.prodigyproductionsllc.com/articles/programming/use-opencv-in-a-windows-form-application-in-c/