当前位置: 首页 > 面试题库 >

IOS Swift项目中使用OpenCV进行视频处理

邹桐
2023-03-14
问题内容

我已经使用桥接标头(将Swift连接到Objective C)和目标C包装器(将Objective C连接到C )集成了Swift
IOS项目中的opencv。使用这种方法,我可以从Swift代码中传递单个图像,在C
文件中对其进行分析并取回它们。

我已经看到opencv提供了可以与Objective C
UIViewController集成的CvVideoCamera对象。

但是由于我的UIViewController是用Swift编写的,所以我想知道是否也可以这样做?


问题答案:

这是我自己玩过这个游戏后对最初答案的更新。是的,可以与用CvVideoCameraSwift编写的视图控制器一起使用。如果您只想使用它来显示应用程序中摄像机的视频,那真的很容易。

#import <opencv2/highgui/cap_ios.h>通过桥接头。然后,在您的视图控制器中:

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

ViewController实际上不能符合CvVideoCameraDelegate协议,但CvVideoCamera不会没有代理工作,所以我们通过声明变通解决此问题ViewController通过该协议没有实施任何它的方法。这将触发编译器警告,但是来自摄像机的视频流将显示在图像视图中。

当然,您可能需要实现CvVideoCameraDelegate的(仅)processImage()方法来在显示视频帧之前对其进行处理。之所以不能在Swift中实现它,是因为它使用C
++类型Mat

因此,您将需要编写一个Objective-C 类,其实例可以设置为相机的委托。该 processImage()Objective-C
类中的方法将由调用,CvVideoCamera并依次调用您的Swift类中的代码。以下是一些示例代码片段。在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扩展名):

#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

然后放入#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 __cplusplusextern "C"(如果需要)的信息。

processImage()委托方法中,您可能需要与某些OpenCV
API交互,还必须为其编写包装程序。您可以在其他地方找到有关此信息的一些信息,例如在这里:在Swift
iOS中使用OpenCV

更新09/03/2019

应社区要求,请参阅注释,示例代码已放置在GitHub上的https://github.com/aperedera/opencv-swift-
examples。

另外,在撰写本文时,当前版本的OpenCV
iOS框架不再允许Swift代码使用声明CvVideoCameraDelegate协议的标头(现在在videoio /
cap_ios.h中),因此您不能仅将其包含在桥接标头中并声明视图控制器符合该协议,以仅在您的应用中显示摄像机视频。



 类似资料:
  • 我试图捕捉一个视频,并转换成帧使用python和OpenCV。我遵循了在Windows8中为python导入openCV2库所需的步骤,如下所示: 打开Python空闲或终端,然后键入 我已经完成了将opencv库导入Python的上述步骤。 但是,当我导入CV2库并试图捕获视频时,我无法使用函数生成帧,也无法使用函数访问帧。我无法捕捉帧。请查找下面的代码。

  • 问题内容: 我目前正在尝试为 多处理OpenCV视频* 流开发 GUI 。下面的代码确实成功执行了此操作,因为它显示了视频供稿和一个“退出”按钮,但是运行方式很奇怪: * 该程序 在退出时* (通过单击或通过单击关闭窗口)在(我正在使用Windows)中引发 运行时错误 ,表示程序“要求运行时以异常方式终止” * 关于如何解决该问题的任何想法将不胜感激! 我的代码: 配置:Windows 7 Ho

  • 问题内容: 我是OpenCV的初学者。我想对要上传到服务器的视频帧进行一些图像处理。我只想读取可用的框架并将它们写入目录中。然后,等待视频的另一部分上载并将帧写入目录。并且,我应该等待每个帧都完全上传,然后将其写入文件。 您能告诉我如何使用OpenCV(Python)吗? 编辑1: 我编写了这段代码,用于从文件中捕获视频,而新数据将附加在文件末尾。换句话说,该文件不是完整的视频,并且另一个程序正在

  • 我计划用网络摄像机捕捉视频,然后用opencv处理,最后在google原生客户端环境下用opencv naclport在网页上显示输出 我现在意识到的是 使用javascript中的MediaStreamTrack接口和 然后 将其编码为Base64字符串并发送到c模块以使用opencv进行处理, 在cpp模块中,将其解码回Mat图像并进行处理,最后将其发送回浏览器进行显示。 所以我想知道,在op

  • 下面是我的代码: 所以问题是调用!当没有框架时,它将返回!而且它不会再捕捉帧了,即使我等了很长时间。

  • 问题内容: 我正在尝试使用中创建视频。但是文件大小为0。 我的代码: 总是回来。 另一种尝试: 没有错误,但输出为空。 我想念什么? 问题答案: 您想要做什么的简单代码。详细内容点击这里