-
Notifications
You must be signed in to change notification settings - Fork 194
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
[HOW-TO] Optimizing PiCam v3 Autofocus for a High-Altitude Balloon launch #1127
Comments
Hi, l'll try and answer a few of your questions, and then perhaps pass on some of the others!
|
I can't think of anything very helpful. The tuning file can be edited for a static offset - which might help in cases where a negative lens position would otherwise be required (since negative values are not allowed). It might also make AF more stable by reducing the loop gain. But this kind of imagery is challenging for PDAF as it doesn't contain much in the way of horizontal deltas (vertical gratings). |
On the question of offsets - is the 0.0 'infinity focus' position at the end of the lens travel range? Or can it go past this? What I'm still pretty unsure about is if the thermal issue we encountered in the fixed-lens-position flight was the infinity focus position ending up being at some 'negative travel' location. |
Clipping at 0.0 is a software limit only. In fact, the standard tuning has a tiny bias so 0.0 is slightly beyond infinity in most cameras, to allow for variation. If necessary, this margin can be increased by lowering the mapping from dioptres to hardware lens driver settings (values between 0 and 1023, where 512 means "zero drive current" and 1023 pushes the lens out for nearest focus; the usable range when horizontal and at room temperature is about 300-960 before the lens hits its end-stops). This can be done either in Python, or by copying and editing the camera tuning file. I also don't know the mechanism of the thermal effect: whether it causes an absolute shift in lens position or merely scales the current (the difference from 512) or something else... Is this the standard or the wide-angle lens? |
Standard lens. |
Well I don't know if it will help, but the following code snippet would offset everything by 3 dioptres, so that to focus on infinity you would now need to set lens position to +3.0
In short it's lowering the dioptres->driver mapping by 96 by reducing If you can discover the actual range of useful settings, set |
I can certainly give this a go! |
That is a good question. It ought to apply to the flipped image. I will have to do some more tests to check it happens consistently. |
Thanks! I did some tests myself, but without much conclusive results as I don't think my 'test scene' was working all that well. |
I have just done some tests and I think it's correct. Both Phase and Contrast statistics align with the image as received (after any flips, which are implemented inside the sensor). [It won't necessarily work the same on every sensor, e.g. those without hardware "flip" capability, but we don't currently support PDAF on any others.] |
OK, this is really good to know! I'm hoping to do a launch sometime in November using a PiCam v3 and autofocus. My thinking right now is I will use:
We will also now be sending the lens position in our downlinked telemetry, so we'll have this data at 1 Hz time resolution - should be interesting to see if it drifts during flight! I did get some 'fixed focus' IMX708 lenses from ArduCam to try.. unfortunately these really are fixed focus, the lens is glued in place, with the focus set too close to be useful... |
I've now integrated your lens offset example into my codebase, with the offset being provided as a command-line parameter. For a lens offset of -1, I end up with the map values pre/post of: It seems to be working, as my 'test scene' has moved from a lens position value of about 0.8 to 1.8-2.0. More testing to be done... |
Today we performed a high-altitude balloon launch with the PiCam v3, using autofocus and a lens offset of -1. Unfortunately it seemed that the offset of -1 was not enough, as we still ended up with the lens position clamping to 0 as we ascended into colder temperatures. Near the top of the flight we got a few better photos. We saw similar on the last flight with a PiCam v3, suggesting it's heating up again as we get to much higher altitudes. I have a lot of data from the flight, though scattered in various places that I'm trying to bring together.
Since it does look like the lens position was ending up at 0, I'm wondering if the offset needs to be increased further, or perhaps needs to be adjusted dynamically throughout the flight? |
Thank you for all the data. It is hard to test this stuff on the ground -- we do have a temperature controlled chamber but it's too small for camera experiments, especially those requiring focus at infinity. It sounds like the offset is helping, at least. Yes it is possible to increase it. The range of "raw" lens driver values (after the mapping has been applied) is 0-1023; this controls an electrical current rather than an absolute mechanical position. Under normal conditions there are hard stops at about 350 and 950 (i.e. settings outside this range have no further effect) but it's hard to say how that generalizes to other conditions. |
Thanks for the info - so in this case the -3 dioptre offset (-96 raw units) is really as far as we can go before hitting the mechanical limits of the lens. I guess this gives us something to test on the next flight - if that doesn't work, then there isnt anything else we can do. As for temperature testing, even lens position vs temperature data for a closer target would still probably provide valuable information, at least to confirm what direction the lens is 'shifting' with temperature! |
Related question - in the camera metadata we see the field 'FocusFoM'. Is this an output from the autofocus algorithms? |
Wow. Thank you! It's a piecewise linear mapping with (typically) 2 points. [d0,h0,d1,h1] ought to mean a forward mapping of: and a reverse mapping of So here I reckon 4.0 => 413; 1.0 => 317. I'm a bit confused about the scale for "sensor temp". Did it go up to 45C? Is this the camera's own temperature sensor? |
We have two focus metrics: this one is based on image contrast (CDAF) which is generally quite stable and reliable for an unchanging scene, but it has a flat top and doesn't tell AF in which direction to move. The other one (PDAF) is directional but flakier. PDAF is not currently included in the metadata. We mostly use PDAF, though when it's working, the two measures tend to agree quite well. |
To test infinity focus in a space constricted environment, you can use a close up lens. You can get those often in set like (+1, +2, +4, +10) from the well known online marketplaces with diameters ranging between 40mm to 80mm. With a +10 lens an object 100mm (1000mm/10) away from the camera is in focus, when the camera is adjusted to infinity. When I tried this, the theoretical value of 100mm did not match exactly, it was about 10-20mm off. But you can adjust the exact distance with a live preview and watching the FocusFoM value, adjusting the distance to match the value to real infinity focusing. The diameter of the lens does not really matter as every available lens is big enough for the Pi Camera to look through. Just build yourself some fixture to adapt it in front of the lens. |
Ok - the context here is that at the moment when we capture imagery to downlink, we capture a block of 5 images with a second gap between each, then pick the 'best' image out of that block. The current approach to picking the 'best' image is to pick the one that has the highest JPEG-compressed file size. Bigger file = More detail. I was thinking of adding an option to select the image based on the FocusFoM metric. Take a sequence of images, and downlink the one with the highest FocusFoM. |
Focus FoM is based on image gradients (after a bit of noise removal) and should correlate pretty well with the file-size approach and ought to reject the all-black images just as well. It only looks at a region of interest which IIRC defaults to the middle two cells of a 4x3-cell grid. I've just remembered that focus offset can vary with tilt as well as with temperature! (I'm a little mystified why smartphone cameras don't seem to suffer from that; perhaps they use an accelerometer...) |
nzottmann That's a good idea. Though relative to the focal length of this camera, 70cm is "not very far" from infinity and may still tell us something relevant about the temperature coefficient. ke5gdb's reported lens positions were surprisingly low, even at room temperature - we may have to revisit our default tuning. Now I am wondering whether to add a temperature coefficient to the AF algorithm in future... |
@njhollinghurst correct, "sensor temp" is what comes back in the image metadata. It did hit 45C when chamber ambient reached 25C. I just purchased a close up lens kit. It should be here by the end of the day. I'll also swing by Microcenter today and buy a new camera. The one I performed the testing with has already flown once and may have some FOD/dirt in or near the lens. I don't think this is an issue, but I'd like to eliminate all variables. Let me know if there are any specific test conditions or additional data you would like to see. |
Thanks. In the new year I will try to repeat this (and also with the standard V3 lens). If you're happy to do further tests, it would be great if you could also try ambient temperatures above 25C (maybe up to 40C) and for two different focus positions (say, ~infinity and ~20cm). We may be able to add temperature compensation to the focus algorithm (using the reported sensor temperature). I don't yet know if it should be purely additive or if it should also depend on focus position. Any changes will be made here. |
Give me a few days, and I'll see what I can do. I'll be out of office starting this Friday and won't be back until the new year, so hopefully there is chamber availability before then. @nzottmann with regards to the close up lenses: is there an ideal distance that I should have between the close up lens and the front element on the Pi Camera? |
@ke5gdb In my experience the exact distance between the close up lens and the camera module did not matter. I mounted it with a distance of about 10mm. You will have to adjust the distance to the object to be sharp when focused to infinity anyways, as the theoretical value of 100mm is only approximately correct. |
I imagine a much weaker lens, such as [EDIT] +2 dioptres, is called for here. |
Describe what it is that you want to accomplish
Figure out how to make the autofocus behave better on a High-Altitude Balloon flight.
We've been launching PiCameras of various types on high altitude balloon payloads for many years. The fixed/adjustable focus PiCam2 and PiCamHQ cameras work pretty well, though the PiCam2 image quality leaves a little to be desired, and the PiCamHQ can be quite heavy if you put a good lens on it. The PiCam v3 looks to be a nice option... however there are issues.
Normally we want to set the focus to near-infinity. I usually adjust the focus using a distant house down my street. On the PiCam v3 we can set the lens position to 0.0, which on-ground looks fine.
However, on our first flight with a PiCam v3 in this configuration, we found that the actual lens position appears to drift with temperature, resulting in fuzzy images as the camera got cold, then better again as it got warmer at the top of the flight (>30km altitude).
See here and here for examples of the fuzzy images.
So, onto trying out Autofocus.
The typical image payload configuration has the camera pointing roughly at the horizon. I say roughly, as the payloads swing and spin under the balloon, so the field of view is always moving around. A PiCamv3 had been successfully used on a balloon launch in the UK with good results, but in that case there was a 'target' (Babbage the teddybear!) in the centre of the frame, so the autofocus probably had an easier job.
We bit the bullet and Andrew KE5GDB tried out a PiCam v3 in continuous autofocus mode without a focus target on a launch a few weeks ago. Our observations:
So, some questions:
(1152, 1296, 2304, 1036)
be appropriate?I get that this use-case is pretty out-of-spec for the camera, but it would be great if we could figure out a way to make use of them in a flight.
Describe alternatives you've considered
Additional context
While the entire code is a bit long, I'm essentially doing this:
The text was updated successfully, but these errors were encountered: