2017-06-19 9 views
0

iOS用のアプリケーションを開発するには、OpenCVとswift/objective C++をリンクしたいと思います。私はCocoaPodがOpenCVポッドでうまく動作することを発見しました。そこで、私はそれらを出発点として使用し、いくつかの画像をうまくつなぎ合わせてみました。しかし、カメラから画像をキャプチャしようとすると、ディスプレイに出力が表示されません。 captureOutput機能の周りのコード実行とループは、カメラ画像は表示されません。コードはバックグラウンドで実行されているようです:カメラビューはswift/objective-C++(opencv)プロジェクトには表示されません - ios 10.3 xcode 8

のObjective C++コード:

@interface VideoSource() <AVCaptureVideoDataOutputSampleBufferDelegate> 
    @property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer; 
    @property (strong, nonatomic) AVCaptureSession *captureSession; 
@end 

@implementation VideoSource 

- (void)setTargetView:(UIView *)targetView { 
    if (self.previewLayer == nil) { 
     return; 
    } 
    self.previewLayer.contentsGravity = kCAGravityResizeAspectFill; 
    self.previewLayer.frame = targetView.bounds; 
    self.previewLayer.affineTransform = CGAffineTransformMakeRotation(M_PI/2); 
    [targetView.layer addSublayer:self.previewLayer]; 
    std::cout<<"VideoSource setTargetView ... done "<<std::endl; 
} 

- (instancetype)init 
{ 
    self = [super init]; 
    if (self) { 
     _captureSession = [[AVCaptureSession alloc] init]; 
     _captureSession.sessionPreset = AVCaptureSessionPreset640x480; 

     AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
     NSError *error = nil; 
     AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error]; 
     [_captureSession addInput:input]; 

     AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init]; 
     output.videoSettings = @{(NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)}; 
     output.alwaysDiscardsLateVideoFrames = YES; 
     [_captureSession addOutput:output]; 

     dispatch_queue_t queue = dispatch_queue_create("VideoQueue", DISPATCH_QUEUE_SERIAL); 
     [output setSampleBufferDelegate:self queue:queue]; 

     _previewLayer = [AVCaptureVideoPreviewLayer layer]; 

     std::cout<<"VideoSource init ... done "<<std::endl; 

    } 

    return self; 
} 


- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    uint8_t *base; 
    int width, height, bytesPerRow; 
    base = (uint8_t*)CVPixelBufferGetBaseAddress(imageBuffer); 
    width = (int)CVPixelBufferGetWidth(imageBuffer); 
    height = (int)CVPixelBufferGetHeight(imageBuffer); 
    bytesPerRow = (int)CVPixelBufferGetBytesPerRow(imageBuffer); 

    Mat mat = Mat(height, width, CV_8UC4, base); 

    //Processing here 
    [self.delegate processFrame:mat]; 

    CGImageRef imageRef = [self CGImageFromCVMat:mat]; 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
    self.previewLayer.contents = (__bridge id)imageRef; 
    }); 

    CGImageRelease(imageRef); 
    CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 

    std::cout<<"VideoSource captureOutput ... done "<<std::endl; 
} 

- (void)start { 
    [self.captureSession startRunning]; 
    std::cout<<"VideoSource start ... done "<<std::endl; 
} 




- (CGImageRef)CGImageFromCVMat:(Mat)cvMat { 
    if (cvMat.elemSize() == 4) { 
    cv::cvtColor(cvMat, cvMat, COLOR_BGRA2RGBA); 
} 
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()]; 
    CGColorSpaceRef colorSpace; 

    if (cvMat.elemSize() == 1) { 
     colorSpace = CGColorSpaceCreateDeviceGray(); 
    } else { 
     colorSpace = CGColorSpaceCreateDeviceRGB(); 
    } 

    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 

    // Creating CGImage from cv::Mat 
    CGImageRef imageRef = CGImageCreate(cvMat.cols,         
    //width 
            cvMat.rows,         
    //height 
            8,           
    //bits per component 
            8 * cvMat.elemSize(),      
    //bits per pixel 
            cvMat.step[0],        
    //bytesPerRow 
            colorSpace,         
    //colorspace 

    kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info 
            provider,         
    //CGDataProviderRef 
            NULL,          
    //decode 
            false,          
    //should interpolate 
            kCGRenderingIntentDefault     
//intent 
            ); 

    CGDataProviderRelease(provider); 
    CGColorSpaceRelease(colorSpace); 
    //std::cout<<"VideoSource CGImageFromCVMat ... done "<<std::endl; 

    return imageRef; 
} 

@end 

SWIFT側:

@IBOutlet var spinner:UIActivityIndicatorView! 
@IBOutlet weak var previewView: UIView! 
let wrapper = Wrapper() 

、その後、コール機能で:

override func viewDidAppear(_ animated: Bool) { 
super.viewDidAppear(animated) 
self.view.backgroundColor = UIColor.darkGray 
self.wrapper.setTargetView(self.previewView) 
self.wrapper.start() 
} 
+0

ただ、上記のコードは、ほとんど私がここで見つけるのソースコードからのものであることを指摘する:https://github.com/akira108/MinimumOpenCVLiveCamera この例は、私が推測され、IOS/Xcodeの以前のバージョンに基づいていますiOS 10.2/xcode 8のバージョンと直接互換性がない理由の1つです。 – fadel

+0

私はiOS 10.2/xcode 8でビルドしてインストールするので、変更する必要があるかどうかはわかりません。追加します。 – fadel

+0

これは、OpenCV/Swift/Objective-C++によるイメージスティッチングの例で、iOS 10.2/xcode8およびcocoapods(OpenCV 3.2移植)でうまくいきます。https://github.com/foundry/OpenCVSwiftStitch – fadel

答えて

0

私はこの問題を解決します。解決策は、特定のUIコンポーネントをドラッグして、UI(main.storyboard)をViewController.swiftに接続することでした。

どちらのパラダイムが仕事:から適応上の掲載

  1. ソースコード:https://github.com/akira108/MinimumOpenCVLiveCamera をこの(ちょうど作成するためにドラッグ&ドロップViewController.swiftpreviewView(UIViewの)へmain.storyboardUIViewを接続するために必要接続)

  2. CvVideoCameraDelegateクラスは、迅速なViewcontroller(Video processing with OpenCV in IOS Swift project)に関係しています。ここではmain.storyboardUIImageオブジェクトを挿入し、ViewControllerpreviewImageにこのオブジェクトを接続しました。この例では、swift(cap_ios.h)内で特定のopencvヘッダーを使用する必要があるため、OpenCV 2.4でのみテストしました。

関連する問題