Search code examples
c#opencvemgucvdirectshow.net

How to lock autofocus


Is there a way to prevent auto-focus from focusing, using any of the "standard" libraries, such as OpenCV, EmGU, DirectShow, etc?

I want auto-focus to find the optimal focus, then during video capture, prevent auto-focus from auto-focusing.

I know I can manually set the value, but that defeats the purpose of using auto-focus, and I have yet to find a way to obtain the optimal focus value as determined by the auto-focus.


Solution

  • 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.