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

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?

You can find this line in focuser.py

self.focus_value = v4l2_utils.get_ctrl(self.fd, Focuser.FOCUS_ID)

Personally, I don’t think this value is set by autofocus, but only if I set it with the previous command when using manual focus or this utility.

1 Like

cool! ill try that out!

so what i have noticed about the focuser example is this:

If i run a command using the autofocus in a different program and focus on something up close, and then close the program, and then i run the focuser example it starts up with a specific number (let’s say like 856)

then if i close that example, and run a different program to autofocus on something else, let’s say in the middle distance, and then i close that program, and open up the focuser again, it will start up with a different number (let’s say 439). So it looks to me like it’s somehow reading what the last focused value of the camera was.

(caveat - Ive never actually gotten the focuser example to work (is it supposed to show you a preview image? because i just see a black screen with text, do other people see a preview image with the focuser example? it seems like that would make sense right?)