如何防止相机在手动模式下调节亮度?

How to prevent camera from adjusting brightness in manual mode?

提问人:ttyghost 提问时间:9/15/2023 更新时间:9/15/2023 访问量:42

问:

如果我锁定了白平衡和自定义曝光,当我在视图中引入新对象时,在黑色背景上,两个对象都会变得更亮。如何关闭此功能或以高性能方式补偿该更改?

这就是我配置会话的方式,请注意,我设置了支持至少 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()
    }
AVFatament AVChagerdevice IOS相机

评论


答: 暂无答案