【问题标题】:Using OpenCV in Swift iOS在 Swift iOS 中使用 OpenCV
【发布时间】:2015-09-03 16:37:12
【问题描述】:

在我的 xcode 项目中添加 OpenCV 2 框架后,我尝试搜索与 swift 集成的示例或教程。

有什么好的教程吗?

【问题讨论】:

    标签: ios swift opencv image-processing


    【解决方案1】:

    OpenCV 是一个用 C++ 编写的框架。 Apple 的 reference 告诉我们

    您不能将 C++ 代码直接导入 Swift。相反,为 C++ 代码创建一个 Objective-C 或 C 包装器。

    因此您不能在 swift 项目中直接导入和使用 OpenCV,但这实际上一点也不差,因为您(需要)继续使用该框架的 C++ 语法,该语法在整个网络上都有很好的记录。

    那么你将如何进行?

    1. 创建一个新的 Objective-C++ 类(.h,.mm)用于调用 C++ OpenCV

    OpenCVWrapper.h

    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    
    @interface OpenCVWrapper : NSObject
    
        + (UIImage *)processImageWithOpenCV:(UIImage*)inputImage;
    
    @end
    

    OpenCVWrapper.mm(使用 Objective-C 的文件 -> 新建...向导并将 .m 文件重命名为 .mm)

    #include "OpenCVWrapper.h"
    #import "UIImage+OpenCV.h" // See below to create this
    
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    @implementation OpenCVWrapper : NSObject
    
        + (UIImage *)processImageWithOpenCV:(UIImage*)inputImage {
            Mat mat = [inputImage CVMat];
            
            // do your processing here
            ...
            
            return [UIImage imageWithCVMat:mat];
        }
    
    @end
    

    作为创建新类(例如示例 OpenCVWrapper.h/mm)的替代方法,您可以使用 Objective-C 类别来扩展现有的具有 OpenCV 功能的 Objective-C 类。比如UIImage+OpenCV分类:

    UIImage+OpenCV.h

    #import <UIKit/UIKit.h>
    #import <opencv2/opencv.hpp>
    
    @interface UIImage (OpenCV)
    
        //cv::Mat to UIImage
    + (UIImage *)imageWithCVMat:(const cv::Mat&)cvMat;
    - (id)initWithCVMat:(const cv::Mat&)cvMat;
    
        //UIImage to cv::Mat
    - (cv::Mat)CVMat;
    - (cv::Mat)CVMat3;  // no alpha channel
    - (cv::Mat)CVGrayscaleMat;
    
    @end
    

    UIImage+OpenCV.mm

    https://github.com/foundry/OpenCVSwiftStitch/blob/master/SwiftStitch/UIImage%2BOpenCV.mm

    1. 通过导入我们新创建的包装器 (#import "OpenCVWrapper.h"),更新 Bridging-Header 以使您创建的所有 Objective-C++ 类都可用于 Swift

    2. 在你的 Swift 文件中使用你的包装器:

      let image = UIImage(named: "image.jpeg")
      let processedImage = OpenCVWrapper.processImageWithOpenCV(image)
      

    桥头中包含的所有 Objective-C++ 类都可以直接从 Swift 获得。

    【讨论】:

    • 您好,我是 OpenCV 新手。你能告诉我 UIImage+OpenCV 类别应该有什么吗?我应该从某个地方下载它吗?
    • @GMHSJ:它是 UIImage 的扩展,有助于在 cv::Mat 结构和 UIImage 之间进行转换。所以你必须在你的项目中创建它。
    • #include 应该在其他所有内容之前包含。否则会出现一些冲突。
    • @TomasCamin,我问了一个与此问题有点相似的问题,即在为 iOS 构建 OpenCV 时出现错误。如果您能看一下这个问题,我将不胜感激:stackoverflow.com/questions/45534183/…
    • @TomasCamin,可以从 Opencv.org 网站下载的 opencv swift 框架怎么样?它是否具有所有的包装类,还是我们仍需要将它与 opencv pod 结合使用?
    【解决方案2】:

    我在 github 上有一个演示:

    https://github.com/foundry/OpenCVSwiftStitch

    它展示了如何在基于 Swift 的项目中使用 OpenCV 拼接器。 openCV 方面的内容并不多,实际上只是一个演示如何将各个部分组合在一起。

    由于 Swift 不会直接使用 C++,它使用一个精简的 Objective-C++ 包装器在 iOS 端和 openCV 端之间进行调解。

    回答这些问题:
    Can I mix Swift with C++? Like the Objective - C .mm files
    libraries to CAPTURE panorama in iOS 6

    【讨论】:

    • @Kashif,我已通过您网站上的联系方式回复。
    • 这个 github 上的演示 (OpenCVSwiftStitch) 是迄今为止我发现的关于将 Swift 与 OpenCV 集成的最佳教程和实用演示。它回答问题、提供安装说明并显示要放入 UIImage+OpenCV 类别实现的内容。看完这篇我终于可以开始了,将图像从 UIImage 格式转换为 OpenCV Mat,做一些处理,转换回来并显示图像
    • @Paulus - 感谢您的反馈。很高兴您发现它很有用。
    • @foundry - 我正在尝试使用您的代码并将其转换为 Swift 3.0。代码编译,但我收到一个错误,“无法拼接图像,错误代码 = 1 CGImageCreate:无效的图像大小:0 x 0。”只是想知道您之前是否遇到过此错误,并且对潜在的解决方案有任何想法?
    • @Tom - 查看 repo 的最新更新。由于更严格的类型强制要求,Swift 3.0 正在崩溃 - 已修复。
    猜你喜欢
    • 2017-11-12
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多