In this sample, we will build the OpenCV library for Windows and add it to a UWP C++ app, which will run facial and body recognition on a photo.
The sample code is available to download, but as an exercise, we will create this app from scratch.
Even if you download the sample, code, you’ll need to follow the steps in Compile the OpenCV Libraries and Add the Libraries to your Project below.
Make sure your device is running and set up and you have Visual Studio installed. See our guide if you have not set up your device yet.
You will need your device’s IP address when connecting to it remotely.
Make sure you have the C++ components for Visual Studio. To check, open the Start Menu, type in Visual Studio Installer and hit enter. Once the Visual Studio Installer opens, click Modify under your installed version of Visual Studio. Check to make sure you have the below components selected. If not, select them and update your installation.
Create a new project with (File | New Project…).
In the New Project dialog, navigate to Universal as shown below (in the left pane in the dialog: Templates | Visual C++ | Windows | Universal).
Select the template Blank App (Windows Universal).
Note that we call the app OpenCVExample. You can name it something different, but you will have to adjust sample code that references OpenCVExample as well.
If this is the first project you create, Visual Studio will likely prompt you to enable developer mode for Windows 10.
Download the Microsoft fork of OpenCV from GitHub
Download Microsoft’s fork of the OpenCV library from GitHub. Unzip it to a place you can remember it, and copy the folder’s path (i.e. C:/path/to/opencv/) for the next step.
Create the OpenCV environment variable
Open the Start Menu and enter Edit the system environment variables and hit Enter. On the next screen, press Environment Variables, then New. Create a new variable called OCV2015_ROOT with a value of the path you copied, i.e. C:/path/to/opencv/
Build the solution
This step depends on your device’s architecture. Follow one of the options below:
x86 (i.e. Your machine or Minnowboard Max)
Open the file explorer and navigate to the following path: “%OCV2015_ROOT%\vs2015\WS\10.0\x86", then open OpenCV.sln in Visual Studio.
On the top of the screen, next to the green Run button, select Release instead of Debug and Win32 instead of ARM or x64.
ARM (i.e. Raspberry Pi)
Open the file explorer and navigate to the following path: “%OCV2015_ROOT%\vs2015\WS\10.0\ARM", then open OpenCV.sln in Visual Studio.
On the top of the screen, next to the green Run button, select Release instead of Debug and ARM instead of x86 or x64.
Open the file explorer and navigate to the following path: “%OCV2015_ROOT%\vs2015\WS\10.0\x64", then open OpenCV.sln in Visual Studio.
On the top of the screen, next to the green Run button, select Release instead of Debug and x64 instead of x86 or ARM.
Press Ctrl+Shift+B to Build the solution. Alternatively, press Build | Build Solution. These results should compile without errors. You will have to re-build this project for each platform (x86, x64, or ARM) and release type (Debug or Release) that you want to use.
Add the DLLs directly
Return to your project’s Visual Studio window. Right click on the project in the window and navigate to Add | Existing Items
x86: In the new window, navigate to %OCV2015_ROOT%\vs2015\WS\10.0\x86\bin\Release
ARM: In the new window, navigate to %OCV2015_ROOT%\vs2015\WS\10.0\ARM\bin\Release
x64: In the new window, navigate to %OCV2015_ROOT%\vs2015\WS\10.0\x64\bin\Release
Add the following files: opencv_core300.dll, open_imgcodecs300.dll, opencv_imgproc300.dll, opencv_ml300.dll, opencv_objdetect300.dll
After adding the files, click on each one in the Solution Explorer and make Content = “True”
Modify you General Properties
Right click on the OpenCVExample (Universal Windows) line of the Solution Explorer and click on Properties.
In the dialog that pops up, navigate to Configuration Properties | C / C++ | General. From there, add the following to the Additional Include Directories field before the already-present contents:
%OCV2015_ROOT%\modules\core\include;%OCV2015_ROOT%\modules\imgproc\include;%OCV2015_ROOT%\modules\imgcodecs\include; %OCV2015_ROOT%\modules\objdetect\include;%OCV2015_ROOT%\modules\hal\include;%OCV2015_ROOT%\modules\highgui\include; %OCV2015_ROOT%\modules\ml\include;
For each new DLL you want to add, you need to add the appropriate “include” directory to this field.
Modify your Linker Properties
In the Properties window still, navigate to Linker | General, then add the following to the Additional Library Directories field:
Switch the menu to Input (still within Linker) and add the following to the Additional Dependencies field:
For each new DLL you want to add, add the appropriate LIB in this field as well.
Open MainPage.xaml and replace the existing code with the following code to create the window UI:
To view the entire UI, change the dropdown in the top left corner from ‘5” Phone’ to ‘12” Tablet’.
Open MainPage.xaml.h. Replace the contents with the following code:
The header file stablishes the functions we’re going to declar in the main .cpp file, as well as a private variable (_stored_image) which stores the content of the storedImage XAML Image element once we upload it.
Add the following header files to the top of your code, right after the #include “MainPage.xaml.h” line:
These lines allow us to use OpenCV library functions, along with some necessary default classes as well. We also define the locations of the features classifiers we’ll use later.
Add the following function right after the MainPage Constructor
This function changes the image contained in the “storedImage” XAML Image element to the contents of the “image” argument.
Add the following function right after the UpdateImage function
This function opens an image and uploads a default image to the StoredImage UI element.
Add the following function right after the last handler:
This function applies Canny Edge detection to the image and updates the image container with the results.
Add the following lines and function right after the last handler:
This function uses cascade classification to classify and detect bodies and faces in a video stream (or image) using two Haar classifiers, face_cascade and body_cascade, stored in the xml files we provided for you. It’s a method of classification involving machine learning, as explained on OpenCV’s website.
Add the following lines and function right after the last helper function:
This function loads the classifiers, re-reads the image (the classification doesn’t work on a Canny image in case the user clicked that button first), finds the faces and bodies using the helper function from the last step, and draws rectangles around the results: red for the faces, black for the bodies. It then pushes the updated image to the container.
If you’ve built the x86 version of OpenCV, you can test the program on your local machine. Make sure the app builds correctly by invoking the Build | Build Solution menu command.
Press F5 to run the program on your machine.
Press the “Test Image” button to see the test image.
Press the “Canny” button to see the Canny edges on the test image.
Press the “Detect” button to see the detected faces and bodies in the image indicated by rectangles.
Close the app once you’re done validating its correct operation.
Click on the dropdown next to the Local Machine label and click on Remote Machine. Make sure the dropdown just to the left says your device’s architecture, either x86, x64, or ARM. The Remote Machine click should open a dialog. Enter your device’s IP address (or unique name) into the field labeled Address, then press Select.
If the dialog does not appear, right click on your project and go to the Properties menu. From there, click on Debugging. Clicking on Machine Name and then Locate should provide the same dialog to enter the device’s IP address.
Make sure the device is powered on, then click the “Run” button. The app should run on your device.
Congratulations! Your app should now be working!