在IOS Swift项目中使用OpenCV进行视频处理 [英] Video processing with OpenCV in IOS Swift project
问题描述
我已经集成opencv在Swift IOS项目中使用桥接头(连接Swift到Objective C)和Objective C包装器(连接Objective C和C ++)。使用这种方法,我可以从Swift代码传递单个图像,在C ++文件中分析它们,并让他们回来。
I've integrated opencv in Swift IOS project using bridging header (to connect Swift to Objective C) and a Objective C wrapper (to connect Objective C to C++). Using this method I can pass single images from the Swift code, analyse them in the C++ files and get them back.
我看到opencv提供了可以与Objective C UIViewController集成的CvVideoCamera对象。
但是因为我的UIViewController是用Swift编写的,我想知道这是否也是可能的。
But since my UIViewController are written in Swift I've wondered if this is possible as well?
推荐答案
这是我最初的答案更新后,我有机会玩这个自己。是的,可以使用用Swift编写的视图控制器使用 CvVideoCamera
。
This is an update to my initial answer after I had a chance to play with this myself. Yes, it is possible to use CvVideoCamera
with a view controller written in Swift. If you just want to use it to display video from the camera in your app, it's really easy.
#import< opencv2 / highgui />如果你只是想在应用程序中使用它来显示来自相机的视频, cap_ios.h>
。然后,在您的视图控制器中:
#import <opencv2/highgui/cap_ios.h>
via the bridging header. Then, in your view controller:
class ViewController: UIViewController, CvVideoCameraDelegate {
...
var myCamera : CvVideoCamera!
override func viewDidLoad() {
...
myCamera = CvVideoCamera(parentView: imageView)
myCamera.delegate = self
...
}
}
ViewController
实际上符合 CvVideoCameraDelegate
协议,但 CvVideoCamera
将无法在没有委托的情况下工作,因此我们解决此问题声明 ViewController
以采用协议而不实现其任何方法。这将触发编译器警告,但来自相机的视频流将显示在图像视图中。
The ViewController
cannot actually conform to the CvVideoCameraDelegate
protocol, but CvVideoCamera
won't work without a delegate, so we work around this problem by declaring ViewController
to adopt the protocol without implementing any of its methods. This will trigger a compiler warning, but the video stream from the camera will be displayed in the image view.
当然,您可能需要实现 CvVideoCameraDelegate
'(仅) processImage()
方法来处理视频帧。你不能在Swift中实现它的原因是因为它使用C ++类型 Mat
。
Of course, you might want to implement the CvVideoCameraDelegate
's (only) processImage()
method to process video frames before displaying them. The reason you cannot implement it in Swift is because it uses a C++ type, Mat
.
需要编写一个Objective-C ++类,其实例可以设置为camera的委托。 Objective-C ++类中的 processImage()
方法将由 CvVideoCamera
调用, Swift类。以下是一些示例代码段。
在 OpenCVWrapper.h
:
So, you will need to write an Objective-C++ class whose instance can be set as camera's delegate. The processImage()
method in that Objective-C++ class will be called by CvVideoCamera
and will in turn call code in your Swift class. Here are some sample code 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
在包装器实现中, OpenCVWrapper.mm
(它是一个Objective-C ++类,因此.mm扩展名):
In the wrapper implementation, OpenCVWrapper.mm
(it's an Objective-C++ class, hence the .mm extension):
#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
然后将 #importOpenCVWrapper.h
桥接头和Swift视图控制器可能看起来像这样:
Then you put #import "OpenCVWrapper.h"
in the bridging header, and the Swift view controller might look like this:
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 关于转发声明和Swift / C ++ / Objective-C互操作。网络上有很多关于 #ifdef __cplusplus
和 externC
(如果你需要它)的信息。
See https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html about forward declarations and Swift/C++/Objective-C interop. There is plenty of info on the web about #ifdef __cplusplus
and extern "C"
(if you need it).
在 processImage()
委托方法中,您可能需要与一些OpenCV API进行交互,也有写包装。您可以在其他地方找到一些信息,例如:在Swift iOS中使用OpenCV
In the processImage()
delegate method you will likely need to interact with some OpenCV API, for which you will also have to write wrappers. You can find some info on that elsewhere, for example here: Using OpenCV in Swift iOS
这篇关于在IOS Swift项目中使用OpenCV进行视频处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!