-
Notifications
You must be signed in to change notification settings - Fork 1.2k
ports/alif: Improve PAG7936 Image Quality. #2911
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: master
Are you sure you want to change the base?
ports/alif: Improve PAG7936 Image Quality. #2911
Conversation
a785163 to
c41fc4b
Compare
c41fc4b to
0c1d134
Compare
|
Code Size Report:
|
iabdalkader
left a comment
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.
Mostly okay. Main change: Rework the API..
common/average.c
Outdated
| @@ -0,0 +1,81 @@ | |||
| /* | |||
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.
I don't like this API, it should be omv_csi_x. For example, omv_csi_stats_t, and functions moved to common/omv_csi.c: omv_csi_stats_update etc...
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.
Done, renamed it to awb as it's controlling that.
lib/imlib/bayer.c
Outdated
|
|
||
| for (int i = 0; i < 256; i++) { | ||
| int v = fast_roundf(((fast_powf(i * (1.0f / 255.0f), gamma) * contrast) + brightness) * 255.0f); | ||
| gamma_lut[i] = IM_CLAMP(v, 0, 255); |
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 recalculated on every call or when those values change?
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.
I was going to expose the brightness/contrast controls to the sensor API later on. It only needs to be done when the value changes, however, the lut part is an implementation detail. So, it shouldn't leave bayer.c. I can move the table update to another function call that's only done on value changes.
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.
Done
common/omv_csi.c
Outdated
| NULL, NULL | ||
| }; | ||
|
|
||
| #if defined(OMV_CSI_RGB_AVG_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.
| #if defined(OMV_CSI_RGB_AVG_SIZE) | |
| #if defined(OMV_CSI_STATS_ENABLE) |
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.
Done
lib/imlib/bayer.c
Outdated
| // FIXME: This needs to be placed in the DTCM. .bss is in the DTCM on Alif. But, this is not portable. | ||
| // Move this to a proper DTCM section for other platforms. | ||
| static uint8_t gamma_lut[256]; |
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.
@iabdalkader - Ideas on how to solve this? It needs to be in the DTCM because that has the quad read port on the AE3.
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.
If you want a DTCM section, just add one (e.g, OMV_FAST_MEMORY), what's the problem?
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.
Moved to the other PR with fast memory.
d9198cf to
6ebfde0
Compare
iabdalkader
left a comment
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.
There might be more comments, you should start with the gamma lut PR then we'll have another look at this.
boards/OPENMV_AE3/omv_boardconfig.h
Outdated
| // Camera interface | ||
| #define OMV_CSI_BASE ((CPI_Type *) CPI_BASE) | ||
| #define OMV_CSI_CLK_FREQUENCY (24000000) | ||
| #define OMV_CSI_AWB_ENABLE |
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.
| #define OMV_CSI_AWB_ENABLE | |
| #define OMV_CSI_STATS_ENABLE (1) |
There are two different things here: the CSI collects stats, and the image library does something with the stats (AWB). This enables collecting stats, what you do with those stats is a different story. omv_csi_awb_get doesn't make sense.
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.
Done
common/omv_csi.h
Outdated
| #if defined(OMV_CSI_AWB_ENABLE) | ||
| typedef struct omv_csi_awb { | ||
| bool enable; | ||
| bool initialized; | ||
| uint32_t last_ms; | ||
| float r_ema; | ||
| float g_ema; | ||
| float b_ema; | ||
| } omv_csi_awb_t; | ||
| #endif // defined(OMV_CSI_AWB_ENABLE) |
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.
| #if defined(OMV_CSI_AWB_ENABLE) | |
| typedef struct omv_csi_awb { | |
| bool enable; | |
| bool initialized; | |
| uint32_t last_ms; | |
| float r_ema; | |
| float g_ema; | |
| float b_ema; | |
| } omv_csi_awb_t; | |
| #endif // defined(OMV_CSI_AWB_ENABLE) | |
| #if OMV_CSI_STATS_ENABLE | |
| typedef struct omv_csi_stats { | |
| bool enable; | |
| bool initialized; | |
| uint32_t last_ms; | |
| float r_avg; | |
| float g_avg; | |
| float b_avg; | |
| } omv_csi_stats_t; | |
| #endif // OMV_CSI_STATS_ENABLE |
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.
Done
common/omv_csi.h
Outdated
| #if defined(OMV_CSI_AWB_ENABLE) | ||
| // Update RGB moving average struct. | ||
| void omv_csi_awb_update(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b, uint32_t ms); | ||
|
|
||
| // Get RGB moving average values. | ||
| void omv_csi_awb_get(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b); | ||
| #endif // defined(OMV_CSI_AWB_ENABLE) |
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.
| #if defined(OMV_CSI_AWB_ENABLE) | |
| // Update RGB moving average struct. | |
| void omv_csi_awb_update(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b, uint32_t ms); | |
| // Get RGB moving average values. | |
| void omv_csi_awb_get(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b); | |
| #endif // defined(OMV_CSI_AWB_ENABLE) | |
| #if OMV_CSI_STATS_ENABLE | |
| // Update RGB stats. | |
| void omv_csi_stats_update(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b, uint32_t ms); | |
| // Get RGB stats. | |
| void omv_csi_get_stats(omv_csi_t *csi, uint32_t *r, uint32_t *g, uint32_t *b); | |
| #endif // OMV_CSI_STATS_EMA_ALPHA |
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.
Done
lib/imlib/bayer.c
Outdated
| // FIXME: This needs to be placed in the DTCM. .bss is in the DTCM on Alif. But, this is not portable. | ||
| // Move this to a proper DTCM section for other platforms. | ||
| static uint8_t gamma_lut[256]; |
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.
If you want a DTCM section, just add one (e.g, OMV_FAST_MEMORY), what's the problem?
lib/imlib/bayer.c
Outdated
|
|
||
| // FIXME: This needs to be placed in the DTCM. .bss is in the DTCM on Alif. But, this is not portable. | ||
| // Move this to a proper DTCM section for other platforms. | ||
| static uint8_t gamma_lut[256]; |
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.
Here's my suggestion: Move this to imlib.c, initialize in init0, while we're at it, please rename imlib_init/deinit_all to just imlib_init/deinit.
Please send this in a new PR first.
I'd also consider mapping the input from an easier to work with range, like: 0.0f..1.0f or 0..255, to make it easier to pass down from Python. This can also be done in the Python module.
We can later implement set_brightness/contrast/gamma, have them call this function to update the table.
| static uint8_t gamma_lut[256]; | |
| #if ENABLE_GAMMA_LUT | |
| // extern in header | |
| uint8_t gamma_lut[256]; | |
| #endif | |
| void imlib_init0() { | |
| #if ENABLE_GAMMA_LUT | |
| imlib_update_gamma_table(-0.2f, 1.0f, 2.2f); | |
| #endif | |
| } | |
| #if ENABLE_GAMMA_LUT | |
| // brightness: -1.0 to 1.0, contrast: 0.0 to 2.0, gamma: 0.0 to inf. | |
| void imlib_update_gamma_table(float brightness, float contrast, float gamma) { | |
| for (int i = 0; i < 256; i++) { | |
| int v = fast_roundf(((fast_powf(i * (1.0f / 255.0f), (1.0f / gamma)) * contrast) + brightness) * 255.0f); | |
| gamma_lut[i] = IM_CLAMP(v, 0, 255); | |
| } | |
| } | |
| #endif |
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.
Moved to: #2914
I'd also consider mapping the input from an easier to work with range, like: 0.0f..1.0f or 0..255, to make it easier to pass down from Python. This can also be done in the Python module.
I tried to match the way arguments are passed to the function gamma().
We can later implement set_brightness/contrast/gamma, have them call this function to update the table.
Yes, but, note, the original code with it just recalculates every time was the easiest for handle future updates. This table will need to be moved to the CSI struct after brightness/contrast controls are exposed, as it technically needs to be reset on sensor reset and varies per sensor, since sensors can be controlled independently.
Anyway, the current method is the best for it being static at the moment, but, expect it to be refactored again shortly.
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.
I tried to match the way arguments are passed to the function gamma().
That function applies gamma correction to an image, right? I think we actually need to match these functions instead https://docs.openmv.io/library/omv.sensor.html#sensor.set_contrast
But the -3 to 3 range is also a really horrible artifact from the past. Perhaps we should refactor those to accept 0..100, or floats.
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.
I like the current float format for gamma() as it's normalized and can easily map to anything.
-3 to 3 range is also a really horrible artifact from the past
Agreeded :)
common/omv_csi.c
Outdated
|
|
||
| // Return the current average. | ||
| *r = fast_roundf(awb->r_ema); | ||
| *g = fast_roundf(awb->g_ema); | ||
| *b = fast_roundf(awb->b_ema); |
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.
The function below, already does that, just call it.
| // Return the current average. | |
| *r = fast_roundf(awb->r_ema); | |
| *g = fast_roundf(awb->g_ema); | |
| *b = fast_roundf(awb->b_ema); |
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.
Done
924c56b to
ecc3781
Compare
common/omv_csi.h
Outdated
| bool enable; | ||
| bool initialized; | ||
| uint32_t last_ms; | ||
| float r_avg; | ||
| float g_avg; | ||
| float b_avg; |
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.
| bool enable; | |
| bool initialized; | |
| uint32_t last_ms; | |
| float r_avg; | |
| float g_avg; | |
| float b_avg; | |
| float r_avg; | |
| float g_avg; | |
| float b_avg; | |
| uint32_t last_ms; |
Can we use r_avg==0 to detect if it's initialized or not? Or bad idea?
Also please add bool stats_enabled to csi_t directly.
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 we use r_avg==0 to detect if it's initialized or not? Or bad idea?
No, we don't want to do that as once I add black line calibration (which subtracts the value of pixels when seeing pure black, like when the lens cap is on), then it's quite possible to have the image go to all 0 in a dark scene.
Also please add bool stats_enabled to csi_t directly.
Done
The image turning green previously was caused by the rgb stats not being sampled continously (only every 100 frames) coupled with only happening on snapshot. As such, any algorithm causing the fps to slow down would lower the update freq. The new average solution ensures that the rgb average is smoothed over many frames and only keeps the last 250ms of history.
This also resolves issues with the luminace target flickering as the average cannot update instantly which filters out flicking on the PS5520 updating its settings quickly.
ecc3781 to
bf0d931
Compare
Fixes issues with the speed of the AWB algorithm and enables controls to enable/disable it.