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.
Related
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.
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.
As a preset, AVCaptureSessionPresetHigh makes a lot of sense to me. Hardware is always changing and it makes sense to have an option to tell AVCapture that "I want the highest quality you can give me given current hardware" What is driving me nuts though, is just because I want to set the session to an abstract value, doesn't mean I don't need to know the resolution it's displaying.
The only way to figure out the current resolution is to actually capture a frame and check the size of said frame. Or even worse, manually find all these resolutions, create a lookup dictionary, ask the device for it's model and then fetch the hardcoded resolution. This is a complete hack, but still better than forcing a frame capture and then asking a UIImage for its frame size.
I desperately need this information, in order to dynamically make decisions based on the aspect ratio the camera is providing. Why does apple not have an interface for such a simple query?
Does anyone know of a resource that lists all of the possible resolutions for both cameras across the entire apple hardware market? I can google my way through some, but I cannot track down a complete list.
Given the AVCaptureDevice, you should be able to enumerate at formats or examine activeFormat, and then look at highResolutionStillImageDimensions of the resulting AVCaptureDeviceFormat.
Is it somehow possible to get the white balance color temperature (and tint) from a camera preview or from a saved picture?
I am able to get other exposure values in real time based on this SO thread, like f-stop, exposure time, ISO, etc. The white balance always returns just 0, probably meaning "auto white balance". When I save an image from live preview the EXIF data has the white balance still just a zero.
I need to get the white balance color temperature in Kelvins the image/live camera preview was balanced to. I read some stuff about hidden APIs to get/set color temperature, but I cannot use hidden APIs. Any ideas if/how is this possible on iOS 7? Thank you.
No, I'm afraid it's not possible (at least not without the hidden APIs to which you refer—and they don't use degK, but some internal system). And yes, 0 is the code for Auto white balance (1 would be manual).
It seems like it's possible to get values with the current API, you can check this out if you're still interested.
https://developer.apple.com/documentation/avfoundation/avcapturedevice/whitebalancetemperatureandtintvalues
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.