00001 #include "AutoExposure.h"
00002
00003 #include "Frame.h"
00004 #include "Sensor.h"
00005 #include "Shot.h"
00006
00007 namespace FCam {
00008 void autoExpose(Shot *s, Frame::Ptr f,
00009 float maxGain,
00010 int maxExposure,
00011 float smoothness) {
00012
00013
00014 if (!f) return;
00015 if (!s) return;
00016
00017
00018 int b = f->histogram.buckets;
00019
00020 int cdf[256];
00021
00022 if (!f->histogram.valid) return;
00023 if (b > 256 || b < 64) return;
00024
00025 cdf[0] = f->histogram(0);
00026 for (int i = 0; i < b; i++) {
00027 cdf[i] = cdf[i-1] + f->histogram(i);
00028 }
00029
00030 int brightPixels = cdf[b-1] - cdf[b-11];
00031 int targetBrightPixels = (f->histogram.region[0].width*
00032 f->histogram.region[0].height)/100;
00033
00034
00035 float adjustment = 1.0f;
00036
00037 if (brightPixels > targetBrightPixels) {
00038
00039 adjustment = 1.0f - ((float)(brightPixels - targetBrightPixels))/(f->image.size.width*f->image.size.height);
00040 } else {
00041
00042 int l = b-11;
00043 while (brightPixels < targetBrightPixels && l > 0) {
00044 brightPixels += cdf[l];
00045 brightPixels -= cdf[l-1];
00046 l--;
00047 }
00048
00049
00050 adjustment = float(b-11+1)/(l+1);
00051
00052 }
00053
00054 if (adjustment > 4.0) adjustment = 4.0;
00055 if (adjustment < 1/16.0f) adjustment = 1/16.0f;
00056
00057 float brightness = f->gain * f->exposure;
00058 float desiredBrightness = brightness * adjustment;
00059 int exposure;
00060 float gain;
00061
00062
00063
00064 int exposureKnee = s->frameTime - 400;
00065
00066 if (desiredBrightness > exposureKnee) {
00067 exposure = exposureKnee;
00068 gain = desiredBrightness / exposureKnee;
00069 } else {
00070 gain = 1.0f;
00071 exposure = desiredBrightness;
00072 }
00073
00074
00075 if (gain > maxGain) {
00076 exposure = desiredBrightness/maxGain;
00077 gain = maxGain;
00078 }
00079
00080
00081 if (exposure > maxExposure) {
00082 exposure = maxExposure;
00083 }
00084
00085 s->exposure = s->exposure*smoothness + exposure*(1-smoothness);
00086 s->gain = s->gain*smoothness + gain*(1-smoothness);
00087 }
00088 }