In computer vision, we often should calibrate the camera of a device and find its intrinsic and extrinsic parameters (pinhole camera model). In order to do this, we should have the possibility to lock some camera settings (for example, focus) to calculate the camera parameters as accurately as possible. In this recipe, we'll consider some advanced settings provided by the CvVideoCamera
class that can help you during the calibration process.
We will use the Recipe10_CapturingVideo
project as a starting point, trying to add more control over the iOS camera. The source code can be found in the Recipe11_AdvancedCameraControl
folder in the code bundle that accompanies this book. For this recipe you can't use Simulator, as it doesn't support camera.
The following are the required steps:
Add four buttons to our GUI to control the focus, exposure, white balance, and camera rotation.
Then implement actions for all buttons.
Let's implement the described steps:
Similarly to previous recipe, we should implement basic functions to work with the video camera and add four more buttons to our UI:
#import <opencv2/highgui/ios.h> @interface ViewController : UIViewController<CvVideoCameraDelegate> { CvVideoCamera* videoCamera; BOOL isCapturing; BOOL isFocusLocked, isExposureLocked, isBalanceLocked; } @property (nonatomic, strong) CvVideoCamera* videoCamera; @property (nonatomic, strong) IBOutlet UIImageView* imageView; @property (nonatomic, strong) IBOutlet UIToolbar* toolbar; @property (nonatomic, weak) IBOutlet UIBarButtonItem* startCaptureButton; @property (nonatomic, weak) IBOutlet UIBarButtonItem* stopCaptureButton; @property (nonatomic, weak) IBOutlet UIBarButtonItem* lockFocusButton; @property (nonatomic, weak) IBOutlet UIBarButtonItem* lockExposureButton; @property (nonatomic, weak) IBOutlet UIBarButtonItem* lockBalanceButton; @property (nonatomic, weak) IBOutlet UIBarButtonItem* rotationButton; -(IBAction)startCaptureButtonPressed:(id)sender; -(IBAction)stopCaptureButtonPressed:(id)sender; - (IBAction)actionLockFocus:(id)sender; - (IBAction)actionLockExposure:(id)sender; - (IBAction)actionLockBalance:(id)sender; - (IBAction)rotationButtonPressed:(id)sender; @end
Then, the first three buttons will be used to control the focus, exposure, and white balance settings. These buttons will have two modes: locked and unlocked. In order to do it, we should implement the corresponding actions:
- (IBAction)actionLockFocus:(id)sender { if (isFocusLocked) { [self.videoCamera unlockFocus]; [lockFocusButton setTitle:@"Lock focus"]; isFocusLocked = NO; } else { [self.videoCamera lockFocus]; [lockFocusButton setTitle:@"Unlock focus"]; isFocusLocked = YES; } } - (IBAction)actionLockExposure:(id)sender { if (isExposureLocked) { [self.videoCamera unlockExposure]; [lockExposureButton setTitle:@"Lock exposure"]; isExposureLocked = NO; } else { [self.videoCamera lockExposure]; [lockExposureButton setTitle:@"Unlock exposure"]; isExposureLocked = YES; } } - (IBAction)actionLockBalance:(id)sender { if (isBalanceLocked) { [self.videoCamera unlockBalance]; [lockBalanceButton setTitle:@"Lock balance"]; isBalanceLocked = NO; } else { [self.videoCamera lockBalance]; [lockBalanceButton setTitle:@"Unlock balance"]; isBalanceLocked = YES; } }
The remaining fourth button will change the camera image orientation relative to the device orientation. It has two possible modes, and we just change the current mode in the action:
- (IBAction)rotationButtonPressed:(id)sender { videoCamera.rotateVideo = !videoCamera.rotateVideo; }
First, let's investigate the focus changing on iOS devices. The iOS camera API supports three modes for camera focus:
AVCaptureFocusModeLocked
: When enabled, the focus becomes fixed.AVCaptureFocusModeAutoFocus
: When enabled, the camera performs an autofocus operation and then returns to the locked mode.AVCaptureFocusModeContinuousAutoFocus
: When enabled, the camera continuously monitors focus and autofocuses as needed.
CvVideoCamera
uses the AVCaptureFocusModeContinuousAutoFocus
mode by default, so the focus may change with the scene. This can make the process of camera calibration much more difficult. The best way, in this case, is to set the focus to some special value (for example, infinity), but unfortunately, the iOS API doesn't contain all functions needed by computer vision specialists. There is no way to programmatically set the camera focus of an iOS device to infinity or any other predefined value. So we can only lock the current focus value. For that purpose, the CvVideoCamera
class provides the lockFocus
method. It changes the focus mode to the AVCaptureFocusModeLocked
value. In order to unlock it again, you should use the unlockFocus
function.
You can also control the exposure and white balance in the same way using lockExposure
and lockBalance
functions.
To control image rotation in camera, you can change the rotateVideo
property. The default value of this variable is NO
.
In this mode, the camera image will not be rotated with the device rotation. If you change this value, the image will be rotated every time a device changes its orientation by 90 degrees.
Each newly added button in this project allows you to switch between the two modes. To indicate mode changing, we'll change the button's text. For that purpose, you can use the setTitle
method.