-
Notifications
You must be signed in to change notification settings - Fork 31
Automatically determining exposure #174
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
base: main
Are you sure you want to change the base?
Conversation
scripts/measure/remote_capture.py
Outdated
print("ERROR:", error) | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is inside a function being called, it might be better to raise an error instead (to kill the script):
raise ValueError(error)
scripts/measure/remote_capture.py
Outdated
print("ERROR:", error) | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is inside a function being called, it might be better to raise an error instead (to kill the script):
raise ValueError(error)
scripts/measure/remote_capture.py
Outdated
print("Output image not found") | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is inside a function being called, it might be better to raise an error instead (to kill the script):
raise ValueError("Output image not found")
scripts/measure/remote_capture.py
Outdated
print("Failed to load captured image") | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here? I guess it's an error so:
Since this is inside a function being called, it might be better to raise an error instead (to kill the script):
raise ValueError("Failed to load captured image")
scripts/measure/remote_capture.py
Outdated
max_iter = 10 | ||
target_max = 4095 | ||
max_saturation_ratio = 0.001 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can these be exposed in the Hydra config? (max_iter, target max, max_saturation_ratio)
scripts/measure/remote_capture.py
Outdated
exp *= 0.7 if sat_ratio > max_saturation_ratio else 0.95 | ||
elif max_val >= 3800: | ||
exp *= 1.05 | ||
else: | ||
exp *= 1.4 | ||
|
||
return final_result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these increase and decrease factors (and other hardcoded values) would also be nice to set in the Hydra config. Like we do when measuring a dataset:
fact_increase: 2 # multiplicative factor to increase exposure |
in short, removing hard-coded values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and can add a sanity check before returning, namely assert final_result is not None
scripts/measure/remote_capture.py
Outdated
max_iter = 10 | ||
target_max = 4095 | ||
max_saturation_ratio = 0.001 | ||
final_img = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be final_result
? this seems to be how you call the image below
scripts/measure/remote_capture.py
Outdated
break | ||
|
||
max_val = int(np.max(img)) | ||
sat_ratio = np.sum(img == 4095) / img.size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of 4095, use config value
scripts/measure/remote_capture.py
Outdated
sat_ratio = np.sum(img == 4095) / img.size | ||
print(f"Max: {max_val} | Saturated: {sat_ratio*100:.4f}%") | ||
|
||
if max_val >= target_max and sat_ratio <= max_saturation_ratio: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in certain cases, we may want no saturation at all (like when measuring images). For example, max_saturation_ratio
may be None
, and we should handle that case
raise ValueError( | ||
"Out of resources! Use bayer for higher resolution, or increase `gpu_mem` in `/boot/config.txt`." | ||
) | ||
max_iter = 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this value to the config
Changes in the
on_device_capture.py
script1. New CLI flags
auto_exp_psf and auto_exp_img
Both flags initiate an iterative auto-exposure routine that captures multiple frames, analyzes their histograms, and adjusts the shutter time to avoid clipping while maximizing tonal range.
We distinguish them because auto_exp_img is more forgiving: even if its raw maximum pixel value settles around 3800, subsequent color correction can stretch it up to 4095. For full-frame images, our primary goal is simply to prevent large white highlights, not to hit an exact exposure level. In contrast, auto_exp_psf demands the highest precision for point-spread function measurements.
These flags integrate seamlessly with the existing Hydra configuration options.
2. Auto-exposure logic
PSF routine (
auto_exp_psf_locally
)Image routine (
auto_expose_image_locally
)Note: the “target range” check usually succeeds first, so the second condition is rarely needed.
PS : In both routines, each iteration logs attempt number, current exposure value, and histogram summary to help diagnose the process.
3. How it hooks into
main()
This lets users drive end-to-end auto-exposure entirely via flags, without manual adjusting.