6

私はiPhone/iPadカメラを使用してビデオストリームを取得し、ストリームで認識を行っていますが、照明を変更すると、堅牢性に悪影響を及ぼします。私はさまざまな光の中でさまざまな設定をテストし、それを機能させることができますが、実行時に設定を調整することを試みることが必要です。

フレームごとに簡単な明るさチェックを計算できますが、カメラが調整して結果を破棄します。急激な変化を監視してチェックを実行することはできますが、段階的に変更すると結果も失われます。

理想的には、ストリームのカメラ/ EXIFデータにアクセスして、フィルター処理されていない明るさが何として登録されているかを確認したいのですが、これを行う方法はありますか?

(私はiOS 5以降のデバイスで作業しています)

ありがとうございました

4

2 に答える 2

8

iOS4.0以降で利用できます。CMSampleBufferRefからEXIF情報を取得することが可能です。

//Import ImageIO & include framework in your project. 
#import <ImageIO/CGImageProperties.h>

サンプルバッファデリゲートのフリーダイヤルブリッジは、CoreMediaのCMGetAttachmentから結果のNSDictionaryを取得します。

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    NSDictionary* dict = (NSDictionary*)CMGetAttachment(sampleBuffer, kCGImagePropertyExifDictionary, NULL);
于 2012-12-04T17:52:22.630 に答える
1

私自身のアプリで使用されている完全なコード:

- (void)setupAVCapture {

//-- Setup Capture Session.
_session = [[AVCaptureSession alloc] init];
[_session beginConfiguration];

//-- Set preset session size.
[_session setSessionPreset:AVCaptureSessionPreset1920x1080];

//-- Creata a video device and input from that Device.  Add the input to the capture session.
AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(videoDevice == nil)
    assert(0);

//-- Add the device to the session.
NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if(error)
    assert(0);

[_session addInput:input];

//-- Create the output for the capture session.
AVCaptureVideoDataOutput * dataOutput = [[AVCaptureVideoDataOutput alloc] init];
[dataOutput setAlwaysDiscardsLateVideoFrames:YES]; // Probably want to set this to NO when recording

//-- Set to YUV420.
[dataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]
                                                         forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; // Necessary for manual preview

// Set dispatch to be on the main thread so OpenGL can do things with the data
[dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

[_session addOutput:dataOutput];
[_session commitConfiguration];

[_session startRunning];
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection
{
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,
                                                                 sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc]
                              initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata
                                   objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    self.autoBrightness = [[exifMetadata
                         objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];

    float oldMin = -4.639957; // dark
    float oldMax = 4.639957; // light
    if (self.autoBrightness > oldMax) oldMax = self.autoBrightness; // adjust oldMax if brighter than expected oldMax

    self.lumaThreshold = ((self.autoBrightness - oldMin) * ((3.0 - 1.0) / (oldMax - oldMin))) + 1.0;

    NSLog(@"brightnessValue %f", self.autoBrightness);
    NSLog(@"lumaThreshold %f", self.lumaThreshold);
}

lumaThreshold変数は、均一変数としてフラグメントシェーダーに送信されます。フラグメントシェーダーは、Yサンプラーテクスチャを乗算して、環境の明るさに基づいて理想的な明るさを見つけます。現在、バックカメラを使用しています。画面の「明るさ」を変更して屋内/屋外の表示に合わせて調整するだけで、ユーザーの目はカメラの前面(背面ではなく)にあるため、おそらく前面カメラに切り替えます。

于 2016-05-11T10:06:54.027 に答える