UNIX / Linux keyboard.

How to Compile OpenCV on OpenBSD

Image Processing with OpenCV

The OpenCV (Open Computer Vision) package is great! It lets you very quickly develop code for dealing with arbitrary image file formats. I got my global and localized histogram equalization algorithms working on JPEG images in about half a day, much of that time taken up by my rustiness at C/C++ programming....

You can very easily add it to Linux by adding a YUM repository definition for the Dag Apt Repository. Then you can simply do this:

# yum install opencv opencv-devel 

However, OpenCV hasn't been included in the OpenBSD packages collection, and building it from source wasn't as obvious as I had hoped.

First, though, learn about and get the source code for OpenCV. Gady's Agam's "Introduction to Programming with OpenCV" document is excellent, it's all I needed to accomplish what I wanted as far as programming goes. The only other thing I needed was to figure out how to compile the libraries on OpenBSD! I found that document by simply asking Google this question:
opencv tutorial

The OpenCV site has the main documentation collection.


Amazon
ASIN: 0596516134

Amazon
ASIN: 1849513244

Build and Install OpenCV Libraries Through the OpenBSD Ports System

Use the Ports system! If you really want to see them, I have historical notes below on how to fight through manual compilation.

Install the Ports Tree

Change the release number as needed:

% cd /tmp
% ftp http://ftp.openbsd.org/pub/OpenBSD/5.7/ports.tar.gz
% ftp http://ftp.openbsd.org/pub/OpenBSD/5.7/SHA256.sig
% signify -C -p /etc/signify/openbsd-57-base.pub -x SHA256.sig ports.tar.gz
% cd /usr
% sudo tar xzf /tmp/ports.tar.gz 

Build and Install the OpenCV Libraries

% su
# cd /usr/ports/graphics/opencv
# pkg_info opencv 

If that last commands shows that you already built and installed an earlier version of OpenCV, then do this as an update:

# make update 

If this is the initial build of OpenCV on this system, do it as an installation:

# make install 

Whether this is the initial build or an update, there will be a lot of output as the ports system downloads source code for the desired package plus any dependencies, builds OpenCV and its dependencies as package files under /usr/ports/packages/, and installs them.

On the same system where a kernel build takes almost 6 minutes, this took 68 minutes to run!

Clean up when the build completes:

# make clean 

Build OpenCV Software

You are now ready to compile OpenCV code, if you know how to go about it. Based on what I had seen while doing the initial development on Linux, I thought that I could put something like the following in ~/src/Makefile to build binaries in ~/bin/bsd/.

CFLAGS = -O3 -Wall -pedantic
TARGET = /home/cromwell/bin/bsd

${TARGET}/histogram-equalize:       histogram-equalize.cc
	g++ ${CFLAGS} histogram-equalize.cc		\
		-o ${TARGET}/histogram-equalize -lcv -lhighgui 

That fails because the compiler can't find the include files. You get errors like this:

histogram-equalize.cc:53:47: cv.h: No such file or directory
histogram-equalize.cc:54:47: highgui.h: No such file or directory
histogram-equalize.cc: In function `int main(int, char**)':
histogram-equalize.cc:84: error: `IplImage' undeclared (first use this function)
histogram-equalize.cc:84: error: (Each undeclared identifier is reported only once for each function it appears in.) 

So, expand the Makefile:

CFLAGS = -O3 -Wall -pedantic
TARGET = /home/cromwell/bin/bsd

${TARGET}/histogram-equalize:       histogram-equalize.cc
	g++ ${CFLAGS} histogram-equalize.cc		\
		-o ${TARGET}/histogram-equalize		\
		-I /usr/local/include/opencv		\
		-lcv -lhighgui 

That reveals that the OpenCV code is not clean enough to compile with the -pedantic option!

In file included from /usr/local/include/opencv/cxcore.h:69,
		from /usr/local/include/opencv/cv.h:58,
		from histogram-equalize.cc:53:
/usr/local/include/opencv/cxtypes.h:144: error: ISO C++ does not support `long long'
/usr/local/include/opencv/cxtypes.h:145: error: ISO C++ does not support `long long' 

So, modify the compiler parameters:

CFLAGS = -O3 -Wall -pedantic
TARGET = /home/cromwell/bin/bsd

${TARGET}/histogram-equalize:       histogram-equalize.cc
	g++ -O3 -Wall histogram-equalize.cc		\
		-o ${TARGET}/histogram-equalize		\
		-I /usr/local/include/opencv		\
		-lcv -lhighgui 

That modification gets it through the initial compilation, but it fails on the ld stage:

/usr/bin/ld: cannot find -lcv
collect2: ld returned 1 exit status 

I should have seen that coming.... I need to specify the OpenCV shared library locations because they're under /usr/local/lib on OpenBSD and the compiler doesn't look there by default:

CFLAGS = -O3 -Wall -pedantic
TARGET = /home/cromwell/bin/bsd

${TARGET}/histogram-equalize:       histogram-equalize.cc
	g++ -O3 -Wall histogram-equalize.cc		\
		-o ${TARGET}/histogram-equalize		\
		-I /usr/local/include/opencv		\
		-L /usr/local/lib			\
		-lcv -lhighgui 

Wow, that generates a lot of errors! I see some fairly obvious X11 warning messages:

/usr/bin/ld: warning: libfreetype.so.16.1, needed by /usr/local/lib/libhighgui.so.1.0, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libXdmcp.so.9.0, needed by /usr/X11R6/lib/libX11.so.11.1, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libXau.so.9.0, needed by /usr/X11R6/lib/libX11.so.11.1, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libX11.so.11.1, needed by /usr/X11R6/lib/libXrender.so.5.0, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libXrender.so.5.0, needed by /usr/local/lib/libcairo.so.9.2, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libfontconfig.so.5.1, needed by /usr/local/lib/libcairo.so.9.2, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libpixman-1.so.12.0, needed by /usr/local/lib/libcairo.so.9.2, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libXfixes.so.5.0, needed by /usr/X11R6/lib/libXdamage.so.3.1, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libXext.so.10.0, needed by /usr/X11R6/lib/libXcomposite.so.3.0, not found (try using -rpath or -rpath-link) 

But then more mysteriously, at least to me, a bunch of similar errors involving the cairo and pango software, undefined references to symbols with names starting "FT_":

/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_PS_Font_Info'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Init_FreeType'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Sfnt_Name'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Load_Glyph'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Done_Face'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_GlyphSlot_Embolden'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Render_Glyph'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Get_Kerning'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Char_Index'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Outline_Translate'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Set_Charmap'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Sfnt_Table'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Has_PS_Glyph_Names'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Outline_Decompose'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Set_Pixel_Sizes'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Glyph_Name'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Select_Charmap'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Outline_Transform'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_MulFix'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Next_Char'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Outline_Get_Bitmap'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Load_Sfnt_Table'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Vector_Transform'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Done_FreeType'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Set_Char_Size'
/usr/local/lib/libpangoft2-1.0.so.1800.0: undefined reference to `FT_Set_Transform'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_Sfnt_Name_Count'
/usr/local/lib/libcairo.so.9.2: undefined reference to `FT_Outline_Get_CBox'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_X11_Font_Format'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_BDF_Property'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_Get_First_Char'
/usr/X11R6/lib/libfontconfig.so.5.1: undefined reference to `FT_New_Face'
collect2: ld returned 1 exit status 

To jump ahead to the solution, I carefully examined the output in the window where I built the libraries. I got fresh output by recompiling:

% gmake clean
% gmake 

I saw that the OpenCV libraries are linked against a large number of shared libraries stored under /usr/local/lib and so software using the OpenCV libraries will also need to be similarly linked. Here's the Makefile entry that solved my problem, with all my changes highlighted

CFLAGS = -O3 -Wall -pedantic
TARGET = /home/cromwell/bin/bsd

${TARGET}/histogram-equalize:       histogram-equalize.cc
	g++ -O3 -Wall histogram-equalize.cc			\
		-o ${TARGET}/histogram-equalize			\
		-I /usr/local/include/opencv			\
		-L /usr/local/lib -L /usr/X11R6/lib		\
		-lcv -lhighgui					\
		-lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0	\
		-lgthread-2.0 -lglib-2.0 -lintl -liconv -lXi	\
		-lXrandr -lXcursor -lXcomposite -lXext		\
		-lXdamage -lXfixes -latk-1.0 -lcairo -lpixman-1 -lglitz  

One page I found through Google suggests that this may also be an issue with libcairo.so on Linux.

Of Historical Interest Only:

Below are outdated notes on how to fight through manual compilation. Use the Ports system!

Get the OpenCV software from SourceForge. I used opencv-1.0.0.tar.gz. Warning: I have tried this with both versions 1.0.0 and 2.3.0rc on OpenBSD. Version 2.3.0rc failed for me on OpenBSD because it relies on finding shared libraries libdl and libtr (possibly among others), shared libraries which are available on Linux if you add the correct packages, but which do not seem to be easily available for OpenBSD. I clearly should be able to build and install these shared libraries, but I can do whatever I want with OpenCV version 1.0.0.

Have a look at the OpenCV Wiki InstallGuide. But be careful — it mentions "getting the cutting-edge OpenCV from SourceForge SVN repository." The problem is that the very latest version will likely require a very recent version of autoconf or automake or another related tool, more recent than is available as a downloadable compiled package on your system.

Now, to build OpenCV. You've downloaded and extracted the archive, and changed to the newly created directory.

You need to set two environment variables. See what versions of autoconf and automake you have, the ls test is probably the most useful:

% pkg_info autoconf | head -1
% pkg_info automake | head -1
% ls /usr/local/bin/auto* 

Now set two environment variables, changing the numbers as appropriate. If you see, for example, autoconf-2.59p1, then you should probably specify simply 2.59. Similarly, if you see automake-1.9.6p1, then you should probably specify simply 1.9.

If you're running tcsh or csh, do something like the following:

% setenv AUTOCONF_VERSION 2.69
% setenv AUTOMAKE_VERSION 1.14 

If you're running bash, do something like the following:

$ export AUTOCONF_VERSION=2.69
$ export AUTOMAKE_VERSION=1.14 

Now set two more environment variables so the include files and libraries added under /usr/local can be found:

% setenv LDFLAGS -L/usr/local/lib
% setenv CPPFLAGS -I/usr/local/include 

Now you are ready to configure the build:

% autoreconf -i --force
% ./configure

You could add the --enable-static option to the second command, and it will certainly build the static libraries. However, my experience is that they aren't too useful as you will also need to link your program with many other libraries for which only shared libraries are available. In fact, that set of other libraries is the reason this was harder than I expected, and why this section appears on this page....

Second, build the libraries. This takes about five minutes on my powerhouse computing system (2.20 GHz Intel Celeron CPU, 512 MB RAM). Be certain to use gmake and not make!

% gmake 

If that worked, install the libraries. If it didn't work, then in my experience you skipped either the autoreconf or ./configure step. You can do this with sudo or with su as shown here:

% su root -c 'make install'