Cross-compiling OpenCV 3 for Raspberry Pi 2

This tutorial shows how to cross-compile the OpenCV library for Raspberry Pi to allow stepping through its source code and searching through it using Find-All-References and Code Map.

Before you begin, download the Raspberry Pi Jessie image and write it to the SD card. Then get a cross-toolchain compatible with the image from the website. Then download the source code of OpenCV for Linux to your Windows machine and unpack it.

  1. Start Visual Studio and select File->New->Project. Then pick the VisualGDB Linux Project Wizard:01-newprj
  2. Select “Import a project -> Import a CMake project”:02-importcmake
  3. Select “Build the project locally with a cross-compiler” and choose your Raspberry Pi board in the “Deployment computer” field:03-build
  4. Specify the directory where you have unpacked the OpenCV source code, provide the path to CMake on your Windows machine and set the build subdirectories for debug and release builds as shown below:04-importcvAfter entering the paths, press “Finish” to generate the OpenCV project for Visual Studio.
  5. If we build OpenCV now, it will not recognize the GTK+ library and the window-related API will not work. To ensure OpenCV builds with GTK+ support, first download pkg-config-lite for Windows and extract the pkg-config.exe executable into the <sysgcc>\Raspberry\bin directory:pkg-config
  6. Ensure that your Raspberry Pi has the GTK+ headers and libraries installed by running “sudo apt-get install libgtk2.0-dev” over SSH. Then open VisualGDB Project Properties for the recently created project, and resynchronize the toolchain sysroot to ensure that all headers and libraries end are copied to the Windows machine. Ensure that you include the /usr/share/pkgconfig and /opt/vc directories:07-sync
  7. Before you can start the build, you need to set the environment variables so that pkg-config knows how to find the information about the packages. Set the following environment variables for the CMake command:

    Replace “C:\SysGCC\Raspberry” with your toolchain directory and do not forget to replace the backward slashes (‘\’) with forward slashes (‘/’):05-pkgconfig
  8. Now you can press Ctrl-Shift-B to build OpenCV using the cross-compiler. As soon as the configuration tests are complete and the actual build starts, search the build output for “gtk” to verify that GTK has been recognized:06-gtk+If GTK is not found, try running the “pkg-config –exists gtk+-2.0 –print-errors && echo found” command manually after setting PKG_CONFIG_SYSROOT and PKG_CONFIG_PATH accordingly and check its output for errors.
  9. Wait until the OpenCV build completes. The library is relatively big, so the build may take 15 minutes or more:05-build
  10. Open command prompt in the OpenCV build directory and run the following commands:

    Replace C:\SysGCC\Raspberry with the actual directory where you have installed your Raspberry Pi cross-toolchain.16-inst
  11. Then start SmarTTY, connect to your Raspberry Pi as root (you can set the root password by connecting as ‘pi’ and running ‘sudo passwd’) and upload the install folder to the root directory:17-upload
  12. Now we will create a new project based on an OpenCV sample called findContours_demo. Right-click in Solution Explorer and select “Add->New->Project”:06-new
  13. Select “Linux Project Wizard”:07-cvdemo
  14. Select “Create a new project->Use CMake”:08-app
  15. Select “Build the project locally” and ensure that Raspberry Pi is still selected:09-rasp
  16. Click the “configure CMake settings” link and specify the path to the cmake.exe executable on your Windows machine:10-config
  17. Press “Finish” to create the project. Replace the contents of the main .cpp file with the contents of <OpenCV folder>\samples\cpp\tutorial_code\ShapeDescriptors\findContours_demo.cpp:10b-srcfile
  18. Add the following lines after the project() line in your project’s CMakeLists.txt:

    Then add ${OpenCV_LIBS} to target_link_libraries():

  19. If you try building your project now, you will get an error message showing that the OpenCV library has not been found:11-cvref
  20. This is fixed by specifying the build directory of the OpenCV project in the CMAKE_PREFIX_PATH environment variable for CMake:12-prefixpathWarning: do not confuse the VisualGDB Project Properties for the demo project and for the OpenCV library itself. Use right-click in Solution Explorer to open the correct properties window.
  21. Now you should be able to build your project:13-buildok
  22. The last step before testing out our application would be to fix the IntelliSense problems. OpenCV uses custom macros to define header and library paths, so VisualGDB cannot automatically detect them unless you configure it to query them from CMake explicitly. Open VisualGDB Project Properties for the demo project and enable the corresponding checkbox:14-dumpflags
  23. Rebuild the project (no need to rebuild the entire solution). The IntelliSense errors should disappear and the functions like code completion or function hints should start working:15-sense
  24. You should also be able to use the C++ Code Map provided by the Clang IntelliSense engine to visualize relations between various OpenCV components:codemap
  25. Now we will run the demo program and step through it. The demo opens an image specified via command line and tries to detect contours on it. To show the program, we will use the Lena image from <OpenCV>\samples\wp8\OpenCVXaml\OpenCVXaml\Assets\Lena.png. First of all, upload it to your Raspberry Pi using SmarTTY:18-lena
  26. Then specify the path to the image in the command-line arguments of your application:18-args
  27. Normally you would need to resynchronize the sysroot again after each build/installation of OpenCV to ensure that the recently installed libraries can be found by the GDB running on Windows, but you can alternatively specify the <OpenCV build directory>/build/debug/lib as the GDB library path by adding the set solib-search-path command to GDB startup commands:18a-searchpath
  28. Finally, hit F5 to start debugging. You should see 2 OpenCV windows redirected from your Raspberry Pi: one with the original image and one with the detected contours:19-run
  29. Set a breakpoint inside the thresh_callback() function and move the slider in the left window. The breakpoint will get hit:20-bkpt
  30. If you step into the Canny() function directly, GDB will first step into several implicit constructors called from the same line. To avoid this, you can click on Canny, press F12 to open its definition and then set a breakpoint inside it:21-func