summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-02-11 07:26:21 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-05-01 12:13:56 +0200
commit4390a8d2da94149db685da2daa22d8ed6e41d02e (patch)
treee7f081c1f520ee3091b324b262567a374f4d376b
parent394b4755f7951c7c598b3162a98772677ee9dace (diff)
Add naive AEWB algorithm
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--iq.c138
-rw-r--r--iq.h35
2 files changed, 173 insertions, 0 deletions
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 <laurent.pinchart@ideasonboard.com>
+ *
+ * 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 <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 <laurent.pinchart@ideasonboard.com>
+ *
+ * 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