2016-05-24 38 views
5

Tôi đã tích hợp opencv trong dự án Swift IOS bằng cách sử dụng tiêu đề bắc cầu (để kết nối Swift với Objective C) và trình bao bọc Objective C (để kết nối Objective C tới C++). Sử dụng phương pháp này tôi có thể truyền các hình ảnh đơn lẻ từ mã Swift, phân tích chúng trong các tệp C++ và đưa chúng trở lại.Xử lý video với OpenCV trong dự án IOS Swift

I've seen that opencv provides CvVideoCamera object that can be integrated with an Objective C UIViewController.

Nhưng kể từ UIViewController của tôi được viết bằng Swift Tôi đã tự hỏi nếu điều này có thể là tốt?

Trả lời

15

Đây là bản cập nhật cho câu trả lời ban đầu của tôi sau khi tôi có cơ hội chơi với chính bản thân mình. Có, có thể sử dụng CvVideoCamera với bộ điều khiển chế độ xem được viết bằng Swift. Nếu bạn chỉ muốn sử dụng nó để hiển thị video từ máy ảnh trong ứng dụng của bạn, nó thực sự dễ dàng.

#import <opencv2/highgui/cap_ios.h> thông qua tiêu đề bắc cầu. Sau đó, trong điều khiển điểm của bạn:

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

Các ViewController không thể thực sự phù hợp với các giao thức CvVideoCameraDelegate, nhưng CvVideoCamera sẽ không làm việc mà không có một đại biểu, vì vậy chúng tôi làm việc xung quanh vấn đề này bằng cách tuyên bố ViewController để thông qua giao thức mà không thực hiện bất kỳ các phương pháp của nó. Điều này sẽ kích hoạt cảnh báo trình biên dịch, nhưng luồng video từ máy ảnh sẽ được hiển thị trong chế độ xem hình ảnh.

Tất nhiên, bạn có thể muốn triển khai phương thức CvVideoCameraDelegate (chỉ) processImage() để xử lý các khung hình video trước khi hiển thị chúng. Lý do bạn không thể thực hiện nó trong Swift là vì nó sử dụng kiểu C++, Mat.

Vì vậy, bạn sẽ cần phải viết một lớp Objective-C++ có thể được đặt làm đại biểu của máy ảnh. Phương thức processImage() trong lớp Objective-C++ đó sẽ được gọi bởi CvVideoCamera và sẽ lần lượt mã gọi trong lớp Swift của bạn. Dưới đây là một số đoạn mã mẫu. Trong 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 

Trong việc thực hiện wrapper, OpenCVWrapper.mm (nó là một-C Mục tiêu ++ lớp, vì thế mà mở rộng .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 

Sau đó, bạn đặt #import "OpenCVWrapper.h" trong tiêu đề cầu nối, và Bộ điều khiển xem nhanh có thể trông giống như sau:

class ViewController: UIViewController { 
... 
    var videoCameraWrapper : CvVideoCameraWrapper! 

    override func viewDidLoad() { 
     ... 
     self.videoCameraWrapper = CvVideoCameraWrapper(controller:self, andImageView:imageView) 
     ... 
    } 

Xem https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html về chuyển tiếp từ chối arations và Swift/C++/Objective-C interop. Có rất nhiều thông tin trên web về #ifdef __cplusplusextern "C" (nếu bạn cần).

Trong phương thức ủy nhiệm processImage(), bạn có thể sẽ cần phải tương tác với một số API OpenCV, mà bạn cũng sẽ phải viết trình bao bọc. Bạn có thể tìm thấy một số thông tin ở nơi khác, ví dụ: Using OpenCV in Swift iOS

+0

Nhận một số lỗi. Bạn có thể cung cấp cả hai tệp –

Các vấn đề liên quan