Is it possible to create a custom flashMode in AVFoundation? - ios

Today I found out that settings like a custom exposuremode or a fixed lens position in the focus mode, which I set for the AVCaptureDevice in my AVCaptureSession conflicted with the flashMode.on option of the AVCaptureSettings, as it alters the previously specified ISO and exposure duration values etc. .
So my question is: Is it possible to specify a custom flashMode that does not analyze the viewed scene and uses strictly pre-defined settings?
For me it is more valuable to be in control of these settings, even though it might lead to a loss of photo quality.

Related

Understanding AVCaptureDevice exposureDuration, exposureTargetOffset, exposureTargetBias

Come from Android os, I'm trying to understand the AVCaptureDevice API and find a match between the different parameters of the IOS and Android.
I'm working with auto-continuous exposure mode.
I'm having trouble with exposure parameters above:
To my understating:
exposureDuration - This is the length of time in which the expose actuacly happens. It can be normalized to units of [seconds] by using the value and scale of this property.
exposureTargetOffset, exposureTargetBias - I'm not sure what these values represents - are they kind of fix applied to get the desired exposure level? what is this exposure target value?
You aren't alone. I'm not a professional photographer either, so it's pretty confusing. I think your gut is leading you in the right direction.
If you set exposureDuration, you're out of "auto-exposure mode" and it'll freeze that exposure duration and current or specified ISO setting. If the light changes, you're stuck with that setting.
If you set the exposureTargetBias, it will mimic a fancy camera and move the automatically calculated exposure settings up or down an exposure value (combination of f-number and exposure duration). There's a standard value for exposure of an image, but sometimes you want to over-expose or under-expose for style or shutter-speed priority. Changing the bias tells the automatic exposure system to aim for a value over or under the "correct" standard value.
Here's a great article explaining it in iOS: https://www.imore.com/camera-api-ios-8-explained
Exposure compensation is expressed in f-stops. +1 f-stop doubles the brightness, -1 f-stop halves the brightness.
Developers can currently set exposure target biases between -8 and +8 for all existing iOS devices. However, Apple warns that that could change in the future.
If you have a new iPhone (11 or newer) you can even change the bias in real time.
Exposure Bias is explained here: https://digital-photography-school.com/using-exposure-bias-to-improve-picture-detail/
exposureTargetOffset tells you how well the camera is hitting your requested bias value. Sometimes it just can't adjust enough to darken the image (aiming at the sun, the camera tries to shorten the exposure time and drops the ISO very low) or lighten it (pitch-black closet, the camera tries to expose the image sensor for a long time and bumps up the ISO a ton to gather all the light, resulting in a dark and grainy image). If the camera can't hit the target or is in the process of adjusting to it, the offset tells you how far off it currently is. For video, the exposure is obviously limited by framerate.

Avoid scene monitoring in AVFoundation?

In my current project I need very specific control over the AVCaptureDevice and the lighting settings (ISO, exposure,flashMode and even TorchMode). I am not trying to get "high quality" photos, in the sense of typical photography, but it is really important for me to be able to control the settings of the camera precisely, in order to get useable photos.
This poses no problem, as long as I am keeping the flash turned off.
But when setting the flashMode to .on, scene monitoring is enabled in the capturePhoto()-method which determines the flash intensity and auto-focusses while using the torch, even though it is set .off.
https://developer.apple.com/documentation/avfoundation/avcapturephotooutput/1778634-photosettingsforscenemonitoring
The flash is required in every photo taken, regardless of lighting conditions. So my question is: Is there a way to avoid scene monitoring and have the capturePhoto() method always using the flash without the torch?
Thanks for your help!

Increasing the brightness level for .continuousAutoExposure Mode

I implemented a custom camera with the AVCaptureDevice.Preset.High preset and I'm using .continuousAutoExposure. Everything works as expected, however, the brightness of the picture is sometimes quite low.
I have researched the official documentation and found out, that I am able to set a custom ISO with setExposureModeCustomWithDuration. Unfortunately, doing it this way results in the loss of the wished automation of the exposure.
My question now is, is there a way to increase the overall brightness Percentage of the .continuousAutoExposure Mode? I need it to increase the exposure to around 5% only, but I also need to stick with the .continuousAutoExposure mode.
The trick is to set exposureTargetOffset property of the AVCaptureDevice instance. You need to use KVO to observe changes in the value of captureDevice.exposureTargetOffset and change it to your required exposure level. For more details, check this answer.

cvCaptureFromCAM() / cvQueryFrame(): disable automatic image correction?

I'm using the two OpenCV functions mentioned above to retrieve frames from my webcam. No additional properties are set, just running with default parameters.
While reading frames in a loop I can see that the image changes, brightness and contrast seem to be adjusted automatically. It definitely seems to be a operation of OpenCV because the image captured by the camera is not changed and lit constantly.
So how can I disable this automated correction? I could not find a property that seems to be able to do that job.
You should try to play around with these three parameters:
CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras)
CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras)
CV_CAP_PROP_SATURATION Saturation of the image (only for cameras)
Try to set them all to 50. Also (if it won't help) try to change another camera capture parameters from documentation.
To answer that for my own: OpenCV is buggy or outdated here.
it seems to be impossible to get images in native resolution of the camera, they're always 640x480; also forcing it to an other value by setting width and height properties does not change anything
it seems to be impossible to disable the automatic image correction, the properties mentioned above seem not to work
the brightness/contrast properties doesn't seem to work as well - or at least I could not find any good values for it or the automatic image correction always overrides them
To sum it up: I'd not recommend to use OpenCV for some more enhanced image capturing.

Setting White balance and Exposure mode for iphone camera + enum default

I am using the back camera of an iphone4 and doing the standard and lengthy process of creating an AVCaptureSession and adding to it an AVCaptureDevice.
Before attaching the AvCaptureDeviceInput of that camera to the session, I am testing my understanding of white balance and exposure, so I am trying this:
[self.theCaptureDevice lockForConfiguration:nil];
[self.theCaptureDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked];
[self.theCaptureDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
[self.theCaptureDevice unlockForConfiguration];
1- Given that the various options for white balance mode are in an enum, I would have thought that the default is always zero since the enum Typedef variable was never assigned a value. I am finding out, if I breakpoint and po the values in the debugger, that the default white balance mode is actually set to 2. Unfortunately, the header files of AVCaptureDevice does not say what the default are for the different camera setting.
2- This might sound silly, but can I assume that once I stop the app, that all settings for whitebalance, exposure mode, will go back to their default. So that if I start another app right after, the camera device is not somehow stuck on those "hardware settings".
After a bit more research and help, I found the answers:
1- All camera settings (White balance, Focus and exposure) default to their "continuous" setting so that the camera is continuously adjusting for all. Check AVCaptureDevice.h for enum values.
2- All apps function in silo. Camera stops when the app that calls it is moved to the background. When a new app calls the camera, the above defaults are set again.

Resources