-
Notifications
You must be signed in to change notification settings - Fork 340
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
Image whitening #96
Image whitening #96
Conversation
We noticed quite heavy flickering in the image output from the camera sensor. We tested an array of approaches to mitigate the issue. Primarily we perform whitening of the camera input. This improves the flow quality and stability immensely for us.
- Added parameter PARAM_IMAGE_WHITENING: * 0: no whitening * 1: always use whitening * 2: use whitening, if flow quality is low, recompute flow with non-whitened images - Added parameter PARAM_IMAGE_WHITENING_QUALITY_THRESHOLD (default 150): value of optic flow quality bellow which optical flow is recomputed from non-whitening images - Added separate buffers for whitened images
Note: In mode |
Thanks! I'll have a look at it as soon as possible. |
@jlecoeur Good work! I just had go with this PR and did some bench testing. The weird artifacts from #90 (comment) are now gone. Generally it seems to work well with my office conditions. |
@ChristophTobler Indeed. My understanding is that when the raw image is almost flat/featureless, image whitening is increasing image noise, so all blocks have high gradients after whitening, even though this is mostly noise. Thus all blocks pass the test with gradient larger than Another issue is that because whitened images generally have larger gradients, the thresholds |
@ChristophTobler Another idea: when images are mostly noise, the NUM_BLOCKS*NUM_BLOCKS optic flow estimates must have large standard deviation. |
Sounds like a good starting point. Would you have time next week to have a go at it? |
@LorenzMeier That worked! |
d75ce2a
to
398e9c3
Compare
I like that quality is now a more continuous indicator. However we have to be careful that optic flow is not rejected too often by filters on the PX4 side. |
@jlecoeur I agree. I would adjust the parameter in the Firmware. Probably between 20-50 depending on the setup/environment. |
@jlecoeur It actually already is very low https://github.com/PX4/Firmware/blame/master/src/modules/ekf2/ekf2_params.c#L684 |
Yes EKF2 will be fine but not LPE |
Yeah we should lower that, once this PR is in. I still want to do some actual flight tests. |
@jlecoeur Here's a log of a test flight https://logs.px4.io/plot_app?log=458daba2-d4d1-4e01-8ac9-6da289620e28. Worked nicely! Maybe I can get another test when it's a little darker outside. |
Nice thanks! |
That's fine. Did you do some test flights in a environment with mixed lighting conditions? |
This is awesome. With small changes (25 feature track, always whitening, all filtering on) I have a (slowly drifting) position. As I recalibrate with the higher level control software, I do not care about having any drift, but I care about having a position to be able to make safe autonomous takeoff. It was impossible with the master while perfectly working here. The drift (when not moving) is about 10cm/s while when I had no position and I regain it, it was sometimes some crazy 10m/s and we had multiple crashes. global_data.param[PARAM_SYSTEM_SEND_LPOS] = 0; //1
global_data.param[PARAM_IMAGE_WHITENING] = IMAGE_WHITENING_ALWAYS; // IMAGE_WHITENING_AUTO
global_data.param[PARAM_SONAR_FILTERED] = 1; // 0
global_data.param[PARAM_BOTTOM_FLOW_FEATURE_THRESHOLD] = 25; // 50
global_data.param[PARAM_BOTTOM_FLOW_HIST_FILTER] = 1; // 0
global_data.param[PARAM_BOTTOM_FLOW_GYRO_COMPENSATION] = 1; // 0
global_data.param[PARAM_BOTTOM_FLOW_LP_FILTERED] = 1; // 0
global_data.param[PARAM_EXPOSURE_MAX] = 125; // 500
global_data.param[PARAM_GAIN_MAX] = 8; // 16
global_data.param[DEBUG_VARIABLE] = 0; // 1 @jlecoeur I am not sure about the IMAGE_WHITENING_AUTO mode logic. I would prefer it to be a state machine which switches from "prefered white or normal". The actual implementation always computes the whitened image and if the whitened is too bad, try the other one. quality_whitened = compute_on_whitened_img()
if quality < threshold:
quality_normal = compute_on_normal_img()
if quality > quality_whitened:
used_whitened_image = true
else:
used_whitened_image = false
else:
used_whitened_image = true I would propose to use quality_white = 0
quality_normal = 0
if use_whitened_image:
quality_white = compute_on_whitened_img()
if quality_white < threshold:
quality_normal = compute_on_normal_img()
else:
quality_normal = compute_on_normal_img()
if quality_normal < threshold:
quality_white = compute_on_whitened_img()
use_whitened_image = (quality_white >= quality_normal) |
@AlexisTM good to hear that you had good results with it! If you could post a log that would be awesome.
Do you think some of these changes should be the default?
In practice quality_whitened is always higher than quality_normal except in corner cases like mixed bright/dark images. So the idea is to check first the whitened images to make sure that the highest quality is selected. |
@jlecoeur I don't think it would be the default except for
Are you sure it is the case on a sunny day outside? Indoor, it is indeed the case. |
10cm/s is already quite bad! Are you doing hand held tests when you say "not moving"? What is the environment like that you test in? Some logs would be good. |
@ChristophTobler I personally think that 10cm/s is pretty good as before I could only get a position at least 30/40cm from the ground. The sensor is at about 10cm of the ground, so the distance sensor is not at a valid distance (< 30 cm). You can still notice the bricks used before to fly from higher. (We do with what we have) On the ground: https://review.px4.io/plot_app?log=b902dd0e-70f6-4c06-bea1-2de5c0d25be8 Flight: Takeoff, hover, land - https://review.px4.io/plot_app?log=e3d447b1-bcde-455c-bba2-a8588b35a481 |
@AlexisTM Thanks! These seem a bit high and there is an offset https://review.px4.io/plot_app?log=b902dd0e-70f6-4c06-bea1-2de5c0d25be8#Nav-Raw-Angular-Speed-Gyroscope. Have you checked the calibration and dampening? I see you are flying offboard. But why are there no setpoints https://review.px4.io/plot_app?log=e3d447b1-bcde-455c-bba2-a8588b35a481#Nav-Local-Position-X? Can you maybe also provide a video of a flight? |
Video of the first flight - https://photos.app.goo.gl/AcevYPa7PVNV6tRF2 PS: I could not get the log of this flight due to a bug in QGC when too many logs are available or due to different log versions (switched to APM, PX4, different versions) and I did not take a video of the second flight. Also, the offboard control is done via velocity setpoints. |
@AlexisTM @jlecoeur @ChristophTobler Any updates on this one? Did we ever get this branch working correctly? Could someone summarise? |
I used this branch with success. It improves flow quality over surfaces with poor contrast. The reported flow quality is more linear with the actual flow quality, so LPE default setting should be updated to reduce the flow quality threshold. |
@mhkabir I am using my master: https://github.com/umdlife/Flow which works fine on a low light condition but has a change that should not be on the master. It is this PR + few changes:
This last change is not viable in production. It returns a quality of almost always 255 and therefore drifts more but we correct it using tags. Right now we are working on 1.6.5 which has a bug when the PX4Flow is not valid. (We were facing a bug on the v1.7.3 (Pixhawk related)). Full changes: Added 7.2.1 GNU toolchain: +CROSSDEV_VER_SUPPORTED = 4.7.4 4.7.5 4.7.6 4.8.2 4.8.4 4.9.3 5.4.1 7.1.0 7.2.0 7.2.1 Difference in settings:
|
We're quite interested in the results that have been presented here as we are experiencing similar position drifting issues. Is there any timeline to get this PR merged? Is there any other way to attenuate the problems by not whitening the image? Thanks! |
Hi @victordias2000 Let me try to rebase in the next week. |
That would be fantastic @jlecoeur !!! Thanks. |
I personally do not have a PX4 drone here, thus cannot help on it. Yet, we used this firmware quite heavily to allow low light environment. The actual repo used was: https://github.com/umdlife/Flow |
This has been open for a long time without activity. I am closing this PR. |
It has been helpful to me at the time, thanks for the contribution @jlecoeur \o/ |
This is a follow-up of #90. I rebased @lericson's work to latest master.
On top of that I added a third whitening mode for param
IMAGE_WHITEN
:IMAGE_WHITENING_DISABLED
(=0) : equivalent to masterIMAGE_WHITENING_ALWAYS
(=1) : performs image whitening before computing optic flowIMAGE_WHITENING_AUTO
(=2) : performs whitening before computing optic flow, if flow quality is lower than paramIMAGE_WHIT_QTHRES
, then recompute optic flow on the non-whitened image, use the optic flow with highest quality.I also added a debug message with the average DT. It gives an indication of the computation time added by each method:
IMAGE_WHITENING_DISABLED
: DT between 6.4ms and 6.6 msIMAGE_WHITENING_ALWAYS
: DT between 8.0ms and 8.2msIMAGE_WHITENING_AUTO
: DT between 8.0ms and 8.2ms with the defaultIMAGE_WHIT_QTHRES
=150, i.e. it was not never recomputing optic flow. By artificially raisingIMAGE_WHIT_QTHRES
to 256, I forced it to always recompute optic flow, and then DT was between 14.2ms and 14.4ms. But keep in mind that in real scenario it would recompute optic flow only for few frames (only when the flow quality is bad). I guess that in these cases it is better to have measurements at lower update rate than no measurement.FYI people from previous conversation @lericson @jgoppert @ChristophTobler @mhkabir @LorenzMeier
I have the same conclusions as in the previous PR: On the low textured floor that you can see in the pictures of #90, I have no optic flow with
IMAGE_WHITENING_DISABLED
. The quality is very good withIMAGE_WHITENING_ALWAYS
andIMAGE_WHITENING_AUTO
. I could not testIMAGE_WHITENING_AUTO
because the weather is bad today and it only kicks in when the luminosity varies a lot in the image.@ChristophTobler @lericson can you try with all three modes and report how it works for you?