ipa: rpi: controller: Improve findPeak() function in AF algorithm
Improve quadratic peak fitting in findPeak(). The old approximation was good but only valid when points were equally spaced and the MAX was not at one end of the series. Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com> Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
committed by
Kieran Bingham
parent
30114cadd8
commit
a283287fbf
@@ -436,15 +436,28 @@ double Af::findPeak(unsigned i) const
|
||||
{
|
||||
double f = scanData_[i].focus;
|
||||
|
||||
if (i > 0 && i + 1 < scanData_.size()) {
|
||||
double dropLo = scanData_[i].contrast - scanData_[i - 1].contrast;
|
||||
double dropHi = scanData_[i].contrast - scanData_[i + 1].contrast;
|
||||
if (0.0 <= dropLo && dropLo < dropHi) {
|
||||
double param = 0.3125 * (1.0 - dropLo / dropHi) * (1.6 - dropLo / dropHi);
|
||||
f += param * (scanData_[i - 1].focus - f);
|
||||
} else if (0.0 <= dropHi && dropHi < dropLo) {
|
||||
double param = 0.3125 * (1.0 - dropHi / dropLo) * (1.6 - dropHi / dropLo);
|
||||
f += param * (scanData_[i + 1].focus - f);
|
||||
if (scanData_.size() >= 3) {
|
||||
/*
|
||||
* Given the sample with the highest contrast score and its two
|
||||
* neighbours either side (or same side if at the end of a scan),
|
||||
* solve for the best lens position by fitting a parabola.
|
||||
* Adapted from awb.cpp: interpolateQaudaratic()
|
||||
*/
|
||||
|
||||
if (i == 0)
|
||||
i++;
|
||||
else if (i + 1 >= scanData_.size())
|
||||
i--;
|
||||
|
||||
double abx = scanData_[i - 1].focus - scanData_[i].focus;
|
||||
double aby = scanData_[i - 1].contrast - scanData_[i].contrast;
|
||||
double cbx = scanData_[i + 1].focus - scanData_[i].focus;
|
||||
double cby = scanData_[i + 1].contrast - scanData_[i].contrast;
|
||||
double denom = 2.0 * (aby * cbx - cby * abx);
|
||||
if (std::abs(denom) >= (1.0 / 64.0) && denom * abx > 0.0) {
|
||||
f = (aby * cbx * cbx - cby * abx * abx) / denom;
|
||||
f = std::clamp(f, std::min(abx, cbx), std::max(abx, cbx));
|
||||
f += scanData_[i].focus;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user