提问人:ttyghost 提问时间:9/15/2023 更新时间:9/15/2023 访问量:42
如何防止相机在手动模式下调节亮度?
How to prevent camera from adjusting brightness in manual mode?
问:
如果我锁定了白平衡和自定义曝光,当我在视图中引入新对象时,在黑色背景上,两个对象都会变得更亮。如何关闭此功能或以高性能方式补偿该更改?
这就是我配置会话的方式,请注意,我设置了支持至少 180 fps 的视频格式,这是我需要的。
private func configureSession() {
self.sessionQueue.async { [self] in
//MARK: Init session
guard let session = try? validSession() else { fatalError("Session is unexpectedly nil") }
session.beginConfiguration()
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for:AVMediaType.video, position: .back) else { fatalError("Video Device is unexpectedly nil") }
guard let videoDeviceInput: AVCaptureDeviceInput = try? AVCaptureDeviceInput(device:device) else { fatalError("videoDeviceInput is unexpectedly nil") }
guard session.canAddInput(videoDeviceInput) else { fatalError("videoDeviceInput could not be added") }
session.addInput(videoDeviceInput)
self.videoDeviceInput = videoDeviceInput
self.videoDevice = device
//MARK: Connect session IO
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue: sampleBufferQueue)
session.automaticallyConfiguresCaptureDeviceForWideColor = false
guard session.canAddOutput(dataOutput) else { fatalError("Could not add video data output") }
session.addOutput(dataOutput)
dataOutput.alwaysDiscardsLateVideoFrames = true
dataOutput.videoSettings = [
String(kCVPixelBufferPixelFormatTypeKey): pixelFormat.rawValue
]
if let captureConnection = dataOutput.connection(with: .video) {
captureConnection.preferredVideoStabilizationMode = .off
captureConnection.isEnabled = true
} else {
fatalError("No Capture Connection for the session")
}
//MARK: Configure AVCaptureDevice
do { try device.lockForConfiguration() } catch { fatalError(error.localizedDescription) }
if let format = format(fps: fps, minWidth: minWidth, format: pixelFormat) { // 180FPS, YUV layout
device.activeFormat = format
device.activeVideoMinFrameDuration = CMTime(value: 1, timescale: CMTimeScale(fps))
device.activeVideoMaxFrameDuration = CMTime(value: 1, timescale: CMTimeScale(fps))
} else {
fatalError("Compatible format not found")
}
device.activeColorSpace = .sRGB
device.isGlobalToneMappingEnabled = false
device.automaticallyAdjustsVideoHDREnabled = false
device.automaticallyAdjustsFaceDrivenAutoExposureEnabled = false
device.isFaceDrivenAutoExposureEnabled = false
device.setFocusModeLocked(lensPosition: 0.4)
device.isSubjectAreaChangeMonitoringEnabled = false
device.exposureMode = AVCaptureDevice.ExposureMode.custom
let exp = CMTime(value: Int64(40), timescale: 100_000)
let isoValue = min(max(40, device.activeFormat.minISO), device.activeFormat.maxISO)
device.setExposureModeCustom(duration: exp, iso: isoValue) { t in }
device.setWhiteBalanceModeLocked(with: AVCaptureDevice.WhiteBalanceGains(redGain: 1.0, greenGain: 1.0, blueGain: 1.0)) {
(timestamp:CMTime) -> Void in }
device.unlockForConfiguration()
session.commitConfiguration()
onAVSessionReady()
}
}
这篇文章(iOS + AVFoundation。使用相同的手动曝光设置时,不同的照片亮度)表明,在设置 device.setExposureModeCustom() 后,可以通过将相机曝光设置为 .locked 来减轻这种影响。仅当与异步 api 一起使用时,这才能正常工作,并且仍然不会影响效果。
异步方法:
private func onAVSessionReady() {
guard let device = device() else { fatalError("Device is unexpectedly nil") }
guard let sesh = try? validSession() else { fatalError("Device is unexpectedly nil") }
MCamSession.shared.activeFormat = device.activeFormat
MCamSession.shared.currentDevice = device
self.observer = SPSDeviceKVO(device: device, session: sesh)
self.start()
Task {
await lockCamera(device)
}
}
private func lockCamera(_ device: AVCaptureDevice) async {
do { try device.lockForConfiguration() } catch { fatalError(error.localizedDescription) }
_ = await device.setFocusModeLocked(lensPosition: 0.4)
let exp = CMTime(value: Int64(40), timescale: 100_000)
let isoValue = min(max(40, device.activeFormat.minISO), device.activeFormat.maxISO)
_ = await device.setExposureModeCustom(duration: exp, iso: isoValue)
_ = await device.setWhiteBalanceModeLocked(with: AVCaptureDevice.WhiteBalanceGains(redGain: 1.0, greenGain: 1.0, blueGain: 1.0))
device.exposureMode = AVCaptureDevice.ExposureMode.locked
device.unlockForConfiguration()
}
private func configureSession() {
//MARK: Init session
guard let session = try? validSession() else { fatalError("Session is unexpectedly nil") }
session.beginConfiguration()
guard let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for:AVMediaType.video, position: .back) else { fatalError("Video Device is unexpectedly nil") }
guard let videoDeviceInput: AVCaptureDeviceInput = try? AVCaptureDeviceInput(device:device) else { fatalError("videoDeviceInput is unexpectedly nil") }
guard session.canAddInput(videoDeviceInput) else { fatalError("videoDeviceInput could not be added") }
session.addInput(videoDeviceInput)
self.videoDeviceInput = videoDeviceInput
self.videoDevice = device
//MARK: Connect session IO
let dataOutput = AVCaptureVideoDataOutput()
dataOutput.setSampleBufferDelegate(self, queue: sampleBufferQueue)
session.automaticallyConfiguresCaptureDeviceForWideColor = false
guard session.canAddOutput(dataOutput) else { fatalError("Could not add video data output") }
session.addOutput(dataOutput)
dataOutput.alwaysDiscardsLateVideoFrames = true
dataOutput.videoSettings = [
String(kCVPixelBufferPixelFormatTypeKey): pixelFormat.rawValue
]
if let captureConnection = dataOutput.connection(with: .video) {
captureConnection.preferredVideoStabilizationMode = .off
captureConnection.isEnabled = true
} else {
fatalError("No Capture Connection for the session")
}
//MARK: Configure AVCaptureDevice
do { try device.lockForConfiguration() } catch { fatalError(error.localizedDescription) }
device.exposureMode = AVCaptureDevice.ExposureMode.custom
if let format = format(fps: fps, minWidth: minWidth, format: pixelFormat) { // 180FPS, YUV layout
device.activeFormat = format
device.activeVideoMinFrameDuration = CMTime(value: 1, timescale: CMTimeScale(fps))
device.activeVideoMaxFrameDuration = CMTime(value: 1, timescale: CMTimeScale(fps))
} else {
fatalError("Compatible format not found")
}
device.activeColorSpace = .sRGB
device.isGlobalToneMappingEnabled = false
device.automaticallyAdjustsVideoHDREnabled = false
device.automaticallyAdjustsFaceDrivenAutoExposureEnabled = false
device.isFaceDrivenAutoExposureEnabled = false
device.isSubjectAreaChangeMonitoringEnabled = false
device.unlockForConfiguration()
session.commitConfiguration()
onAVSessionReady()
}
答: 暂无答案
评论