2016-05-24 9 views
5

Ich habe opencv in Swift IOS-Projekt mit Bridging-Header (um Swift mit Objective C zu verbinden) und einem Objective-C-Wrapper (um Objective C mit C++ zu verbinden) integriert. Mit dieser Methode kann ich einzelne Bilder aus dem Swift-Code übergeben, in den C++ - Dateien analysieren und zurückholen.Videoverarbeitung mit OpenCV in IOS Swift Projekt

I've seen that opencv provides CvVideoCamera object that can be integrated with an Objective C UIViewController.

Aber da meine UIViewController in Swift geschrieben ich gefragt haben, ob dies auch möglich ist?

Antwort

15

Dies ist ein Update zu meiner ersten Antwort, nachdem ich die Chance hatte, selbst damit zu spielen. Ja, es ist möglich, CvVideoCamera mit einem in Swift geschriebenen View-Controller zu verwenden. Wenn Sie es nur zum Anzeigen von Videos von der Kamera in Ihrer App verwenden möchten, ist es wirklich einfach.

#import <opencv2/highgui/cap_ios.h> über den Bridging-Header. Dann in Ihrem View-Controller:

class ViewController: UIViewController, CvVideoCameraDelegate { 
... 
    var myCamera : CvVideoCamera! 
    override func viewDidLoad() { 
     ... 
     myCamera = CvVideoCamera(parentView: imageView) 
     myCamera.delegate = self 
     ... 
    } 
} 

Die ViewController kann nicht wirklich entsprechen das CvVideoCameraDelegate Protokoll, aber CvVideoCamera nicht ohne Delegierter arbeiten, so dass wir dieses Problem umgehen, indem ViewController erklärt, das Protokoll zu verabschieden, ohne dass die Umsetzung seiner Methoden. Dies wird eine Compiler-Warnung auslösen, aber der Videostream von der Kamera wird in der Bildansicht angezeigt.

Natürlich können Sie die Methode CvVideoCameraDelegate (nur) processImage() implementieren, um Videobilder vor der Anzeige zu verarbeiten. Der Grund, warum Sie es nicht in Swift implementieren können, ist, weil es einen C++ - Typ verwendet.

Sie müssen also eine Objective-C++ - Klasse schreiben, deren Instanz als Delegate der Kamera festgelegt werden kann. Die processImage()-Methode in dieser Objective-C++ - Klasse wird von CvVideoCamera aufgerufen und ruft wiederum Code in Ihrer Swift-Klasse auf. Hier sind einige Beispielcode-Snippets. In OpenCVWrapper.h:

// Need this ifdef, so the C++ header won't confuse Swift 
#ifdef __cplusplus 
#import <opencv2/opencv.hpp> 
#endif 

// This is a forward declaration; we cannot include *-Swift.h in a header. 
@class ViewController; 

@interface CvVideoCameraWrapper : NSObject 
... 
-(id)initWithController:(ViewController*)c andImageView:(UIImageView*)iv; 
... 
@end 

In der Wrapper-Implementierung OpenCVWrapper.mm (es ist ein Objective-C++ Klasse, daher der .mm Erweiterung):

#import <opencv2/highgui/cap_ios.h> 
using namespace cv; 
// Class extension to adopt the delegate protocol 
@interface CvVideoCameraWrapper() <CvVideoCameraDelegate> 
{ 
} 
@end 
@implementation CvVideoCameraWrapper 
{ 
    ViewController * viewController; 
    UIImageView * imageView; 
    CvVideoCamera * videoCamera; 
} 

-(id)initWithController:(ViewController*)c andImageView:(UIImageView*)iv 
{ 
    viewController = c; 
    imageView = iv; 

    videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView]; 
    // ... set up the camera 
    ... 
    videoCamera.delegate = self; 

    return self; 
} 
// This #ifdef ... #endif is not needed except in special situations 
#ifdef __cplusplus 
- (void)processImage:(Mat&)image 
{ 
    // Do some OpenCV stuff with the image 
    ... 
} 
#endif 
... 
@end 

Sie dann #import "OpenCVWrapper.h" in dem Überbrückungs Header setzen, und die Swift-view-Controller könnte wie folgt aussehen:

class ViewController: UIViewController { 
... 
    var videoCameraWrapper : CvVideoCameraWrapper! 

    override func viewDidLoad() { 
     ... 
     self.videoCameraWrapper = CvVideoCameraWrapper(controller:self, andImageView:imageView) 
     ... 
    } 

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html über vorwärts Decl See Anwendungen und Swift/C++/Objective-C Interop. Es gibt viele Informationen im Internet über #ifdef __cplusplus und extern "C" (wenn Sie es brauchen).

In der Delegate-Methode processImage() müssen Sie wahrscheinlich mit einigen OpenCV-API interagieren, für die Sie auch Wrapper schreiben müssen. Sie können einige Informationen darüber woanders finden, zum Beispiel hier: Using OpenCV in Swift iOS

+0

Erhalte etwas Fehler. Können Sie beide Dateien bereitstellen? –

Verwandte Themen