繁体   English   中英

如何从 captureOutput 获取 WhiteBalance (Kelvin)

[英]How to get WhiteBalance (Kelvin) from captureOutput

苹果有各种方法可以改变和查看使用 AVCaptureDevice 的开尔文

https://developer.apple.com/documentation/avfoundation/avcapturedevice/white_balance

例子:

    guard let videoDevice = AVCaptureDevice
        .default(.builtInWideAngleCamera, for: .video, position: .back) else {
        return
    }
    
   
    guard
        let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice),
        captureSession.canAddInput(videoDeviceInput) else {

        print("There seems to be a problem with the camera on your device.")
        
        return
    }
    
    captureSession.addInput(videoDeviceInput)
    
    let kelvin = videoDevice.temperatureAndTintValues(for: videoDevice.deviceWhiteBalanceGains)
    print("Kelvin temp \(kelvin.temperature)")
    print("Kelvin tint \(kelvin.tint)")
    
    let captureOutput = AVCaptureVideoDataOutput()
    
    captureOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)]
    captureOutput.setSampleBufferDelegate(self, queue: DispatchQueue.global(qos: DispatchQoS.QoSClass.default))
    
    captureSession.addOutput(captureOutput)

这将永远回归

Kelvin temp 3900.0889
Kelvin tint 4.966322

如何通过实时摄像头获取白平衡(开尔文值)?

它给你一个值,因为videoDevice.temperatureAndTintValues(for: videoDevice.deviceWhiteBalanceGains)只被调用一次。 要在相机提要之后获取更新值,您有两种选择:

  1. key-value observing,当WB发生变化时会通知
  2. 为每一帧调用 function videoDevice.temperatureAndTintValues(for: videoDevice.deviceWhiteBalanceGains)

我建议你使用第二种,键值观察有点烦人。 在那种情况下,我猜你已经实现了 AVCaptureVideoDataOutputSampleBufferDelegate 的方法func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) AVCaptureVideoDataOutputSampleBufferDelegate 每次返回一帧时都会调用该方法,因此,您可以为实时摄像机源的每一帧更新videoDevice.temperatureAndTintValues

对于键值观察,首先要设置观察者(例如在 viewDidAppear 中),例如:

func addObserver() {
self.addObserver(self, forKeyPath: "videoDevice.deviceWhiteBalanceGains", options: .new, context: &DeviceWhiteBalanceGainsContext)
}

保留对 videoDevice 的引用,以这种方式声明它:

@objc dynamic var videoDevice : AVCaptureDevice!

然后需要@objcdynamic来进行键值观察。

现在你可以实现这个 function ,每次观测值变化时都会调用它:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

guard let context = context else {
                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: nil)
                return
            }

if context == &DeviceWhiteBalanceGainsContext {
// do your work on WB here
} 
}

最后,您可以这样定义上下文(我在 ViewController 之外):

private var DeviceWhiteBalanceGainsContext = 0

我已经在我的应用程序中实现了这两种方法,它们都运行良好。

警告:有时,WB 值会超出允许范围(尤其是在启动时),并且 API 会引发异常。 确保处理此问题,否则应用程序将崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM