Disable Webcam's Autofocus in Linux

Disable webcam's Autofocus in Linux

Use program v4l2-ctl from your shell to control hardware settings on your webcam. To turn off autofocus just do:

v4l2-ctl -c focus_auto=0

You can list all possible controls with:

v4l2-ctl -l

The commands default to your first Video4Linux device, i.e. /dev/video0. If you got more than one webcam plugged in, use -d switch to select your target device.


Installing v4l-utils

Easiest way to install the utility is using your package manager, e.g. on Ubuntu or other Debian-based systems try:

apt-get install v4l-utils

or on Fedora, CentOS and other RPM-based distros use:

yum install v4l-utils

How to lock autofocus

You can detect when the image is focused during calibration phase (when you are finding the optimal focus) and save that configuration (focus distance). Then set the focus to the saved value and disable auto-focus before capturing phase. To find the optimal focus distance you can start with the most close (macro) focus distance and gradualy raise it to maximum, measuring how focused the image is.

This SO question has an answer that describes how to measure if the image is focused or not. You can use OpenCV Laplacian() (Emgu.CV) to achieve that.

The key is that in-focus image has much more strong gradients and sharp features. So what I suggest is to apply a Gaussian Laplace filter and then look at the distribution of pixel values of the result. The in-focus one has much more high values (because the image has more sharp gradients).

Another interesting way to determine best focus is described in this article. The technique is used in the NASA Curiosity Mars Rover. The idea is to JPEG-compress the frames and use the size of jpegs as the measure of focus.

The autofocus command instructs the camera to move to a specified starting motor count position and collect an image, move a specified number of steps and collect another image, and keep doing so until reaching a commanded total number of images, each separated by a specified motor count increment. Each of these images is JPEG compressed (Joint Photographic Experts Group; see CCITT (1993)) with the same compression quality factor applied. The file size of each compressed image is a measure of scene detail, which is in turn a function of focus (an in-focus image shows more detail than a blurry, out of focus view of the same scene).

OpenCV imencode() (Emgu.CV) can be used to compress the image in JPEG.

If you want to focus on some specific stable object or area and you are able to calculate / recognize its fixed position, you should process only that area to determine best focus. In the first approach you can apply Laplacian to cropped rectangular area or even use not rectangular mask for result "focus value" calculation if you know shape of the object. The same is for the second approach - compress only the region of interest you want to focus at. If you want it to process not rectangular areas and know the shape of the region, first set all pixels which do not cover the region you focus at to same color. It will make the algorithm not to take account of regions you do not need to be focused.

How to programmatically disable the auto-focus of a webcam?

The Hercules cameras are UVC compliant, so they should work with the DirectShow Interface IAMCameraControl. You can set the focus to a specific value, and use the flags to set that you do not want it to be automatic. You can use IAMCameraControl::Get to poll the current state, because not all cameras do support turning off the focus.

IAMCameraControl *pCameraControl; 
HRESULT hr;
hr = pFilter->QueryInterface(IID_IAMCameraControl, (void **)&pCameraControl);
if (hr == S_OK) {
long defaultFocusValue;
hr = pCameraControl->GetRange(CameraControl_Focus,
NULL, // min
NULL, // max
NULL, // minstep
&defaultFocusValue, // default
NULL); // capflags
hr = pCameraControl->Set(CameraControl_Focus, // property
defaultFocusValue, // value
CameraControl_Flags_Manual);
}

Focus has a range which is defined by each camera separately, so you should query it as shown to find the default value and the min, max if you want.
In this example the pFilter is a pointer to the input filter that you have from DirectShow. You can get it by enumerating the devices and finding the one you want.

How to programatically disable the auto-focus of two webcams in opencv

The IAMCameraControl interface is exposed on the DirectShow capture filter. You're not showing how you've obtained this interface, but in general you would need to get a separate instance of this interface from each capture filter as in (C# code example):

IAMVideoProcAmp VideoProcAmp1 { get { return cap1 as IAMVideoProcAmp; } }
IAMVideoProcAmp VideoProcAmp2 { get { return cap2 as IAMVideoProcAmp; } }


Related Topics



Leave a reply



Submit