From 1a97c4dfc4f1c617c09f5cd494b531163f5692e7 Mon Sep 17 00:00:00 2001 From: CitizenOneX <17427385+CitizenOneX@users.noreply.github.com> Date: Tue, 4 Mar 2025 14:05:44 +1100 Subject: [PATCH 1/5] #233 In auto exposure and white balance loop, scale per-channel rgb gains so none exceed new parameter rgb_gain_limit --- source/application/lua_libraries/camera.c | 104 +++++++++++++++++----- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index 0d9d6b1b..5cfb8e61 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -50,11 +50,11 @@ static struct camera_auto_last_values double green_gain; double blue_gain; } last = { - .shutter = 500.0f, + .shutter = 4096.0f, .analog_gain = 1.0f, - .red_gain = 1.9f, - .green_gain = 1.0f, - .blue_gain = 2.2f, + .red_gain = 121.6f, + .green_gain = 64.0f, + .blue_gain = 140.8f, }; static struct camera_capture_settings @@ -564,8 +564,9 @@ static int lua_camera_auto(lua_State *L) camera_metering_mode_t metering = AVERAGE; double target_exposure = 0.18; double exposure_speed = 0.50; - double shutter_limit = 1600.0; - double analog_gain_limit = 60.0; + double shutter_limit = 8192.0; + double analog_gain_limit = 16.0; + double rgb_gain_limit = 141.0; // Default white balance settings double white_balance_speed = 0.5; @@ -655,6 +656,17 @@ static int lua_camera_auto(lua_State *L) lua_pop(L, 1); } + + if (lua_getfield(L, 1, "rgb_gain_limit") != LUA_TNIL) + { + rgb_gain_limit = luaL_checknumber(L, -1); + if (rgb_gain_limit < 0.0 || rgb_gain_limit > 1023.0) + { + luaL_error(L, "rgb_gain_limit must be between 0 and 1023"); + } + + lua_pop(L, 1); + } } // Get current brightness from FPGA @@ -668,6 +680,25 @@ static int lua_camera_auto(lua_State *L) double matrix_g = metering_data[4] / 255.0f; double matrix_b = metering_data[5] / 255.0f; + if (spot_r == 0.0) { + spot_r = 0.0001; + } + if (spot_g == 0.0) { + spot_g = 0.0001; + } + if (spot_b == 0.0) { + spot_b = 0.0001; + } + if (matrix_r == 0.0) { + matrix_r = 0.0001; + } + if (matrix_g == 0.0) { + matrix_g = 0.0001; + } + if (matrix_b == 0.0) { + matrix_b = 0.0001; + } + double spot_average = (spot_r + spot_g + spot_b) / 3.0; double matrix_average = (matrix_r + matrix_g + matrix_b) / 3.0; double center_weighted_average = (spot_average + @@ -777,19 +808,6 @@ static int lua_camera_auto(lua_State *L) double blending_factor = (scene_brightness - white_balance_min_activation) / (white_balance_max_activation - white_balance_min_activation); - - if (red_gain > 1023.0) - { - red_gain = 1023.0; - } - if (green_gain > 1023.0) - { - green_gain = 1023.0; - } - if (blue_gain > 1023.0) - { - blue_gain = 1023.0; - } if (blending_factor > 1.0) { blending_factor = 1.0; @@ -811,9 +829,51 @@ static int lua_camera_auto(lua_State *L) (blue_gain - last.blue_gain) + last.blue_gain; - uint16_t red_gain_uint16 = (uint16_t)(last.red_gain * 256.0); - uint16_t green_gain_uint16 = (uint16_t)(last.green_gain * 256.0); - uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain * 256.0); + double max_rgb_gain = last.red_gain > last.green_gain + ? (last.red_gain > last.blue_gain + ? last.red_gain + : last.blue_gain) + : (last.green_gain > last.blue_gain + ? last.green_gain + : last.blue_gain); + + // Scale per-channel gains so the largest channel is at most rgb_gain_limit + if (max_rgb_gain > rgb_gain_limit) + { + double scale_factor = rgb_gain_limit / max_rgb_gain; + last.red_gain *= scale_factor; + last.green_gain *= scale_factor; + last.blue_gain *= scale_factor; + } + + if (last.red_gain > 1023.0) + { + last.red_gain = 1023.0; + } + if (last.red_gain <= 0.0) + { + last.red_gain = 0.0001; + } + if (last.green_gain > 1023.0) + { + last.green_gain = 1023.0; + } + if (last.green_gain <= 0.0) + { + last.green_gain = 0.0001; + } + if (last.blue_gain > 1023.0) + { + last.blue_gain = 1023.0; + } + if (last.blue_gain <= 0.0) + { + last.blue_gain = 0.0001; + } + + uint16_t red_gain_uint16 = (uint16_t)(last.red_gain); + uint16_t green_gain_uint16 = (uint16_t)(last.green_gain); + uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain); check_error(i2c_write(CAMERA, 0x5180, 0x03, red_gain_uint16 >> 8).fail); check_error(i2c_write(CAMERA, 0x5181, 0xFF, red_gain_uint16).fail); From a9ea62276c11f0bebd0f964dc4f0921fe810b2af Mon Sep 17 00:00:00 2001 From: CitizenOneX <17427385+CitizenOneX@users.noreply.github.com> Date: Tue, 4 Mar 2025 14:05:44 +1100 Subject: [PATCH 2/5] #233 In auto exposure and white balance loop, scale per-channel rgb gains so none exceed new parameter rgb_gain_limit --- source/application/lua_libraries/camera.c | 104 +++++++++++++++++----- 1 file changed, 82 insertions(+), 22 deletions(-) diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index 6405be06..d80b8a68 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -50,11 +50,11 @@ static struct camera_auto_last_values double green_gain; double blue_gain; } last = { - .shutter = 500.0f, + .shutter = 4096.0f, .analog_gain = 1.0f, - .red_gain = 1.9f, - .green_gain = 1.0f, - .blue_gain = 2.2f, + .red_gain = 121.6f, + .green_gain = 64.0f, + .blue_gain = 140.8f, }; static struct camera_capture_settings @@ -564,8 +564,9 @@ static int lua_camera_auto(lua_State *L) camera_metering_mode_t metering = AVERAGE; double target_exposure = 0.18; double exposure_speed = 0.50; - double shutter_limit = 1600.0; - double analog_gain_limit = 60.0; + double shutter_limit = 8192.0; + double analog_gain_limit = 16.0; + double rgb_gain_limit = 141.0; // Default white balance settings double white_balance_speed = 0.5; @@ -655,6 +656,17 @@ static int lua_camera_auto(lua_State *L) lua_pop(L, 1); } + + if (lua_getfield(L, 1, "rgb_gain_limit") != LUA_TNIL) + { + rgb_gain_limit = luaL_checknumber(L, -1); + if (rgb_gain_limit < 0.0 || rgb_gain_limit > 1023.0) + { + luaL_error(L, "rgb_gain_limit must be between 0 and 1023"); + } + + lua_pop(L, 1); + } } // Get current brightness from FPGA @@ -668,6 +680,25 @@ static int lua_camera_auto(lua_State *L) double matrix_g = metering_data[4] / 255.0f; double matrix_b = metering_data[5] / 255.0f; + if (spot_r == 0.0) { + spot_r = 0.0001; + } + if (spot_g == 0.0) { + spot_g = 0.0001; + } + if (spot_b == 0.0) { + spot_b = 0.0001; + } + if (matrix_r == 0.0) { + matrix_r = 0.0001; + } + if (matrix_g == 0.0) { + matrix_g = 0.0001; + } + if (matrix_b == 0.0) { + matrix_b = 0.0001; + } + double spot_average = (spot_r + spot_g + spot_b) / 3.0; double matrix_average = (matrix_r + matrix_g + matrix_b) / 3.0; double center_weighted_average = (spot_average + @@ -777,19 +808,6 @@ static int lua_camera_auto(lua_State *L) double blending_factor = (scene_brightness - white_balance_min_activation) / (white_balance_max_activation - white_balance_min_activation); - - if (red_gain > 1023.0) - { - red_gain = 1023.0; - } - if (green_gain > 1023.0) - { - green_gain = 1023.0; - } - if (blue_gain > 1023.0) - { - blue_gain = 1023.0; - } if (blending_factor > 1.0) { blending_factor = 1.0; @@ -811,9 +829,51 @@ static int lua_camera_auto(lua_State *L) (blue_gain - last.blue_gain) + last.blue_gain; - uint16_t red_gain_uint16 = (uint16_t)(last.red_gain * 256.0); - uint16_t green_gain_uint16 = (uint16_t)(last.green_gain * 256.0); - uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain * 256.0); + double max_rgb_gain = last.red_gain > last.green_gain + ? (last.red_gain > last.blue_gain + ? last.red_gain + : last.blue_gain) + : (last.green_gain > last.blue_gain + ? last.green_gain + : last.blue_gain); + + // Scale per-channel gains so the largest channel is at most rgb_gain_limit + if (max_rgb_gain > rgb_gain_limit) + { + double scale_factor = rgb_gain_limit / max_rgb_gain; + last.red_gain *= scale_factor; + last.green_gain *= scale_factor; + last.blue_gain *= scale_factor; + } + + if (last.red_gain > 1023.0) + { + last.red_gain = 1023.0; + } + if (last.red_gain <= 0.0) + { + last.red_gain = 0.0001; + } + if (last.green_gain > 1023.0) + { + last.green_gain = 1023.0; + } + if (last.green_gain <= 0.0) + { + last.green_gain = 0.0001; + } + if (last.blue_gain > 1023.0) + { + last.blue_gain = 1023.0; + } + if (last.blue_gain <= 0.0) + { + last.blue_gain = 0.0001; + } + + uint16_t red_gain_uint16 = (uint16_t)(last.red_gain); + uint16_t green_gain_uint16 = (uint16_t)(last.green_gain); + uint16_t blue_gain_uint16 = (uint16_t)(last.blue_gain); check_error(i2c_write(CAMERA, 0x5180, 0x03, red_gain_uint16 >> 8).fail); check_error(i2c_write(CAMERA, 0x5181, 0xFF, red_gain_uint16).fail); From d29669897b332763eedd41dc781f3d46aa86034f Mon Sep 17 00:00:00 2001 From: CitizenOneX <17427385+CitizenOneX@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:43:16 +1100 Subject: [PATCH 3/5] scale max normalized rgb value up to gain scale since it will be indirectly used to subtract previous gain values --- source/application/lua_libraries/camera.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index d80b8a68..996049df 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -50,7 +50,7 @@ static struct camera_auto_last_values double green_gain; double blue_gain; } last = { - .shutter = 4096.0f, + .shutter = 1600.0f, .analog_gain = 1.0f, .red_gain = 121.6f, .green_gain = 64.0f, @@ -800,6 +800,10 @@ static int lua_camera_auto(lua_State *L) ? matrix_g / last.green_gain : matrix_b / last.blue_gain); + // scale normalized RGB values to the gain scale + max_rgb *= 256.0; + + // target per-channel gains that we blend towards double red_gain = max_rgb / matrix_r * last.red_gain; double green_gain = max_rgb / matrix_g * last.green_gain; double blue_gain = max_rgb / matrix_b * last.blue_gain; From 5584a35e4d7778bb79ef6d32a7545d64100231d6 Mon Sep 17 00:00:00 2001 From: CitizenOneX <17427385+CitizenOneX@users.noreply.github.com> Date: Thu, 6 Mar 2025 23:34:21 +1100 Subject: [PATCH 4/5] update to reduce shutter_limit to reduce motion blur, with the consequence of dimmer images --- source/application/lua_libraries/camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index 996049df..5fb5a297 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -564,7 +564,7 @@ static int lua_camera_auto(lua_State *L) camera_metering_mode_t metering = AVERAGE; double target_exposure = 0.18; double exposure_speed = 0.50; - double shutter_limit = 8192.0; + double shutter_limit = 3072.0; double analog_gain_limit = 16.0; double rgb_gain_limit = 141.0; From 7c9be344c1e346d316e07c7c98a477acb04dd59b Mon Sep 17 00:00:00 2001 From: CitizenOneX <17427385+CitizenOneX@users.noreply.github.com> Date: Tue, 18 Mar 2025 14:05:15 +1100 Subject: [PATCH 5/5] updated AE algo limits/parameters as well as default starting values for exposure/wb --- source/application/lua_libraries/camera.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/application/lua_libraries/camera.c b/source/application/lua_libraries/camera.c index 5fb5a297..5ff7e6ed 100644 --- a/source/application/lua_libraries/camera.c +++ b/source/application/lua_libraries/camera.c @@ -50,7 +50,7 @@ static struct camera_auto_last_values double green_gain; double blue_gain; } last = { - .shutter = 1600.0f, + .shutter = 4096.0f, .analog_gain = 1.0f, .red_gain = 121.6f, .green_gain = 64.0f, @@ -561,12 +561,12 @@ static int lua_camera_auto(lua_State *L) } // Default auto exposure settings - camera_metering_mode_t metering = AVERAGE; - double target_exposure = 0.18; - double exposure_speed = 0.50; - double shutter_limit = 3072.0; + camera_metering_mode_t metering = CENTER_WEIGHTED; + double target_exposure = 0.1; + double exposure_speed = 0.45; + double shutter_limit = 16383.0; double analog_gain_limit = 16.0; - double rgb_gain_limit = 141.0; + double rgb_gain_limit = 287.0; // Default white balance settings double white_balance_speed = 0.5;