Computer Vision

How to develop an OpenCV C++ algorithm in Xcode

Everything you need to get up and running to develop and debug an OpenCV C++ algorithm

Getting Started

1. Create new Xcode project

Command line tool run output

2. Installing OpenCV

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install opencv
OpenCV installation path

3. Linking OpenCV

brew install pkg-config
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
OpenCV package config file
pkg-config --libs-only-l opencv4 | pbcopy
Open project navigator on the right hand side pane
Select the project configuration file from the project navigator pane
Linking OpenCV library
pkg-config --libs-only-L opencv4 | cut -c 3- | pbcopy
Settings Library search paths in Xcode
pkg-config --cflags opencv4 | cut -c 3- | pbcopy
Setting Header search paths in Xcode
dyld: Library not loaded:
/usr/local/opt/gcc/lib/gcc/10/libgfortran.5.dylib
Referenced from: /usr/local/opt/openblas/lib/libopenblas.0.dylib
Reason: no suitable image found. Did find:
/usr/local/opt/gcc/lib/gcc/10/libgfortran.5.dylib: code signature in
...

3. Reading images from disk

#include <opencv2/opencv.hpp>
int showImageFromDisk(std::string imagePath) {
cv::Mat image = cv::imread(imagePath);
// process image
cv::imshow("Image from disk", image);
cv::waitKey();
return 0;
}
int main(int argc, const char * argv[]) {
if (argc == 3) {
std::string readType(argv[1]);
std::string filePath(argv[2]);
if (readType == "--image") {
return showImageFromDisk(filePath);
}
}
return 0;
}
--image <PATH_TO_IMAGE>

4. Reading video from disk

int showVideoFromDisk(std::string videoPath) {
cv::VideoCapture videoCapture(videoPath);
if (!videoCapture.isOpened()) {
std::cout << "Error opening video stream of file" << std::endl;
return -1;
}
while (true) {
cv::Mat frame;
videoCapture >> frame;
// process frame here
if (frame.empty()) break;
cv::imshow("Video frame", frame);
if (cv::waitKey(10) == 27) break;
}
videoCapture.release();
cv::waitKey();
return 0;
}
int main(int argc, const char * argv[]) {
if (argc == 3) {
std::string readType(argv[1]);
std::string filePath(argv[2]);
if (readType == "--image") {
return showImageFromDisk(filePath);
} else if (readType == "--video") {
return showVideoFromDisk(filePath);
}
}
return 0;
}
--video <PATH_TO_VIDEO_FILE>
Video playing

5. Streaming the camera feed

int streamWebcamFeed() {
cv::VideoCapture videoCapture(0);
if (!videoCapture.isOpened()) {
std::cout << "Unable to connect to webcam" << std::endl;
return -1;
}
while(true) {
cv::Mat frame;
videoCapture >> frame;
if(frame.empty()) break;
cv::imshow("Camera feed", frame);
if (cv::waitKey(10) == 27) break;
}
videoCapture.release();
return 0;
}
int main(int argc, const char * argv[]) {
if (argc == 3) {
std::string readType(argv[1]);
std::string filePath(argv[2]);
if (readType == "--image") {
return showImageFromDisk(filePath);
} else if (readType == "--video") {
return showVideoFromDisk(filePath);
} else {
return streamWebcamFeed();
}
} else {
return streamWebcamFeed();
}
return 0;
}
This app has crashed because it attempted to access privacy-sensitive data without a usage description.  The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.
Create a new file
cp ${PROJECT_DIR}/${INFOPLIST_FILE} ${CONFIGURATION_BUILD_DIR}/
OpenCV displaying camera feed

7. Running the tool from the command line

cd ~/PATH/TO/MyOpenCVAlgorithm
xcodebuild -scheme MyOpenCVAlgorithm -derivedDataPath .derived_data
Executable location built through Terminal
./.derived_data/Build/Products/Debug/MyOpenCVAlgorithm
Terminal requesting camera permission

Summary

Final Notes

Senior iOS Engineer @ Onfido. Writing weekly blogs on iOS and programming. Follow me to stay tuned!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store