[英]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)
只被调用一次。 要在相机提要之后获取更新值,您有两种选择:
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!
然后需要@objc
和dynamic
来进行键值观察。
现在你可以实现这个 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.