-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] LensPosition control ignored in still configuration with AfMode set to manual. #800
Comments
Hi, it always takes a few frames for a control to take effect - what happens if you put a |
|
The libcamera design is that controls happen asynchronously from capturing frames. Normally I think you would be expected to check the image metadata to discover when the change has happened, though I couldn't totally guarantee how well that works with the lens mechanism as that is totally asyncrhonous. But I don't really understand why you need to wait for 2 seconds. The delay getting controls through the pipeline should be a few frames at most, plus a few milliseconds for the lens actually to move. You might also have more luck if you set the controls after |
Considering What I noticed is that libcamera-apps seem to open the camera always twice. My snippet above however only opens it once. Output of
|
The folks over at MediaMTX had a similar issue with auto focus not working in video but found a solution: bluenviron/mediamtx#2326 Maybe these issues are connected somehow? I'm not sure. |
I'm not sure, it seems to be a very different environment and they seem to have fixed something. To make progress with this, I'd love to see some tests that show that AF can be turned on/off and the AfMode metadata confirms that this is happening. Can we confirm that when it's in continuous mode, it works as expected? Can we confirm that in manual mode, it never moves spontaneously? Can we confirm that we you set the lens position in manual mode then it does move as instructed (just with some delay) and then stays there? Could you also include the precise script you're using for this test. Thanks. |
They fixed it by doing an initial scan via libcamera. Something picamera2 might be missing? (The libcamera-still application also seems to open the camera twice, maybe to achieve the same thing?) I wrote a test per your request (requires the from picamera2 import Picamera2
from libcamera import controls
import exifread
import time
test_file = "test.jpg"
log_file = "log.txt"
tests = [
# af_mode lens_pos sleep_time
[controls.AfModeEnum.Auto, None, 0.5],
[controls.AfModeEnum.Auto, None, 1.0],
[controls.AfModeEnum.Auto, None, 2.0],
[controls.AfModeEnum.Continuous, None, 0.5],
[controls.AfModeEnum.Continuous, None, 1.0],
[controls.AfModeEnum.Continuous, None, 2.0],
[controls.AfModeEnum.Manual, 10.0, 0.5],
[controls.AfModeEnum.Manual, 10.0, 1.0],
[controls.AfModeEnum.Manual, 10.0, 2.0]
]
def take_snapshot(af_mode, lens_pos, sleep_time):
""" Instantiates a new Picamera2 instance, configures
it according to test params and captures to test_file."""
picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration())
picam2.start()
picam2.set_controls({"AfMode" : af_mode})
if lens_pos:
picam2.set_controls({"LensPosition" : lens_pos})
time.sleep(sleep_time)
picam2.capture_file(test_file)
picam2.stop()
picam2.close()
def log_exif(af_mode, lens_pos, sleep_time):
""" Reads EXIF data from current test_file and
appends it to log_file."""
with open(test_file, 'rb') as p:
tags = exifread.process_file(p)
with open(log_file, 'a') as l:
l.write(f"### EXIF Tags for snapshot with af_mode={af_mode}, lens_pos={lens_pos}, sleep_time={sleep_time}\n")
for k,v in tags.items():
l.write(f"{k}: {v}\n")
l.write("\n")
for test in tests:
take_snapshot(test[0], test[1], test[2])
log_exif(test[0], test[1], test[2]) Logs on my end:
Currently, it doesn't seem to store any information about focus.
I assume that is the focus distance for the given lens position at that time. |
You're right that Picamera2 doesn't store the lens position in the exif data. I didn't know libcamera-apps even did that. Is the problem here that there's no exif data for the lens? Or is it that the lens is or is not moving correctly? I'm afraid I'm starting to lose the thread of what we think is wrong here. Maybe you could post another short Python script (as you did initially) that does something wrong and we can look again at that? Thanks. |
No, I don't need the EXIF data.
That is indeed the problem. I updated the script to take seperate pictures for each test and reordered the tests by sleep time: from picamera2 import Picamera2
from libcamera import controls
import exifread
import time
test_file = "test.jpg"
log_file = "log.txt"
tests = [
# af_mode lens_pos sleep_time
[controls.AfModeEnum.Auto, None, 0.5], #0
[controls.AfModeEnum.Continuous, None, 0.5], #1
[controls.AfModeEnum.Manual, 10.0, 0.5], #2
[controls.AfModeEnum.Auto, None, 1.0], #3
[controls.AfModeEnum.Continuous, None, 1.0], #4
[controls.AfModeEnum.Manual, 10.0, 1.0], #5
[controls.AfModeEnum.Auto, None, 2.0], #6
[controls.AfModeEnum.Continuous, None, 2.0], #7
[controls.AfModeEnum.Manual, 10.0, 2.0], #8
[controls.AfModeEnum.Auto, None, 5.0], #9
[controls.AfModeEnum.Continuous, None, 5.0], #10
[controls.AfModeEnum.Manual, 10.0, 5.0] #11
]
def take_snapshot(af_mode, lens_pos, sleep_time, index):
""" Instantiates a new Picamera2 instance, configures
it according to test params and captures to test_file."""
picam2 = Picamera2()
picam2.configure(picam2.create_still_configuration())
picam2.start()
picam2.set_controls({"AfMode" : af_mode})
if lens_pos:
picam2.set_controls({"LensPosition" : lens_pos})
time.sleep(sleep_time)
picam2.capture_file(f"{index}_{test_file}")
picam2.stop()
picam2.close()
def log_exif(af_mode, lens_pos, sleep_time, index):
""" Reads EXIF data from current test_file and
appends it to log_file."""
with open(f"{index}_{test_file}", 'rb') as p:
tags = exifread.process_file(p)
with open(log_file, 'a') as l:
l.write(f"### EXIF Tags for snapshot with af_mode={af_mode}, lens_pos={lens_pos}, sleep_time={sleep_time}\n")
for k,v in tags.items():
l.write(f"{k}: {v}\n")
l.write("\n")
idx = 0
for test in tests:
take_snapshot(test[0], test[1], test[2], idx)
log_exif(test[0], test[1], test[2], idx)
idx = idx + 1 Of all tests, only 7, 8, 10 & 11 achieved the correct focus. All others resulted in blurry images (including test 9 with AfMode:Auto and 5 seconds sleep before capture). |
Thanks for the code. When using Auto mode, I don't actually see it triggering an autofocus cycle. Maybe have a look at section 5.2.4 of the manual to see if that helps. Putting those aside for the moment, that means we have this:
Does that sound like an appropriate test case to discuss? One thing I notice is that you're using a full resolution configuration which will give you a very slow framerate by default. That means that requests (containing AF commands, for example) get queued up and take longer to be handled. I'm still a bit surprised, though, TBH. Perhaps try adding Another alternative would be to run in a faster preview mode, and then do a mode switch just for the capture. That's how all the libcamera-apps work. |
Yes that's a good test case for this issue and works as expected. I will look into trying to use the preview mode without an actual connected display. I did indeed miss triggering the autofocus cycle with AfMode:Auto. |
This issue is still present. I've been trying to make a script to find the appropriate lens position to focus on targets that are a set distance away. All the pictures are the same. I've tried sleeping for up to 10 seconds after setting the controls but nothing. I've also tried autofocus_cycle() which is the only thing that seems to actually change anything |
@WillisAllen Am I right in thinking this is now a new issue being raised? Is so, could you maybe file a new report, please? Don't forget to include:
Thanks! |
Hi, and thanks for the report. Could you maybe file it as a new issue, please - no point spamming others in this thread who aren't having this problem. Thanks! |
Describe the bug
Setting
AfMode = AfModeEnum.Manual
andLensPosition = 10.0
(Or anything else between 0 and 10) withPicamera2.set_controls()
does not set the lens position on supported cameras.To Reproduce
Script:
Expected behaviour
An image file focused at approx. 10 centimeters when LensPosition is set to 10.0.
Console Output, Screenshots
Output looks fine:
Hardware :
Raspberry Pi Zero W + Raspberry Camera Module V3
Additional context
picamera2 version: 0.3.12-2
libcamera version: 0.0.5+83-bde9b04f
Everything works fine using libcamera-apps. The following command produces the expected image focused at 10 centimeters:
libcamera-jpeg -n --autofocus-mode manual --lens-position 10.0 -o test.jpg
The text was updated successfully, but these errors were encountered: