From patchwork Wed Jul 29 09:31:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9062 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 C8CD8BD86F for ; Wed, 29 Jul 2020 09:32:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 94D996185C; Wed, 29 Jul 2020 11:32:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="qHOsoKT6"; dkim-atps=neutral Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DBCDE611A2 for ; Wed, 29 Jul 2020 11:32:03 +0200 (CEST) Received: by mail-wr1-x443.google.com with SMTP id b6so20937787wrs.11 for ; Wed, 29 Jul 2020 02:32:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5PMt33dqXzIUjSsz8EwXzOq9fkust7oXx3uBnBL8KqI=; b=qHOsoKT6HwVvQug4GrEMbiRqSxZhD35c5xxTq7oy6Iiz1Jf9S7q+KRgDD1Zk4Qb4p5 sbWZN/eUmwutVcCTmBb8TRs3EMfKvdI+VcP/7XTjSrLdSLRO9AY1dxfCCG/tihsNpCgq JM0XH35tVGrHIb4b8zFyr6GiYBmIw6Ldk5//Fbjp6vy2A/n1qhpnMTc14RvXc2ZUKwBj X8dUJi9CMiigv+A26LVfxyrwK2gDmmGlRpilD4/txYoo1z62SdON3feNeFLPx5cp1lSB DG9O0eKKZWPigqqTP/lSbxYpzpLRAvvIw44GAU3Ft1LCr6jWYhup1QifGb7qjVVtYZNJ CyrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5PMt33dqXzIUjSsz8EwXzOq9fkust7oXx3uBnBL8KqI=; b=HLSv5IOS7a6yWPjFO0WqoSHtTQ/y/t/qgnefaOorv8akNDrEbScVjygbt5at7fTePX 1HStnMRSH52anO7voJhsEKPouITsf8q81vM4Y5qb/jJLLW2pD7f6dZ78SOsiXu7kU1Y5 VNMVVf3RB241HRJoPmGmqptor+AJ/0Q7Y2RoZre/QVdEuSkXVV0Ky7UIZRrCquAjJPMr /0GqOiaqMzn9zTsi81OLp/9tyDFhTwt+Y6jwYX8vehix1qxwK4+VJ0HiPoiY8ZHfu5Ft L0PqXdqWaNodJe0TkX4wkExpRi/2YXeT+KL7EjbjCy5JaHyY3jcOj/rZZsS7E36gq6L7 sZiw== X-Gm-Message-State: AOAM532lOPoozKQFtwgyVzUFu18gXauA3GU06jVEkMufP8d6N+5Qfctm UQh7GKwXAxF1sL6rxhuQbIP+HFbdko4I4g== X-Google-Smtp-Source: ABdhPJwTzdpDWtWdKCBbPVchdcvQwYCBgoUkdFSs2m3tdbJycUvw39vdTsyltRRVqyR7bTkpDdNfOA== X-Received: by 2002:a5d:4984:: with SMTP id r4mr28624353wrq.401.1596015123277; Wed, 29 Jul 2020 02:32:03 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id c15sm3709921wme.23.2020.07.29.02.32.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jul 2020 02:32:02 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Wed, 29 Jul 2020 10:31:53 +0100 Message-Id: <20200729093154.12296-5-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200729093154.12296-1-david.plowman@raspberrypi.com> References: <20200729093154.12296-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/5] libcamera: raspberrypi: ALSC: Handle transform in colour tables 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" This commit updates ALSC (Auto Lens Shading Correction) to handle the transform now passed in the SwitchMode method. The transform is applied by the sensor, so the statistics we get already incorporates it, and the adpative algorithm is agnostic to it. That leaves only the calibrated tables (assumed measured without any user transform) that need to be flipped, and resample_cal_table - where we resample the calibrated table anyway - is an easy place to do it. --- src/ipa/raspberrypi/controller/rpi/alsc.cpp | 22 ++++++++++++++------- src/ipa/raspberrypi/controller/rpi/alsc.hpp | 3 ++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp index 5fac9dd..33c1a88 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp @@ -151,8 +151,9 @@ static void get_cal_table(double ct, std::vector const &calibrations, double cal_table[XY]); static void resample_cal_table(double const cal_table_in[XY], - CameraMode const &camera_mode, - double cal_table_out[XY]); + CameraMode const &camera_mode, + Transform transform, + double cal_table_out[XY]); static void compensate_lambdas_for_cal(double const cal_table[XY], double const old_lambdas[XY], double new_lambdas[XY]); @@ -187,6 +188,7 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Transform transform, Metada // change, any effects should be transient, and if they're not transient // enough, we'll revisit the question then. camera_mode_ = camera_mode; + transform_ = transform; if (first_time_) { // On the first time, arrange for something sensible in the // initial tables. Construct the tables for some default colour @@ -194,9 +196,9 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Transform transform, Metada // adaptive algorithm. double cal_table_r[XY], cal_table_b[XY], cal_table_tmp[XY]; get_cal_table(4000, config_.calibrations_Cr, cal_table_tmp); - resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r); + resample_cal_table(cal_table_tmp, camera_mode_, transform_, cal_table_r); get_cal_table(4000, config_.calibrations_Cb, cal_table_tmp); - resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b); + resample_cal_table(cal_table_tmp, camera_mode_, transform_, cal_table_b); compensate_lambdas_for_cal(cal_table_r, lambda_r_, async_lambda_r_); compensate_lambdas_for_cal(cal_table_b, lambda_b_, @@ -379,7 +381,9 @@ void get_cal_table(double ct, std::vector const &calibrations, } void resample_cal_table(double const cal_table_in[XY], - CameraMode const &camera_mode, double cal_table_out[XY]) + CameraMode const &camera_mode, + Transform transform, + double cal_table_out[XY]) { // Precalculate and cache the x sampling locations and phases to save // recomputing them on every row. @@ -395,6 +399,8 @@ void resample_cal_table(double const cal_table_in[XY], xf[i] = x - x_lo[i]; x_hi[i] = std::min(x_lo[i] + 1, X - 1); x_lo[i] = std::max(x_lo[i], 0); + if (transform.contains(Transform::hflip())) + x_lo[i] = X - 1 - x_lo[i], x_hi[i] = X - 1 - x_hi[i]; } // Now march over the output table generating the new values. double scale_y = camera_mode.sensor_height / @@ -407,6 +413,8 @@ void resample_cal_table(double const cal_table_in[XY], double yf = y - y_lo; int y_hi = std::min(y_lo + 1, Y - 1); y_lo = std::max(y_lo, 0); + if (transform.contains(Transform::vflip())) + y_lo = Y - 1 - y_lo, y_hi = Y - 1 - y_hi; double const *row_above = cal_table_in + X * y_lo; double const *row_below = cal_table_in + X * y_hi; for (int i = 0; i < X; i++) { @@ -671,9 +679,9 @@ void Alsc::doAlsc() // Fetch the new calibrations (if any) for this CT. Resample them in // case the camera mode is not full-frame. get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp); - resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_r); + resample_cal_table(cal_table_tmp, async_camera_mode_, transform_, cal_table_r); get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp); - resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_b); + resample_cal_table(cal_table_tmp, async_camera_mode_, transform_, cal_table_b); // You could print out the cal tables for this image here, if you're // tuning the algorithm... (void)print_cal_table; diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp index 9b54578..9001e8a 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp @@ -60,7 +60,8 @@ private: // configuration is read-only, and available to both threads AlscConfig config_; bool first_time_; - std::atomic camera_mode_; + CameraMode camera_mode_; + libcamera::Transform transform_; std::thread async_thread_; void asyncFunc(); // asynchronous thread function std::mutex mutex_;