mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add white balance control.
You can now get white balance gains from the camera chip and set the camera to then use these gains again in a new enviorment.
This commit is contained in:
parent
92c7900039
commit
30ecbdc4f8
@ -210,12 +210,12 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_AEC_AGC_ENABLE,
|
||||
(reg & (~MT9V034_AGC_ENABLE)) | ((enable != 0) ? MT9V034_AGC_ENABLE : 0));
|
||||
|
||||
if ((enable == 0) && (gain_db >= 0)) {
|
||||
if ((enable == 0) && (!isnanf(gain_db))) {
|
||||
int gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db / 20.0) * fast_log(10.0)) * 16.0), 127), 0);
|
||||
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, ®);
|
||||
ret |= cambus_writew(sensor->slv_addr, MT9V034_ANALOG_GAIN_CONTROL, (reg & 0xFF80) | gain);
|
||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||
} else if ((enable != 0) && (!isnanf(gain_db_ceiling))) {
|
||||
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)) * 16.0), 127), 16);
|
||||
|
||||
ret |= cambus_readw(sensor->slv_addr, MT9V034_MAX_GAIN, ®);
|
||||
@ -273,7 +273,12 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -329,6 +334,7 @@ int mt9v034_init(sensor_t *sensor)
|
||||
sensor->set_auto_exposure = set_auto_exposure;
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->set_special_effect = set_special_effect;
|
||||
|
||||
@ -610,7 +610,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
ret |= cambus_readb(sensor->slv_addr, COM8, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0));
|
||||
|
||||
if ((enable == 0) && (gain_db >= 0)) {
|
||||
if ((enable == 0) && (!isnanf(gain_db))) {
|
||||
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 0.0);
|
||||
|
||||
int gain_hi = 15;
|
||||
@ -624,7 +624,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
}
|
||||
|
||||
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||
} else if ((enable != 0) && (!isnanf(gain_db_ceiling))) {
|
||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
||||
@ -756,22 +756,40 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
|
||||
{
|
||||
uint8_t reg;
|
||||
/* Switch to SENSOR register bank */
|
||||
int ret = cambus_writeb(sensor->slv_addr, BANK_SEL, BANK_SEL_DSP);
|
||||
|
||||
/* Update CTRL1 */
|
||||
int ret = cambus_readb(sensor->slv_addr, BANK_SEL, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg & (~BANK_SEL_SENSOR));
|
||||
ret |= cambus_readb(sensor->slv_addr, CTRL1, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, CTRL1, (reg & (~CTRL1_AWB)) | ((enable != 0) ? CTRL1_AWB : 0));
|
||||
|
||||
if (enable) {
|
||||
reg |= CTRL1_AWB;
|
||||
} else {
|
||||
reg &= ~CTRL1_AWB;
|
||||
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))) {
|
||||
}
|
||||
|
||||
return cambus_writeb(sensor->slv_addr, CTRL1, reg) | ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
|
||||
{
|
||||
uint8_t reg;
|
||||
int ret = cambus_readb(sensor->slv_addr, BANK_SEL, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, BANK_SEL, reg & (~BANK_SEL_SENSOR));
|
||||
ret |= cambus_readb(sensor->slv_addr, CTRL1, ®);
|
||||
|
||||
// DISABLED
|
||||
// if (reg & CTRL1_AWB) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, CTRL1, reg & (~CTRL1_AWB));
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
// DISABLED
|
||||
// if (reg & CTRL1_AWB) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, CTRL1, reg | CTRL1_AWB);
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
@ -829,6 +847,7 @@ int ov2640_init(sensor_t *sensor)
|
||||
sensor->set_auto_exposure = set_auto_exposure;
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
|
||||
|
||||
@ -358,7 +358,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AGC(reg, (enable != 0)));
|
||||
|
||||
if ((enable == 0) && (gain_db >= 0)) {
|
||||
if ((enable == 0) && (!isnanf(gain_db))) {
|
||||
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 32.0), 0.0);
|
||||
|
||||
int gain_hi = 15;
|
||||
@ -372,7 +372,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
}
|
||||
|
||||
ret |= cambus_writeb(sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
|
||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||
} else if ((enable != 0) && (!isnanf(gain_db_ceiling))) {
|
||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 32.0), 2.0);
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, COM9, ®);
|
||||
@ -491,24 +491,59 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
|
||||
{
|
||||
uint8_t reg;
|
||||
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
||||
// Set AWB on/off
|
||||
reg = COM8_SET_AWB(reg, enable);
|
||||
ret |= cambus_writeb(sensor->slv_addr, COM8, reg);
|
||||
ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, (enable != 0)));
|
||||
|
||||
if (enable == 0 && r_gain >= 0 && g_gain >=0 && b_gain >=0) {
|
||||
// Set value manually.
|
||||
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))) {
|
||||
ret |= cambus_readb(sensor->slv_addr, AWB_CTRL1, ®);
|
||||
float gain_div = (reg & 0x2) ? 64.0 : 128.0;
|
||||
|
||||
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
|
||||
int g_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((g_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
|
||||
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0)) * gain_div), 255), 0);
|
||||
|
||||
ret |= cambus_writeb(sensor->slv_addr, BLUE, b_gain);
|
||||
ret |= cambus_writeb(sensor->slv_addr, RED, r_gain);
|
||||
ret |= cambus_writeb(sensor->slv_addr, GREEN, g_gain);
|
||||
ret |= cambus_writeb(sensor->slv_addr, BLUE, b_gain);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
|
||||
{
|
||||
uint8_t reg, blue, red, green;
|
||||
int ret = cambus_readb(sensor->slv_addr, COM8, ®);
|
||||
|
||||
// DISABLED
|
||||
// if (reg & COM8_AWB_EN) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, 0));
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, BLUE, &blue);
|
||||
ret |= cambus_readb(sensor->slv_addr, RED, &red);
|
||||
ret |= cambus_readb(sensor->slv_addr, GREEN, &green);
|
||||
|
||||
// DISABLED
|
||||
// if (reg & COM8_AWB_EN) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, COM8, COM8_SET_AWB(reg, 1));
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, AWB_CTRL1, ®);
|
||||
float gain_div = (reg & 0x2) ? 64.0 : 128.0;
|
||||
|
||||
*r_gain_db = 20.0 * (fast_log(red / gain_div) / fast_log(10.0));
|
||||
*g_gain_db = 20.0 * (fast_log(green / gain_div) / fast_log(10.0));
|
||||
*b_gain_db = 20.0 * (fast_log(blue / gain_div) / fast_log(10.0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
{
|
||||
uint8_t reg;
|
||||
@ -578,6 +613,7 @@ int ov7725_init(sensor_t *sensor)
|
||||
sensor->set_auto_exposure = set_auto_exposure;
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->set_special_effect = set_special_effect;
|
||||
|
||||
@ -334,7 +334,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, (reg & (~REG_COM8_AGC)) | ((enable != 0) ? REG_COM8_AGC : 0));
|
||||
|
||||
if ((enable == 0) && (gain_db >= 0)) {
|
||||
if ((enable == 0) && (!isnanf(gain_db))) {
|
||||
float gain = IM_MAX(IM_MIN(fast_expf((gain_db / 20.0) * fast_log(10.0)), 128.0), 0.0);
|
||||
|
||||
int gain_hi = 63;
|
||||
@ -350,7 +350,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_GAIN, ((gain_hi & 0x0F) << 4) | (gain_lo << 0));
|
||||
ret |= cambus_readb(sensor->slv_addr, REG_VREF, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
|
||||
} else if ((enable != 0) && (gain_db_ceiling >= 0)) {
|
||||
} else if ((enable != 0) && (!isnanf(gain_db_ceiling))) {
|
||||
float gain_ceiling = IM_MAX(IM_MIN(fast_expf((gain_db_ceiling / 20.0) * fast_log(10.0)), 128.0), 2.0);
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, REG_COM9, ®);
|
||||
@ -459,15 +459,47 @@ static int get_exposure_us(sensor_t *sensor, int *exposure_us)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain)
|
||||
static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db)
|
||||
{
|
||||
uint8_t val;
|
||||
cambus_readb(sensor->slv_addr, REG_COM8, &val);
|
||||
uint8_t reg;
|
||||
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_COM8, (reg & (~REG_COM8_AWB)) | ((enable != 0) ? REG_COM8_AWB : 0));
|
||||
|
||||
cambus_writeb(sensor->slv_addr, REG_COM8,
|
||||
enable ? (val | REG_COM8_AWB) : (val & ~REG_COM8_AWB));
|
||||
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))) {
|
||||
int r_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((r_gain_db / 20.0) * fast_log(10.0)) * 128.0), 255), 0);
|
||||
int b_gain = IM_MAX(IM_MIN(fast_roundf(fast_expf((b_gain_db / 20.0) * fast_log(10.0)) * 128.0), 255), 0);
|
||||
|
||||
return 0;
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_BLUE, b_gain);
|
||||
ret |= cambus_writeb(sensor->slv_addr, REG_RED, r_gain);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_rgb_gain_db(sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db)
|
||||
{
|
||||
uint8_t reg, blue, red;
|
||||
int ret = cambus_readb(sensor->slv_addr, REG_COM8, ®);
|
||||
|
||||
// DISABLED
|
||||
// if (reg & REG_COM8_AWB) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg & (~REG_COM8_AWB));
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
ret |= cambus_readb(sensor->slv_addr, REG_BLUE, &blue);
|
||||
ret |= cambus_readb(sensor->slv_addr, REG_RED, &red);
|
||||
|
||||
// DISABLED
|
||||
// if (reg & REG_COM8_AWB) {
|
||||
// ret |= cambus_writeb(sensor->slv_addr, REG_COM8, reg | REG_COM8_AWB);
|
||||
// }
|
||||
// DISABLED
|
||||
|
||||
*r_gain_db = 20.0 * (fast_log(red / 128.0) / fast_log(10.0));
|
||||
*b_gain_db = 20.0 * (fast_log(blue / 128.0) / fast_log(10.0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable)
|
||||
@ -503,6 +535,7 @@ int ov9650_init(sensor_t *sensor)
|
||||
sensor->set_auto_exposure = set_auto_exposure;
|
||||
sensor->get_exposure_us = get_exposure_us;
|
||||
sensor->set_auto_whitebal = set_auto_whitebal;
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
|
||||
|
||||
@ -41,6 +41,19 @@ void py_helper_lookup_int_array(mp_map_t *kw_args, mp_obj_t kw, int *x, int size
|
||||
}
|
||||
}
|
||||
|
||||
void py_helper_lookup_float_array(mp_map_t *kw_args, mp_obj_t kw, float *x, int size)
|
||||
{
|
||||
mp_map_elem_t *kw_array = mp_map_lookup(kw_args, kw, MP_MAP_LOOKUP);
|
||||
|
||||
if (kw_array != NULL) {
|
||||
mp_obj_t *arg_array;
|
||||
mp_obj_get_array_fixed_n(kw_array->value, size, &arg_array);
|
||||
for (int i=0; i<size; i++) {
|
||||
x[i] = mp_obj_get_float(arg_array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int py_helper_lookup_color(mp_map_t *kw_args, int default_color)
|
||||
{
|
||||
mp_map_elem_t *kw_color = mp_map_lookup(kw_args,
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
int py_helper_lookup_int(mp_map_t *kw_args, mp_obj_t kw, int default_val);
|
||||
float py_helper_lookup_float(mp_map_t *kw_args, mp_obj_t kw, float default_val);
|
||||
void py_helper_lookup_int_array(mp_map_t *kw_args, mp_obj_t kw, int *x, int size);
|
||||
void py_helper_lookup_float_array(mp_map_t *kw_args, mp_obj_t kw, float *x, int size);
|
||||
int py_helper_lookup_color(mp_map_t *kw_args, int default_color);
|
||||
void py_helper_lookup_offset(mp_map_t *kw_args, image_t *img, point_t *p);
|
||||
void py_helper_lookup_rectangle(mp_map_t *kw_args, image_t *img, rectangle_t *r);
|
||||
|
||||
@ -346,8 +346,8 @@ static mp_obj_t py_sensor_set_colorbar(mp_obj_t enable) {
|
||||
|
||||
static mp_obj_t py_sensor_set_auto_gain(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
int enable = mp_obj_get_int(args[0]);
|
||||
float gain_db = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db), -1);
|
||||
float gain_db_ceiling = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db_ceiling), -1);
|
||||
float gain_db = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db), NAN);
|
||||
float gain_db_ceiling = py_helper_lookup_float(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db_ceiling), NAN);
|
||||
if (sensor_set_auto_gain(enable, gain_db, gain_db_ceiling) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
@ -380,12 +380,20 @@ static mp_obj_t py_sensor_get_exposure_us() {
|
||||
|
||||
static mp_obj_t py_sensor_set_auto_whitebal(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
int enable = mp_obj_get_int(args[0]);
|
||||
int value[3] = {-1, -1, -1};
|
||||
py_helper_lookup_int_array(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_value), value, 3);
|
||||
if (sensor_set_auto_whitebal(enable, value[0], value[1], value[2]) != 0) {
|
||||
return mp_const_false;
|
||||
float rgb_gain_db[3] = {NAN, NAN, NAN};
|
||||
py_helper_lookup_float_array(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_gain_db), rgb_gain_db, 3);
|
||||
if (sensor_set_auto_whitebal(enable, rgb_gain_db[0], rgb_gain_db[1], rgb_gain_db[2]) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
return mp_const_true;
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_get_rgb_gain_db() {
|
||||
float r_gain_db = 0.0, g_gain_db = 0.0, b_gain_db = 0.0;
|
||||
if (sensor_get_rgb_gain_db(&r_gain_db, &g_gain_db, &b_gain_db) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!"));
|
||||
}
|
||||
return mp_obj_new_tuple(3, (mp_obj_t []) {mp_obj_new_float(r_gain_db), mp_obj_new_float(g_gain_db), mp_obj_new_float(b_gain_db)});
|
||||
}
|
||||
|
||||
static mp_obj_t py_sensor_set_hmirror(mp_obj_t enable) {
|
||||
@ -463,6 +471,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_gain_db_obj, py_sensor_ge
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_auto_exposure_obj,1,py_sensor_set_auto_exposure);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_exposure_us_obj, py_sensor_get_exposure_us);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_sensor_set_auto_whitebal_obj,1,py_sensor_set_auto_whitebal);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_get_rgb_gain_db_obj, py_sensor_get_rgb_gain_db);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_hmirror_obj, py_sensor_set_hmirror);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_vflip_obj, py_sensor_set_vflip);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_special_effect_obj, py_sensor_set_special_effect);
|
||||
@ -541,6 +550,7 @@ STATIC const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_auto_exposure), (mp_obj_t)&py_sensor_set_auto_exposure_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_exposure_us), (mp_obj_t)&py_sensor_get_exposure_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_auto_whitebal), (mp_obj_t)&py_sensor_set_auto_whitebal_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_get_rgb_gain_db), (mp_obj_t)&py_sensor_get_rgb_gain_db_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_hmirror), (mp_obj_t)&py_sensor_set_hmirror_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_vflip), (mp_obj_t)&py_sensor_set_vflip_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_special_effect), (mp_obj_t)&py_sensor_set_special_effect_obj },
|
||||
|
||||
@ -229,6 +229,8 @@ Q(set_auto_exposure)
|
||||
Q(exposure_us)
|
||||
Q(get_exposure_us)
|
||||
Q(set_auto_whitebal)
|
||||
Q(rgb_gain_db)
|
||||
Q(get_rgb_gain_db)
|
||||
Q(set_hmirror)
|
||||
Q(set_vflip)
|
||||
Q(set_special_effect)
|
||||
|
||||
@ -569,11 +569,22 @@ int sensor_get_exposure_us(int *exposure_us)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_set_auto_whitebal(int enable, int r_gain, int g_gain, int b_gain)
|
||||
int sensor_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db)
|
||||
{
|
||||
/* call the sensor specific function */
|
||||
if (sensor.set_auto_whitebal == NULL
|
||||
|| sensor.set_auto_whitebal(&sensor, enable, r_gain, g_gain, b_gain) != 0) {
|
||||
|| sensor.set_auto_whitebal(&sensor, enable, r_gain_db, g_gain_db, b_gain_db) != 0) {
|
||||
/* operation not supported */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sensor_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db)
|
||||
{
|
||||
/* call the sensor specific function */
|
||||
if (sensor.get_rgb_gain_db == NULL
|
||||
|| sensor.get_rgb_gain_db(&sensor, r_gain_db, g_gain_db, b_gain_db) != 0) {
|
||||
/* operation not supported */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -139,7 +139,8 @@ typedef struct _sensor {
|
||||
int (*get_gain_db) (sensor_t *sensor, float *gain_db);
|
||||
int (*set_auto_exposure) (sensor_t *sensor, int enable, int exposure_us);
|
||||
int (*get_exposure_us) (sensor_t *sensor, int *exposure_us);
|
||||
int (*set_auto_whitebal) (sensor_t *sensor, int enable, int r_gain, int g_gain, int b_gain);
|
||||
int (*set_auto_whitebal) (sensor_t *sensor, int enable, float r_gain_db, float g_gain_db, float b_gain_db);
|
||||
int (*get_rgb_gain_db) (sensor_t *sensor, float *r_gain_db, float *g_gain_db, float *b_gain_db);
|
||||
int (*set_hmirror) (sensor_t *sensor, int enable);
|
||||
int (*set_vflip) (sensor_t *sensor, int enable);
|
||||
int (*set_special_effect) (sensor_t *sensor, sde_t sde);
|
||||
@ -214,7 +215,10 @@ int sensor_set_auto_exposure(int enable, int exposure_us);
|
||||
int sensor_get_exposure_us(int *get_exposure_us);
|
||||
|
||||
// Enable auto white balance or set value manually.
|
||||
int sensor_set_auto_whitebal(int enable, int r_gain, int g_gain, int b_gain);
|
||||
int sensor_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db);
|
||||
|
||||
// Get the rgb gain values.
|
||||
int sensor_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
|
||||
|
||||
// Enable/disable the hmirror mode.
|
||||
int sensor_set_hmirror(int enable);
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
# Sensor Manual Whitebal Control
|
||||
#
|
||||
# This example shows off how to control the camera sensor's
|
||||
# white balance gain manually versus letting the AWB control run.
|
||||
|
||||
# White balance is achieve by adjusting R/G/B gain values
|
||||
# such that the average color of the image is gray. The
|
||||
# automatic white balance (AWB) algorithm does this for
|
||||
# you but usually ends up with a different result each
|
||||
# time you turn the camera on making it hard to get
|
||||
# color tracking settings right. By manually recording
|
||||
# the gain values you like and then forcing them to
|
||||
# the sensor on startup you can control the colors
|
||||
# the camera sees.
|
||||
|
||||
import sensor, image, time
|
||||
|
||||
sensor.reset() # Reset and initialize the sensor.
|
||||
sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE)
|
||||
sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240)
|
||||
sensor.skip_frames(time = 2000) # Wait for settings take effect.
|
||||
clock = time.clock() # Create a clock object to track the FPS.
|
||||
|
||||
# You can control the white balance gains here. The first value is the
|
||||
# R gain in db, and then the G gain in db, followed by the B gain in db.
|
||||
#
|
||||
# Uncomment the below line with gain values you like (get them from the print out).
|
||||
#
|
||||
# sensor.set_auto_whitebal(False, rgb_gain_db = (0.0, 0.0, 0.0))
|
||||
|
||||
# Note: Putting (0.0, 0.0, 0.0) for the gain results in something close to zero
|
||||
# comming out. Do not expect the exact value going in to be equal to the value
|
||||
# comming out.
|
||||
|
||||
while(True):
|
||||
clock.tick() # Update the FPS clock.
|
||||
img = sensor.snapshot() # Take a picture and return the image.
|
||||
print(clock.fps(), \
|
||||
sensor.get_rgb_gain_db()) # Prints the AWB current RGB gains.
|
||||
Loading…
Reference in New Issue
Block a user