Setting up the OpenCV framework
OpenCV for iOS is distributed as a framework file, which is a bundle containing the library's header files as well as binary files for static linkage. The binaries support all iOS device architectures (ARMv7, ARMv7s, and ARM64) and all iOS simulator architectures (x86 and x64). Thus, we can use the same framework file for all configurations of an iOS application project.
OpenCV 3 is designed to be modular. Its build process is highly configurable to allow modules to be added, reimplemented, or removed without breaking other modules. Each module consists of one public header file along with various private header files and implementation files. Some modules are considered standard components of an OpenCV build, and these standard modules are maintained and tested by the library's core development team. Other modules are considered extras, and these extra or "contributed" modules are maintained and tested by third-party contributors. Collectively, the extra modules are called opencv_contrib
.
If we just want to use the standard modules, we can obtain the official, prebuilt distribution of OpenCV for iOS. This prebuilt distribution consists of a framework file, opencv2.framework
. If we want to use extra modules, we must build opencv2.framework
for ourselves. Next, let's examine the steps to get or build the framework.
Note
For this book's projects, the extra modules are not required but they are recommended because we will use them to implement some optional features.
Getting the prebuilt framework with standard modules
Go to of OpenCV for iOS. Specifically, we require OpenCV 3.1 or a later version. The download's filename is opencv2.framework.zip
. Unzip it to get the framework file, opencv2.framework
. Later, we will add this framework to our iOS application projects; we will import its header files using the following code:
#import <opencv2/core.hpp>
This imports the core
module's header file from opencv2.framework
. The import statement will vary according to the module's name.
Building the framework from source with extra modules
We will try to get and build all of OpenCV's modules. Broadly, this process will consist of the following four steps:
- Get the source code for OpenCV's standard modules. Store this in any folder, which we will refer to as
<opencv_source_path>
. - Get the source code for OpenCV's extra modules. Store this in any folder, which we will refer to as
<opencv_contrib_source_path>
. - Try to build all the modules and store the build in any folder, which we will refer to as
<opencv_contrib_build_path>
. - If any module fails to build, resolve the issue by either removing the module or patching its source code. Then, try to build again.
Now, let's discuss the details as we walk through the steps. To obtain OpenCV's latest source code, we can use Git, an open source version control tool. We already installed Git as part of the Xcode Command Line Tools. OpenCV's standard and extra modules are hosted in two repositories on GitHub, an online repository hosting service. To download the standard modules' source code to <opencv_source_path>
, run the following command:
$ git clone https://github.com/Itseez/opencv.git <opencv_source_path>
Similarly, to download the extra modules' source code to <opencv_contrib_source_path>
, run the following command:
$ git clone https://github.com/Itseez/opencv_contrib.git <opencv_contrib_source_path>
Note
For an exhaustive guide to Git, see the book Pro Git, 2nd Edition (Apress, 2014) by Scott Chacon and Ben Straub. The free eBook version is available at https://www.git-scm.com/book.
OpenCV's source code comes with build scripts for various platforms. The iOS build script takes two arguments—the build path and the opencv_contrib
source path. Run the script in the following manner:
$ ./<opencv_source_path>/platforms/ios/build_framework.py <opencv_contrib_build_path> --contrib <opencv_contrib_source_path>
Read the script's output to see whether it failed to build any modules. Remember that opencv_contrib
contains experimental modules from various authors, and some authors might not test their modules for iOS compatibility. For example, the following output shows a compilation error in the saliency
module (modules/saliency
):
** BUILD FAILED ** The following build commands failed: CompileC /Users/Joe/SDKs/OpenCV/fork_build_ios/build/iPhoneOS-armv7/modules/saliency/OpenCV.build/Release-iphoneos/opencv_saliency_object.build/Objects-normal/armv7/FilterTIG.o /Users/Joe/SDKs/OpenCV/fork_contrib/modules/saliency/src/BING/FilterTIG.cpp normal armv7 c++ com.apple.compilers.llvm.clang.1_0.compiler (1 failure) ('Child returned:', 65)
If we do not require the problematic module, we may simply delete its source subfolder in <opencv_contrib_source_path>/modules
, and then rerun build_framework.py
. For example, to avoid building the saliency
module, we may delete <opencv_contrib_source_path>/modules/saliency.
Note
For this book's projects, the following extra modules are useful:
- xfeatures2d: This provides extra algorithms to match images based on distinctive details in the images
- xphoto: This provides extra photo processing techniques
On the other hand, if we do require the problematic module, first somebody must modify its source code so that it successfully compiles and runs for iOS. Patching opencv_contrib
is beyond the scope of this book, but if you are skilled in C++ programming, I encourage you to try it sometime. Alternatively, you may decide to file an issue report at https://github.com/Itseez/opencv_contrib/issues and wait for the module's authors to respond.
When build_framework.py
works properly, it prints ** INSTALL SUCCEEDED **
, and creates the framework file at <opencv_contrib_build_path>/opencv2.framework
. Later, we will add this framework to our iOS application projects; we will import its header files using the following code:
#import <opencv2/xphoto.hpp>
This imports the xphoto
module's header file from opencv2.framework
. The import statement will vary according to the module's name.
Making the extra modules optional in our code
As the extra modules are less stable than the standard modules, we may want to make them optional in our code. By enclosing the optional code inside a preprocessor condition, we can easily disable or re-enable it in order to test the effect. Consider the following example:
#ifdef WITH_OPENCV_CONTRIB #import <opencv2/xphoto.hpp> #endif
If we want to use opencv2_contrib
, we will edit the Xcode project settings to add WITH_OPENCV_CONTRIB
as a preprocessor definition. Then, in the preceding example, the xphoto.hpp
headers will be imported in our code. Detailed steps to create a preprocessor definition are provided later in this chapter, in the Configuring the project section.