From 4390a8d2da94149db685da2daa22d8ed6e41d02e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 11 Feb 2012 07:26:21 +0100 Subject: Add naive AEWB algorithm Signed-off-by: Laurent Pinchart --- iq.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ iq.h | 35 +++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 iq.c create mode 100644 iq.h diff --git a/iq.c b/iq.c new file mode 100644 index 0000000..b02c297 --- /dev/null +++ b/iq.c @@ -0,0 +1,138 @@ +/* + * OMAP3 image quality tuning + * + * Copyright (C) 2010-2012 Ideas on board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +#include "isp/omap3isp.h" +#include "isp/stats.h" +#include "isp/tools.h" + +#include "iq.h" + +struct iq_tuning { + struct omap3_isp_device *isp; + + unsigned int frame_count; + unsigned int pix_max; + float mean_level; + + unsigned int exposure; + unsigned int exposure_min; + unsigned int exposure_max; + + unsigned int gain; + unsigned int gain_min; + unsigned int gain_max; + + unsigned int black_level; +}; + +void iq_aewb_process(struct iq_tuning *iq, + const struct omap3_isp_aewb_stats *stats) +{ + unsigned int i; + float gains[4]; + double factor; + double gain; + double mean; + + /* Automatic White Balance */ + mean = stats->accum[0] + stats->accum[3] + + (stats->accum[1] + stats->accum[2]) / 2; + mean /= 3; + + for (i = 0; i < 4; ++i) + gains[i] = mean / stats->accum[i]; + + omap3_isp_preview_set_white_balance(iq->isp, gains); + + /* Automatic Exposure */ + if ((iq->frame_count++ % 2) == 0) + return; + + mean = stats->accum[0] + stats->accum[1] + + stats->accum[2] + stats->accum[3]; + mean /= 4 * stats->npix; + + factor = (iq->pix_max * iq->mean_level) / mean; + + gain = factor * iq->exposure * iq->gain / iq->gain_min; + iq->exposure = clamp((unsigned int)gain, + iq->exposure_min, iq->exposure_max); + + gain = gain / iq->exposure * iq->gain_min; + iq->gain = clamp((unsigned int)gain, + iq->gain_min, iq->gain_max); + + printf("AE: factor %.4f exposure %u sensor gain %u\n", + factor, iq->exposure, iq->gain); + + omap3_isp_sensor_set_exposure(iq->isp, iq->exposure); + omap3_isp_sensor_set_gain(iq->isp, iq->gain); +} + +struct iq_tuning *iq_init(struct omap3_isp_device *isp) +{ + struct v4l2_mbus_framefmt format; + struct v4l2_rect window; + struct iq_tuning *iq; + + iq = malloc(sizeof *iq); + if (iq == NULL) + return NULL; + + iq->isp = isp; + iq->frame_count = 0; + iq->pix_max = (1 << 10) - 1; + iq->mean_level = 0.15; + iq->exposure = 1000; + iq->exposure_min = 10; + iq->exposure_max = 2000; + iq->gain = 8; + iq->gain_min = 8; + iq->gain_max = 1024; + iq->black_level = 64; + + omap3_isp_sensor_set_gain(isp, iq->gain); + omap3_isp_sensor_set_exposure(isp, iq->exposure); + omap3_isp_ccdc_set_black_level(isp, iq->black_level); + + omap3_isp_stats_get_format(isp, &format); + window.left = 0; + window.top = 0; + window.width = format.width; + window.height = format.height; + + omap3_isp_aewb_configure(isp, &window, iq->pix_max - iq->black_level - 1); + omap3_isp_stats_enable(isp, true); + + return iq; +} + +void iq_cleanup(struct iq_tuning *iq) +{ + free(iq); +} diff --git a/iq.h b/iq.h new file mode 100644 index 0000000..aeb29de --- /dev/null +++ b/iq.h @@ -0,0 +1,35 @@ +/* + * OMAP3 image quality tuning + * + * Copyright (C) 2010-2012 Ideas on board SPRL + * + * Contact: Laurent Pinchart + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __IQ_H__ +#define __IQ_H__ + +struct iq_tuning; +struct omap3_isp_device; +struct omap3_isp_aewb_stats; + +void iq_aewb_process(struct iq_tuning *iq, + const struct omap3_isp_aewb_stats *stats); +struct iq_tuning *iq_init(struct omap3_isp_device *isp); +void iq_cleanup(struct iq_tuning *iq); + +#endif -- cgit v1.2.3