How to set manual focus distance with libcamera / 64mp / C++

Is there a map between the int value and the real focal distance? (ex, Value 0 => 80mm, value 100 => N mm) ?

@AnotherDredd

This is the real value.But please don’t make this value too small, otherwise the effect may not be obvious, it is best to set it from 50.

Thanks, I will test that ASAP … probably next week.

@Z3bc2G Sure, if any questions you can let me know

Hi Edward. I’m confused:

Those are the results from a close up photo (at 80mm) from the camera

image

Picamera2 camera_controls

{'FrameDurationLimits': (8331, 71022464, 0), 'NoiseReductionMode': (0, 4, 0), 'AwbEnable': (False, True, 0), 'LensPosition': (0.0, 1000.0, 100.0), 'ExposureValue': (-8.0, 8.0, 0.0), 'ColourGains': (0.0, 32.0, 0), 'AfMode': (0, 2, 0), 'Brightness': (-1.0, 1.0, 0.0), 'AeEnable': (False, True, 0), 'AnalogueGain': (1.0, 10.079999923706055, 0), 'Saturation': (0.0, 32.0, 1.0), 'ExposureTime': (76, 71022430, 0), 'AeMeteringMode': (0, 3, 0), 'ColourCorrectionMatrix': (-16.0, 16.0, 0), 'AeConstraintMode': (0, 3, 0), 'AeExposureMode': (0, 3, 0), 'AfTrigger': (0, 1, 0), 'AwbMode': (0, 7, 0), 'ScalerCrop': (libcamera.Rectangle(0, 0, 256, 256), libcamera.Rectangle(0, 0, 5120, 2880), 0), 'Sharpness': (0.0, 16.0, 1.0), 'Contrast': (0.0, 32.0, 1.0)}

Focuser read
959

Metadata

{'SensorTimestamp': 8196990327000, 'ScalerCrop': (2704, 2032, 3840, 2880), 'DigitalGain': 1.0007247924804688, 'ColourGains': (1.4702939987182617, 2.179482936859131), 'SensorBlackLevels': (4096, 4096, 4096, 4096), 'AeLocked': False, 'Lux': 214.1499481201172, 'FrameDuration': 60028, 'ColourCorrectionMatrix': (1.4431895017623901, -0.2621518075466156, -0.18104535341262817, -0.3699720799922943, 1.457980751991272, -0.08800331503152847, -0.12651540338993073, -0.6927090287208557, 1.8192243576049805), 'AnalogueGain': 4.849999904632568, 'ColourTemperature': 3768, 'ExposureTime': 59994}

Then the same at 100mm

image

Picamera2 camera_controls

{'FrameDurationLimits': (8331, 71022464, 0), 'NoiseReductionMode': (0, 4, 0), 'AwbEnable': (False, True, 0), 'LensPosition': (0.0, 1000.0, 100.0), 'ExposureValue': (-8.0, 8.0, 0.0), 'ColourGains': (0.0, 32.0, 0), 'AfMode': (0, 2, 0), 'Brightness': (-1.0, 1.0, 0.0), 'AeEnable': (False, True, 0), 'AnalogueGain': (1.0, 10.079999923706055, 0), 'Saturation': (0.0, 32.0, 1.0), 'ExposureTime': (76, 71022430, 0), 'AeMeteringMode': (0, 3, 0), 'ColourCorrectionMatrix': (-16.0, 16.0, 0), 'AeConstraintMode': (0, 3, 0), 'AeExposureMode': (0, 3, 0), 'AfTrigger': (0, 1, 0), 'AwbMode': (0, 7, 0), 'ScalerCrop': (libcamera.Rectangle(0, 0, 256, 256), libcamera.Rectangle(0, 0, 5120, 2880), 0), 'Sharpness': (0.0, 16.0, 1.0), 'Contrast': (0.0, 32.0, 1.0)}

Focuser read 715

Metadata
{'SensorTimestamp': 8686485454000, 'ScalerCrop': (2704, 2032, 3840, 2880), 'DigitalGain': 1.000074028968811, 'ColourGains': (1.6726670265197754, 1.9570255279541016), 'SensorBlackLevels': (4096, 4096, 4096, 4096), 'AeLocked': False, 'Lux': 303.45867919921875, 'FrameDuration': 35602, 'ColourCorrectionMatrix': (1.6900042295455933, -0.5692741274833679, -0.12073886394500732, -0.4300917088985443, 1.4773222208023071, -0.04723991081118584, -0.13397414982318878, -0.4994589388370514, 1.6334331035614014), 'AnalogueGain': 4.0, 'ColourTemperature': 4292, 'ExposureTime': 35568}


So,

A) the values of “LensPosition” are not updated,
B) the values are inversely proportional to the distance.

  • 80mm => ~1000
  • 100mm => ~700

The composition of these values is ( min , max , default) and does not change.

B) the values are inversely proportional to the distance.

  • 80mm => ~1000
  • 100mm => ~700

I am sorry for this, I have communicated with the hardware engineer, this value is indeed mapped, the size of the vcmcode is set, and the value of the motor driver current is changed, not the real position.

Hi Edward,

I apologize because didn’t understand well your answer, so have further questions:

Will be the device lens position (in 0-1000 units) reflected on Metadata?
although is not critical because can be retrieved using subdev1 i2c query

Will be the real lens position (in millimeters) reflected on Metadata?
If is not, can you provide the map for the lens distance? Maybe as a subdev1 query?

thanks!

@AnotherDredd

Will be the device lens position (in 0-1000 units) reflected on Metadata?

libcamera does not provide an interface for reading similar values, and the method for reading subdev1 is also what I can think of at the moment. subdev1 only the value of the mapping you set can be found.

Will be the real lens position (in millimeters) reflected on Metadata?

There is currently no way to get the real value.If there are new developments, I will alert on this thread.

Found this:

We know camera sensor size, pixels, and maximum and ratio Only need the focal distance (IE, the distance from the lens to the sensor that should be somewhere in the specs of the focus device, as is the length of the rail the lense is moved)

EDIT:
Maximum focal length is 5.1mm as specs (https://www.arducam.com/wp-content/uploads/2022/06/arducam-pi-hawk-eye-specification_f.svg)

So, using the calculator in a completely naive way (I’m not a photography expert), found that the focal length range is: 0.025mm (80mm, 1000 units) ~ 5.1mm (Infinity, 0 units)


Hi, I finnaly found some time to test the new release.

First : thanks a lot, this looks working fine.

controls_.set(controls::AfMode, controls::AfModeManual);
controls_.set(controls::LensPosition, 200);

This is doing the job for setting the LensPosition.

Question 1 :
But is there a way to GET the curent LensPosition ?
( the idea is to use AF in RGB mode to get the LensPosition and to apply it later in RAW mode )

Question 2 :
About LensPosition values, is there a way to know max & min value ?

Thanks.

1 Like
  1. How to set manual focus distance with libcamera / 64mp / C++ - #14 by Edward

    Use reading subdev1 as FocuserExample.py does. Be warned its not a real distance but an abstract value.

  2. How to set manual focus distance with libcamera / 64mp / C++ - #12 by Edward

Thanks for your answer :innocent:

So by “reading subdev1” I will be able to get the actual controls::LensPosition value ?
Nice, I will try to do that.

Any link to a C++ sample about that ? :yum:

Hi,
FYI, I’ll post a link.

Does anyone know how to set these controls but in Python? Ive been looking at the Python Focuser example for hours, but can’t figure out how to just manually set a lens position myself and take a photo :slight_smile:

This looks like it works to change the focus in python manually for picamera2 (if it is updated to the latest version!)

Here is link to some example …

This is great! By the way, do you happen to know how to READ what the current focus level is?

For instance if i want to run the autofocus, and then use the focus that it arrived on and take multiple photos with the focus changed in either direction to do some focus stacking?

You can use Focuser.py provided with the driver package. Read and write.

1 Like

I searched, but it looks like it’s not possible to get a reading from autofocus. So the only way is to manually focus via focuser.py and then pass the data here to manual focus.

1 Like

The focuser.py program is somehow reading what the current focus level is, but im not sure how.

anyone have any ideas?