Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set camera focus at controlled fixed distance on Android

Tags:

android

camera

My device has only two focus modes, AUTO and FIXED (as per getSupportedFocusModes()). I want to set my camera at a fixed focus distance of 'x' (x being whatever I like, or whatever I can get from the camera..). (I'm aware of setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED), but this seems to be fixed only on the farthest possible setting..)

Can this be done? (Android version 4.2.2)

like image 794
Ysch Avatar asked Apr 24 '14 15:04

Ysch


People also ask

How to set camera parameters in android?

Camera service settings. To make camera parameters take effect, applications have to call Camera#setParameters(Camera. Parameters) . For example, after Camera.

How do you focus camera distance?

The basic concept is pretty simple. You focus on the closest thing to the camera, then focus on the farthest object, and then center the focusing ring halfway in between those distances. Not halfway out in the field, but halfway between the distance marks on the lens.


2 Answers

Not trying to completely answer the question here, just trying to give it some direction.
So, what you need here is a driver support for that kind of operation. Then at some point you'd ask the driver from your application to set a requested focus distance.

Another question is: "if anyone really needs that kind of functionality?".

Android documentation says:

public static final String FOCUS_MODE_FIXED
Focus is fixed. The camera is always in this mode if the focus is not adjustable. If the camera has auto-focus, this mode can fix the focus, which is usually at hyperfocal distance. Applications should not call autoFocus(AutoFocusCallback) in this mode.

Lets see what hyperfocal distance is.

Hyperfocal distance
From Wikipedia, the free encyclopedia

In optics and photography, hyperfocal distance is a distance beyond which all objects can be brought into an "acceptable" focus. There are two commonly used definitions of hyperfocal distance, leading to values that differ only slightly:

Definition 1: The hyperfocal distance is the closest distance at which a lens can be focused while keeping objects at infinity acceptably sharp. When the lens is focused at this distance, all objects at distances from half of the hyperfocal distance out to infinity will be acceptably sharp.

Definition 2: The hyperfocal distance is the distance beyond which all objects are acceptably sharp, for a lens focused at infinity.

The distinction between the two meanings is rarely made, since they have almost identical values. The value computed according to the first definition exceeds that from the second by just one focal length.

As the hyperfocal distance is the focus distance giving the maximum depth of field, it is the most desirable distance to set the focus of a fixed-focus camera.

So the focus is not set on the farthest possible setting, but is set to have all visible objects to be acceptably sharp.

Returning to the question.
If you happen to be a developer of this particular camera's firmware, you can add any needed IOCTLs to you driver. But then you still going to need to call them somehow. This can't be achieved without adding additional functions into the Android OS, and further recompiling of Android itself and it's underlying Linux kernel.
So it seems like you can't achieve this goal, not from the user space at least.

like image 197
mykolaj Avatar answered Oct 20 '22 23:10

mykolaj


One potential approach to achieve that fixed focus distance is to call autoFocus at the start of the camera life-cycle. Keep calling autoFocus sporatically until a condition is met. Once the condition is met, then instead of calling autoFocus, set a flag and call takePicture instead.

This is one solution that I have come to in order to get the desired effect that you might be looking to achieve.

So within my thread that is taking pictures continuously, the code looks something like this:

if(needsFocus)
{
    myCamera.autoFocus(autoFocusCallback);
}
else //Focus is not needed anymore at this point
{
    if(myCamera != null)
    {
        myCamera.startPreview();    
        myCamera.takePicture(pictureCallback);
    }
}

Once the condition is met, needsFocus is set to true. At this point, the focus is fixed at the place that I want it to be at. Then it won't change throughout the rest of the activities task. The condition for my case was the appearance of a particular object detected with the OpenCV library.

like image 28
Jay Snayder Avatar answered Oct 21 '22 00:10

Jay Snayder