Cross-compiling OpenCV for embedded linux

I have compiled OpenCV many times now, since for one reason or another each time I needed to use it the previously compiled files would be lost. This was in addition done directly on the platform, which meant having the board running for 8-10 hours building everything, and not at all fun having to redo, for example for getting locked out of the board by a poor wifi AP configuration and having to re-flash the memory!

So I finally decided to do the sensible thing and cross-compile it, which means using the much higher processing power of my laptop to build the files, but for the target board’s architecture, significantly reducing the time needed (kind of like sending something to the cloud to be processed, but locally). The official OpenCV guide covers the basics, but is oriented to C++, since the files needed for Python development are not generated.

This  meant that I simply would have to link to the Python libs and compile it. I merged the cross-compiler-specific instructions with the regular method I’ve followed other times and… it predictably failed. It turned out that I was trying to build OpenCV for an armhf architecture while linking it to Python libs from my native (and incompatible) x86_64, which of course meant that nothing worked.

After much trial and error I found that I had to link to the correct architecture files, and the best way to do so was copying them from the target board before  the compilation. The full procedure would then look something like this:

  1. Install any missing packages needed and download OpenCV
  2. Copy the required files from the target board
  3. Cross-compile OpenCV
  4. Send the compiled library to the target board

Each stage is completed by a different script, which takes care of intermediate steps such as creating directories as well. There is also a configuration file where the board’s username, IP address and type are specified, and optionally the password too. The board type is arm-linux-gnueabihf for an armhf architecture and x86_64-linux-gnu for x86_64, there will probably be a folder under /usr/include/ with the correct name for other architectures. If the password field is filled, that is what will be used to transfer the files, if left empty the user must manually enter it each time.

The configuration file:

Step 1, installing packages and downloading OpenCV:

Step 2, copying files from the board:

Step 3, cross-compiling:

Step 4, sending compiled files to the target board:

I also wrote a small script that calls all the previous ones sequentially so everything can be done in one go:

To launch this, make sure that the board and computer are both connected to the Internet and on the same network, and execute

chmod +x && ./

Once the installation folder containing the compiled library has been transferred to the board, log into it and execute

sudo rsync -av installation/ /usr/local

to copy the different files to the corresponding places.

If when trying to import cv2 there is an error about not finding the corresponding GLIBXX version in the board as the one used to compile, try upgrading g++ to the appropiate version. For example, for GLIBCXX_3.4.22 execute

sudo apt upgrade g++-6

The complete process will vary depending on processing speed, Internet connection and packages already present, but in my case took just under 30 minutes from launching the script to receiving the folder in the board.


Leave a Reply

Your email address will not be published. Required fields are marked *