Questo è un aggiornamento della mia risposta iniziale dopo aver avuto la possibilità di giocare con questo me stesso. Sì, è possibile utilizzare CvVideoCamera
con un controller di visualizzazione scritto in Swift. Se vuoi solo usarlo per visualizzare i video dalla fotocamera nella tua app, è davvero facile.
#import <opencv2/highgui/cap_ios.h>
tramite la testata di collegamento. Poi, nel vostro controller della vista:
class ViewController: UIViewController, CvVideoCameraDelegate {
...
var myCamera : CvVideoCamera!
override func viewDidLoad() {
...
myCamera = CvVideoCamera(parentView: imageView)
myCamera.delegate = self
...
}
}
Il ViewController
non può di fatto conforme al protocollo CvVideoCameraDelegate
, ma CvVideoCamera
non funzionerà senza un delegato, in modo da ovviare a questo problema, dichiarando ViewController
di adottare il protocollo senza attuare alcuna dei suoi metodi. Ciò attiverà un avvertimento del compilatore, ma il flusso video dalla telecamera verrà visualizzato nella vista dell'immagine.
Naturalmente, si potrebbe voler implementare il metodo (solo) processImage()
per elaborare i frame video prima di visualizzarli. Il motivo per cui non è possibile implementarlo in Swift è perché utilizza un tipo C++, Mat
.
Quindi, sarà necessario scrivere una classe Objective-C++ la cui istanza può essere impostata come delegato della telecamera. Il metodo processImage()
in quella classe Objective-C++ verrà chiamato da CvVideoCamera
e chiamerà a turno il codice nella classe Swift. Ecco alcuni snippet di codice di esempio. 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
Nell'implementazione involucro, OpenCVWrapper.mm
(è un-C Obiettivo ++ classe, quindi l'estensione .mm):
#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
Poi si mette #import "OpenCVWrapper.h"
nell'intestazione ponte, e Swift controller della vista potrebbe essere simile a questo:
class ViewController: UIViewController {
...
var videoCameraWrapper : CvVideoCameraWrapper!
override func viewDidLoad() {
...
self.videoCameraWrapper = CvVideoCameraWrapper(controller:self, andImageView:imageView)
...
}
Vedi https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html su decl avanti arations e interoperabilità Swift/C++/Objective-C. Ci sono molte informazioni sul web su #ifdef __cplusplus
e extern "C"
(se ne hai bisogno).
Nel metodo delegato processImage()
è probabile che sia necessario interagire con alcune API OpenCV, per le quali sarà necessario scrivere anche wrapper. È possibile trovare alcune informazioni su questo altrove, ad esempio qui: Using OpenCV in Swift iOS
Ottenere qualche errore. Puoi fornire entrambi i file –