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:
parent
30114cadd8
commit
a283287fbf
1 changed files with 22 additions and 9 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue