From patchwork Fri Jun 20 12:42:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 23610 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5477DBDE6B for ; Fri, 20 Jun 2025 12:45:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 77F8B61535; Fri, 20 Jun 2025 14:45:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ZR7n+Sw/"; dkim-atps=neutral Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2C39E61535 for ; Fri, 20 Jun 2025 14:44:59 +0200 (CEST) Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-3a4e749d7b2so353163f8f.0 for ; Fri, 20 Jun 2025 05:44:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1750423498; x=1751028298; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1fgw5gWlXRgAGINCK27+v1vEnL5TJfgKBKWPe1uS9M8=; b=ZR7n+Sw/JdmA9+GKE1/oTpY15ePHs6Zto+8BjGsxV47aZ9/uTcWW61J3cvg0U295VZ kHviOaNPNUzXJZ+5RGRzyKIRYoW9HcYJ5uqSQYiK4QcjUClX6ZxA0PkifWopO1gEIAOH QOmGgphipz9tfivmxJ4dCCUyJF4PTq9F9nfPziGhFb1iiOtDYUYpE3Ays6YN1S+d+xCr nVB3O0SDZbz1xQkJBQgBBIQXOaW6rtT4Rmz3edKZS4ykZUOcAAn4llVMAOSbnty6HKT3 Btp9NWGWrmsPGncUPZa9MPQTDTb3nd2hjs9w1JBNdTlCfq5GFs/ay5ZFDjH1BepgYSms X3AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750423498; x=1751028298; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1fgw5gWlXRgAGINCK27+v1vEnL5TJfgKBKWPe1uS9M8=; b=awZxYmqU4O6CalbirDCe0Nq1vk6MCRg2+TYWQOkLJkvhVNR3Bot0DxSL2ZRHFHA69w bYXo202+Li4xvU4n8O/4XKeTo6YKrZqFM2HBL1PtSvpge5gUqjHgfno9bvilTao92hDh aRAr1LZwi7r4UmhY6i/yGmg5C7j4wAglRUU2QmOsHB0VjB91uYpdnxRGAg27dFfr1YMn v5wDICs9GTc5ojJkffV0ZfCgLq8BR/djdsb9V0dpSWXK9lI+ErjRx0BJ9gURj1zkoTbd H9WSAELSeHnVLaKcLf65LGH8/hza+9qM2MwhNFVLOelrWa9l/K6Van+52q8QS4JNn/cE Rykg== X-Gm-Message-State: AOJu0Yx94m4rPGPmkuifRtlDIxzqX7bPZN3t/9ytFeXXDvkejO/tzErR XhSbX/Lhi/AGvOxgsppWjG9n/MtE2IrDYE6h8siKHs6BZ0L2bctnimfqtX3zohYnWlcFlwuH7BU KtDba X-Gm-Gg: ASbGncsELat11iL/sTKNCOSWJUswpgV8LIMCkOzJScwFheelpoKWT2lcVMkknTE9JeR 2oi37NGQyDR/1C7Nsa/U3Ir1DkhhOptsTwJ556vwCHKUUZ+SXHeAgE1tHV8oV6wTYxvf6/3OPe1 +/SdPBJyCs49kbvD+UYJYZapcDnONtvMNufqzP7SUzjSOb9IUZXqRVod2jmCDZYSjc40IIjsoNm dUtRCgFVZguIZBJtUaVq3hKbog89oH7MYsM+yyxDB3+1JVUFhxqfd/5BPZ6TnKfewB0LdcazZyA KRQyvGkLXqlyDi0HyBQLOhb1zyFSVUbl9FyT6HBT4+1NDJRjuOufZkLuTJw1Tx+Tp/vjDSk15dE lmXAI3g== X-Google-Smtp-Source: AGHT+IG+V2QnXhGMLGsz1b49YX+JWTlKouCpYcyTJsmce+nG18y0Jrqq3ike0fb0OGRjnqBKBY0kpQ== X-Received: by 2002:a05:600c:c087:b0:439:a30f:2e49 with SMTP id 5b1f17b1804b1-453657bd470mr7316525e9.5.1750423498446; Fri, 20 Jun 2025 05:44:58 -0700 (PDT) Received: from NAUSH-P-DELL.pitowers.org ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-45361461375sm41561525e9.14.2025.06.20.05.44.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Jun 2025 05:44:58 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: Nick Hollinghurst , Naushir Patuck Subject: [PATCH v1 2/8] ipa: rpi: controller: Improve findPeak() function in AF algorithm Date: Fri, 20 Jun 2025 13:42:23 +0100 Message-ID: <20250620124452.557855-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250620124452.557855-1-naush@raspberrypi.com> References: <20250620124452.557855-1-naush@raspberrypi.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Nick Hollinghurst 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 Signed-off-by: Naushir Patuck Reviewed-by: Naushir Patuck --- src/ipa/rpi/controller/rpi/af.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp index 041cb51db277..8df614ed7b6b 100644 --- a/src/ipa/rpi/controller/rpi/af.cpp +++ b/src/ipa/rpi/controller/rpi/af.cpp @@ -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; } }