56

After adding the OpenCV 2 framework in my xcode project, I tried searching for samlpes or tutorials for integration with swift.

Are there any good tutorials for the same?

Kaushil Ruparelia
  • 1,179
  • 2
  • 9
  • 26

2 Answers2

67

OpenCV is a framework written in C++. Apple's reference tell us that

You cannot import C++ code directly into Swift. Instead, create an Objective-C or C wrapper for C++ code.

so you cannot directly import and use OpenCV in a swift project, but this is actually not bad at all because you (need) continue to use the C++ syntax of the framework which is pretty well documented all over the net.

So how do you proceed?

  1. Create a new Objective-C++ class (.h, .mm) for calling C++ OpenCV

OpenCVWrapper.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface OpenCVWrapper : NSObject

    + (UIImage *)processImageWithOpenCV:(UIImage*)inputImage;

@end

OpenCVWrapper.mm (use the File -> New... Wizard for Objective-C and rename the .m file to .mm)

#include "OpenCVWrapper.h"
#import "UIImage+OpenCV.h" // See below to create this

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

@implementation OpenCVWrapper : NSObject

    + (UIImage *)processImageWithOpenCV:(UIImage*)inputImage {
        Mat mat = [inputImage CVMat];
        
        // do your processing here
        ...
        
        return [UIImage imageWithCVMat:mat];
    }

@end

As an alternative to creating new classes such as the example OpenCVWrapper.h/mm you can use Objective-C categories to extend existing Objective-C classes with OpenCV functionality. For instance UIImage+OpenCV category:

UIImage+OpenCV.h

#import <UIKit/UIKit.h>
#import <opencv2/opencv.hpp>

@interface UIImage (OpenCV)

    //cv::Mat to UIImage
+ (UIImage *)imageWithCVMat:(const cv::Mat&)cvMat;
- (id)initWithCVMat:(const cv::Mat&)cvMat;

    //UIImage to cv::Mat
- (cv::Mat)CVMat;
- (cv::Mat)CVMat3;  // no alpha channel
- (cv::Mat)CVGrayscaleMat;

@end

UIImage+OpenCV.mm

See https://github.com/foundry/OpenCVSwiftStitch/blob/master/SwiftStitch/UIImage%2BOpenCV.mm

  1. Update the Bridging-Header to make all Objective-C++ classes you created available to Swift by importing our newly created wrappers (#import "OpenCVWrapper.h")

  2. Use your wrapper in your Swift files:

    let image = UIImage(named: "image.jpeg")
    let processedImage = OpenCVWrapper.processImageWithOpenCV(image)
    

All Objective-C++ classes included in the bridge header are available directly from Swift.

Suresh Mopidevi
  • 919
  • 3
  • 9
  • 24
Tomas Camin
  • 9,996
  • 2
  • 43
  • 62
  • Hello I am new to OpenCV. Can you please tell me what should be there in UIImage+OpenCV category?? Should I download it from somewhere? – Hanushka Suren Mar 18 '16 at 12:15
  • @GMHSJ: It is extension of UIImage which help to convert to and from cv::Mat structure to UIImage.So you have to create it in your project. – Shrawan Feb 08 '17 at 17:19
  • 2
    #include Should be included before everything else. If not some conflicts will appear. – Pochi Apr 05 '17 at 08:07
  • @TomasCamin, I have asked a question somewhat similar to this one regarding an error when building OpenCV for iOS. I would really appreciate it if you could take a look at the question: https://stackoverflow.com/questions/45534183/opencv-error-assertions-failed-on-ios. – fi12 Aug 07 '17 at 02:38
  • 1
    @TomasCamin, how about the opencv swift framework that is available for download at Opencv.org site? Does it have all the wrapper classes or do we still need to use it in conjunction with the opencv pod? – TRVD1707 Mar 02 '21 at 23:46
  • Hello, i'm new at OpenCV & C-Obj. can you tell me what i should put in `+ (UIImage *)processImageWithOpenCV:(UIImage*)inputImage {}` for face classification? Thank you. – Ricardo Milos Mar 16 '21 at 11:04
  • hi @Tomas, the Bridging-Header link has broken, could you please update it? I'd like to learn this as well. thanks – Franva Apr 03 '22 at 03:17
38

I have a demo on github:

https://github.com/foundry/OpenCVSwiftStitch

It shows how to use the OpenCV stitcher from a Swift-based project. There is not a lot to the openCV side, it's really just a demo of how to put the various pieces together.

As Swift won't talk C++ directly, it uses a thin Objective-C++ wrapper to mediate between the iOS side and the openCV side.

Made in answer to these questions:
Can I mix Swift with C++? Like the Objective - C .mm files
libraries to CAPTURE panorama in iOS 6

Community
  • 1
  • 1
foundry
  • 31,615
  • 9
  • 90
  • 125
  • @Kashif, I have replied via the contact details on your website. – foundry Nov 19 '15 at 15:15
  • 3
    This demo (OpenCVSwiftStitch) on github is the best tutorial and practical demo I have found so far on integrating Swift with OpenCV. It answers questions, gives install instructions and shows what to put into the UIImage+OpenCV category implementation. After reading this I could finally get going, convert an image from UIImage format to OpenCV Mat, do some processing, convert back and display the image – Paulus Apr 01 '16 at 17:05
  • @Paulus - thanks for the feedback. I'm glad you found it useful. – foundry Apr 03 '16 at 21:08
  • @foundry - I was attempting to play around with your code and converted it to Swift 3.0. The code compiles but I'm getting an error, "Can't stitch images, error code = 1 CGImageCreate: invalid image size: 0 x 0." Just wondered if you had come across this error before and do have any thoughts on a potential resolution? – Tom Oct 05 '16 at 20:15
  • @Tom - thanks for the heads-up. I was waiting for someone to attempt a Swift 3.0 conversion! I'll investigate. Meanwhile you should add breakpoints to verify that you have input images with non-zero dimensions, and you can also check the cv::Mat images size() property to narrow down the cause. – foundry Oct 05 '16 at 23:41
  • 2
    @Tom - see the latest updates to the repo. Swift 3.0 was breaking due to stricter type coercion requirements - fixed. – foundry Oct 06 '16 at 08:31
  • 1
    @foundry, I saw your demo and I was able to build and run, but I noticed the OpenCV.org has a swift framework for download now. Does it replace the need to use the OpenCV pod and to create the OBJC wrappers that call the C++ classes and expose them to Swift? – TRVD1707 Mar 02 '21 at 23:42