Message ID | 20201116164918.2055-5-david.plowman@raspberrypi.com |
---|---|
State | Superseded |
Headers | show |
Series |
|
Related | show |
Hi David, On Mon, 16 Nov 2020 at 16:49, David Plowman <david.plowman@raspberrypi.com> wrote: > Previously the calculation computed Y for each region before returning > the weighted average, which "baked in" the over-importance of small > statistics regions. The revised calculation will treat all pixels > equally when the region weights are the same, making it easier to > use. With the previous scheme, proper "average" metering was difficult > to implement. > > Signed-off-by: David Plowman <david.plowman@raspberrypi.com> > Reviewed-by: Naushir Patuck <naush@raspberrypi.com> > --- > src/ipa/raspberrypi/controller/rpi/agc.cpp | 25 +++++++++++++--------- > 1 file changed, 15 insertions(+), 10 deletions(-) > > diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp > b/src/ipa/raspberrypi/controller/rpi/agc.cpp > index d29b1156..ead28398 100644 > --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp > +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp > @@ -386,18 +386,23 @@ static double compute_initial_Y(bcm2835_isp_stats > *stats, Metadata *image_metada > awb.gain_r = awb.gain_g = awb.gain_b = 1.0; // in case no metadata > if (image_metadata->Get("awb.status", awb) != 0) > LOG(RPiAgc, Warning) << "Agc: no AWB status found"; > - double Y_sum = 0, weight_sum = 0; > + // Note how the calculation below means that equal weights give you > + // "average" metering (i.e. all pixels equally important). > + double R_sum = 0, G_sum = 0, B_sum = 0, pixel_sum = 0; > for (int i = 0; i < AGC_STATS_SIZE; i++) { > - if (regions[i].counted == 0) > - continue; > - weight_sum += weights[i]; > - double Y = regions[i].r_sum * awb.gain_r * .299 + > - regions[i].g_sum * awb.gain_g * .587 + > - regions[i].b_sum * awb.gain_b * .114; > - Y /= regions[i].counted; > - Y_sum += Y * weights[i]; > + R_sum += regions[i].r_sum * weights[i]; > + G_sum += regions[i].g_sum * weights[i]; > + B_sum += regions[i].b_sum * weights[i]; > + pixel_sum += regions[i].counted * weights[i]; > } > - return Y_sum / weight_sum / (1 << PIPELINE_BITS); > + if (pixel_sum == 0.0) { > + LOG(RPiAgc, Warning) << "compute_initial_Y: pixel_sum is > zero"; > + return 0; > + } > + double Y_sum = R_sum * awb.gain_r * .299 + > + G_sum * awb.gain_g * .587 + > + B_sum * awb.gain_b * .114; > + return Y_sum / pixel_sum / (1 << PIPELINE_BITS); > } > > // We handle extra gain through EV by adjusting our Y targets. However, > you > -- > 2.20.1 > > _______________________________________________ > libcamera-devel mailing list > libcamera-devel@lists.libcamera.org > https://lists.libcamera.org/listinfo/libcamera-devel >
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index d29b1156..ead28398 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -386,18 +386,23 @@ static double compute_initial_Y(bcm2835_isp_stats *stats, Metadata *image_metada awb.gain_r = awb.gain_g = awb.gain_b = 1.0; // in case no metadata if (image_metadata->Get("awb.status", awb) != 0) LOG(RPiAgc, Warning) << "Agc: no AWB status found"; - double Y_sum = 0, weight_sum = 0; + // Note how the calculation below means that equal weights give you + // "average" metering (i.e. all pixels equally important). + double R_sum = 0, G_sum = 0, B_sum = 0, pixel_sum = 0; for (int i = 0; i < AGC_STATS_SIZE; i++) { - if (regions[i].counted == 0) - continue; - weight_sum += weights[i]; - double Y = regions[i].r_sum * awb.gain_r * .299 + - regions[i].g_sum * awb.gain_g * .587 + - regions[i].b_sum * awb.gain_b * .114; - Y /= regions[i].counted; - Y_sum += Y * weights[i]; + R_sum += regions[i].r_sum * weights[i]; + G_sum += regions[i].g_sum * weights[i]; + B_sum += regions[i].b_sum * weights[i]; + pixel_sum += regions[i].counted * weights[i]; } - return Y_sum / weight_sum / (1 << PIPELINE_BITS); + if (pixel_sum == 0.0) { + LOG(RPiAgc, Warning) << "compute_initial_Y: pixel_sum is zero"; + return 0; + } + double Y_sum = R_sum * awb.gain_r * .299 + + G_sum * awb.gain_g * .587 + + B_sum * awb.gain_b * .114; + return Y_sum / pixel_sum / (1 << PIPELINE_BITS); } // We handle extra gain through EV by adjusting our Y targets. However, you
Previously the calculation computed Y for each region before returning the weighted average, which "baked in" the over-importance of small statistics regions. The revised calculation will treat all pixels equally when the region weights are the same, making it easier to use. With the previous scheme, proper "average" metering was difficult to implement. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> --- src/ipa/raspberrypi/controller/rpi/agc.cpp | 25 +++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-)