在IOS Swift项目中使用OpenCV进行video处理
我使用桥接头(将Swift连接到Objective C)和Objective C包装器(将Objective C连接到C ++)在swift IOS项目中集成了opencv。 使用这种方法,我可以从Swift代码传递单个图像,在C ++文件中分析它们并将它们取回。
我已经看到opencv提供了可以与Objective C UIViewController集成的CvVideoCamera对象。
但是因为我的UIViewController是用Swift编写的,我想知道这是否可行?
在我有机会自己玩这个之后,这是我最初答案的更新。 是的,可以将CvVideoCamera
与用Swift编写的视图控制器一起使用。 如果您只是想用它来在应用程序中显示来自相机的video,那真的很容易。
#import
通过桥接头。 然后,在您的视图控制器中:
class ViewController: UIViewController, CvVideoCameraDelegate { ... var myCamera : CvVideoCamera! override func viewDidLoad() { ... myCamera = CvVideoCamera(parentView: imageView) myCamera.delegate = self ... } }
ViewController
实际上不能符合CvVideoCameraDelegate
协议,但是CvVideoCamera
没有委托, CvVideoCamera
将无法工作,因此我们通过声明ViewController
采用协议而不实现其任何方法来解决此问题。 这将触发编译器警告,但来自摄像机的video流将显示在图像视图中。
当然,您可能希望在显示video帧之前实现CvVideoCameraDelegate
(仅)的processImage()
方法。 你无法在Swift中实现它的原因是它使用了C ++类型Mat
。
因此,您需要编写一个Objective-C ++类,其实例可以设置为摄像机的委托。 该Objective-C ++类中的processImage()
方法将由CvVideoCamera
调用,并将依次调用Swift类中的代码。 以下是一些示例代码段。 在OpenCVWrapper.h
:
// Need this ifdef, so the C++ header won't confuse Swift #ifdef __cplusplus #import #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
在包装器实现中, OpenCVWrapper.mm
(它是一个Objective-C ++类,因此是.mm扩展名):
#import using namespace cv; // Class extension to adopt the delegate protocol @interface CvVideoCameraWrapper () { } @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
然后将#import "OpenCVWrapper.h"
放在桥接头中,Swift视图控制器可能如下所示:
class ViewController: UIViewController { ... var videoCameraWrapper : CvVideoCameraWrapper! override func viewDidLoad() { ... self.videoCameraWrapper = CvVideoCameraWrapper(controller:self, andImageView:imageView) ... }
有关前向声明和Swift / C ++ / Objective-C互操作,请参阅https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html 。 网上有很多关于#ifdef __cplusplus
和extern "C"
(如果你需要的话)。
在processImage()
委托方法中,您可能需要与某些OpenCV API进行交互,为此您还必须编写包装器。 您可以在其他地方找到相关信息,例如: 在Swift iOS中使用OpenCV