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
Erhalte etwas Fehler. Können Sie beide Dateien bereitstellen? –