From patchwork Wed Sep 25 08:12:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 21350 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 60282C0F1B for ; Wed, 25 Sep 2024 08:16:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 04B0A6350B; Wed, 25 Sep 2024 10:16:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="O++BF+7f"; dkim-atps=neutral Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 441E463502 for ; Wed, 25 Sep 2024 10:16:03 +0200 (CEST) Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-205659dc63aso55246875ad.1 for ; Wed, 25 Sep 2024 01:16:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1727252161; x=1727856961; 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=tBhL4xEvsxdss/ASWIxhXN6eYcF3o/Wyd4aQEAOsBrg=; b=O++BF+7fQvClx7sFpwYRd8bDJ0VTaGRtisEYjwpmOyhACgtWjSm/Z7ACsKJuAffkKN ZzLHODMD9QpdnZGXh3ql5UljVn+TNbirng3o97BoB/X8nCk99lC9zBDHy/6OZwEJ/a0b vXYK/+diFzybG5hVgIhYPgRWwr/s5Lslnci7w= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727252161; x=1727856961; 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=tBhL4xEvsxdss/ASWIxhXN6eYcF3o/Wyd4aQEAOsBrg=; b=IlYwtpIiuPC8fwFLIGu3DhiN8pk7U7r9Nt6YC7lKHxWh5vIT73gIXvbL1W7NW0IaXc WO8fB9JVsykDPEr65olVIu7pQiNXutp3CCczBgaKu4Jv8UN+SFWTHDhT2bm+Y45F+PYM 7VOJkf7thky89kMgb6Xwcbz5wgkjFqbP0mrTXKm2O24EQ23NRbD5zgsAZECDKVj2K4KS 9D7YXWCCErxxIac77TM3Hj7Ap4wO4MXOa76FSDMMejeMXw4+ig6vWYrLzHdK7PR7uZz8 xHoKxPv5nsXfScMVxH4+9sPeIh9+mpCakD3sgs/u3YRpb04/nw88x4BR4JtOtTfKZNkf i39Q== X-Gm-Message-State: AOJu0YwmVyj7yDBOO8fZtKTOOP9+G8831dMwyzjwhI+v2GBaYr+RuzOE dYL+DvAna7qMGkpNPW0tL+Cen9RbrVoUGBv8GLiS9Mznz1aUf+jwKDAU2I8VSGVBtbn5c2OtrOo = X-Google-Smtp-Source: AGHT+IG04SXniC3wCns0hjTy1nUbhn/ErQCqDQPo4Z+CIniqwulOJmqkBLUlqcEP5lJn6axsUp8JKQ== X-Received: by 2002:a17:902:c94a:b0:202:26d:146c with SMTP id d9443c01a7336-20afc42d838mr24931395ad.5.1727252160864; Wed, 25 Sep 2024 01:16:00 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (0.223.81.34.bc.googleusercontent.com. [34.81.223.0]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b002aaa8fsm6336465ad.240.2024.09.25.01.15.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Sep 2024 01:16:00 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , Harvey Yang , Jacopo Mondi Subject: [PATCH v8 1/3] libcamera: Add rectangle two-point constructor Date: Wed, 25 Sep 2024 08:12:24 +0000 Message-ID: <20240925081551.3265942-2-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.792.g87dc391469-goog In-Reply-To: <20240925081551.3265942-1-chenghaoyang@google.com> References: <20240925081551.3265942-1-chenghaoyang@google.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: Yudhistira Erlandinata Add a Rectangle constructor that accepts two points: topLeft and bottomRight. Signed-off-by: Yudhistira Erlandinata Co-developed-by: Harvey Yang Reviewed-by: Jacopo Mondi --- include/libcamera/geometry.h | 7 +++++++ src/libcamera/geometry.cpp | 7 +++++++ test/geometry.cpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 3e6f0f5d..5949d55c 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -262,6 +262,13 @@ public: { } + constexpr Rectangle(const Point &point1, const Point &point2) + : Rectangle(std::min(point1.x, point2.x), std::max(point1.y, point2.y), + std::max(point1.x, point2.x) - std::min(point1.x, point2.x), + std::max(point1.y, point2.y) - std::min(point1.y, point2.y)) + { + } + int x; int y; unsigned int width; diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 00015136..3c47dcdc 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -629,6 +629,13 @@ std::ostream &operator<<(std::ostream &out, const SizeRange &sr) * \param[in] size The desired Rectangle size */ +/** + * \fn Rectangle::Rectangle(const Point &point1, const Point &point2) + * \brief Construct a Rectangle with the two given points + * \param[in] point1 One corner point of the rectangle + * \param[in] point2 The diagonal corner point from \a point1 + */ + /** * \var Rectangle::x * \brief The horizontal coordinate of the rectangle's top-left corner diff --git a/test/geometry.cpp b/test/geometry.cpp index 64169206..3ed2cc23 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -481,6 +481,20 @@ protected: return TestFail; } + Point topLeft(3, 3); + Point bottomRight(30, 30); + Point topRight(30, 3); + Point bottomLeft(3, 30); + Rectangle rect1(topLeft, bottomRight); + Rectangle rect2(topRight, bottomLeft); + Rectangle rect3(bottomRight, topLeft); + Rectangle rect4(bottomLeft, topRight); + + if (rect1 != rect2 || rect1 != rect3 || rect1 != rect4) { + cout << "Point-from-point construction failed" << endl; + return TestFail; + } + return TestPass; } }; From patchwork Wed Sep 25 08:12:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 21351 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 16005C0F1B for ; Wed, 25 Sep 2024 08:16:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9BB526350B; Wed, 25 Sep 2024 10:16:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="oLHloQKA"; dkim-atps=neutral Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 22A47634F4 for ; Wed, 25 Sep 2024 10:16:05 +0200 (CEST) Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-2053525bd90so60170455ad.0 for ; Wed, 25 Sep 2024 01:16:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1727252163; x=1727856963; 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=GWZlrTn3UIKHPYN3S3TmQEW5JGVkDju8QySmkcDjybo=; b=oLHloQKAy15ePGzt7lJxq9UQ/HTxW+3glvwlLPqL2ARf6+6dSfHRZALhGNwzELnyL2 01kGeZmWdPAm5G07Cpbf8vRFy0iXSb96pOCsPuFeXvk5JuTCDC5Q+5hickNBHgwMZnsy GCzEJbtFR1b5OLyOBzsvduktcExU3kckBE0qk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727252163; x=1727856963; 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=GWZlrTn3UIKHPYN3S3TmQEW5JGVkDju8QySmkcDjybo=; b=S14OsNZpXMEBnMUXMkR2Ybq54T0SCcVzKqTQ7E4o7806Q5ctaWJpUa0tBmLgFdvVXd y24rJ3iadPdLr/uylB9xOBn/aHkuOGoB3XdGN6ZLNcTWhjfxbYP6+ZGmomhtskrCUotT wFzPw6fQgoWl9W4xz3/PvJM84zZzg458Fj4FHcMkD4krf3z/CZeraQ8vDYrNoNKu0jtQ rDuivmL8vLdENd8ypBmVbZT8DFWjiHWCZNlZ29og0HF2Qf8zOZCTs3rMtAftDhhb9GAI 3vj6Dg1+e4pvd8Z37+xsRoqNvs95r+hZ6HJ3JNjDrQ7YTHhQ0WV272kr98IG6nN3WmFC 4mUQ== X-Gm-Message-State: AOJu0YxBWR2ba5peszyEWcghfgwj1336gHCXr+9HDPDzlkPv+Iom/Ffy apcMAtWQBTrez05z1uN5EZRUVncUbfWaMWagdlrgJzRtEXHcdgoshLYfczrjh3nfI4sfQnTz5kw = X-Google-Smtp-Source: AGHT+IERYT2KthmAJbnfu9sY/NJDGf+saa4glEfOrvG435tjaUV2adnRImTnZWeZhTphQq9AkCmenA== X-Received: by 2002:a17:902:d4c9:b0:1f6:fcd9:5b86 with SMTP id d9443c01a7336-20afc40cfd8mr36086535ad.12.1727252163308; Wed, 25 Sep 2024 01:16:03 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (0.223.81.34.bc.googleusercontent.com. [34.81.223.0]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b002aaa8fsm6336465ad.240.2024.09.25.01.16.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Sep 2024 01:16:02 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Yudhistira Erlandinata , becker hsieh , Harvey Yang , Jacopo Mondi Subject: [PATCH v8 2/3] libcamera: Add face detection controls Date: Wed, 25 Sep 2024 08:12:25 +0000 Message-ID: <20240925081551.3265942-3-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.792.g87dc391469-goog In-Reply-To: <20240925081551.3265942-1-chenghaoyang@google.com> References: <20240925081551.3265942-1-chenghaoyang@google.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: Yudhistira Erlandinata Add FaceDetectMode, FaceDetectFaceRectangles, FaceDetectFaceScores, and FaceDetectFaceLandmark. Also add ControlTypePoint for supporting FaceDetectFaceLandmark. Signed-off-by: Yudhistira Erlandinata Co-developed-by: becker hsieh Co-developed-by: Harvey Yang Reviewed-by: Jacopo Mondi --- include/libcamera/controls.h | 6 ++ src/libcamera/control_ids_draft.yaml | 88 ++++++++++++++++++++++++++++ src/libcamera/controls.cpp | 6 ++ 3 files changed, 100 insertions(+) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index 7c2bb287..bf1b8609 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -34,6 +34,7 @@ enum ControlType { ControlTypeString, ControlTypeRectangle, ControlTypeSize, + ControlTypePoint, }; namespace details { @@ -87,6 +88,11 @@ struct control_type { static constexpr ControlType value = ControlTypeSize; }; +template<> +struct control_type { + static constexpr ControlType value = ControlTypePoint; +}; + template struct control_type> : public control_type> { }; diff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml index 9bef5bf1..6a472b48 100644 --- a/src/libcamera/control_ids_draft.yaml +++ b/src/libcamera/control_ids_draft.yaml @@ -227,4 +227,92 @@ controls: value. All of the custom test patterns will be static (that is the raw image must not vary from frame to frame). + - FaceDetectMode: + type: uint8_t + description: | + Reporting mode of face detection. + + Currently identical to ANDROID_STATISTICS_FACE_DETECT_MODE. + + \sa FaceDetectFaceRectangles + \sa FaceDetectFaceScores + \sa FaceDetectFaceLandmarks + \sa FaceDetectFaceIds + + enum: + - name: FaceDetectModeOff + value: 0 + description: | + Pipeline should not report face detection result. + + - name: FaceDetectModeSimple + value: 1 + description: | + Pipeline should at least report FaceDetectFaceRectangles and + FaceDetectFaceScores for each detected face. + FaceDetectFaceLandmarks and FaceDetectFaceIds are optional. + + - name: FaceDetectModeFull + value: 2 + description: | + Pipeline should report all face controls, including + FaceDetectFaceRectangles, FaceDetectFaceScores, + FaceDetectFaceLandmarks, and FaceDeteceFaceIds. + + - FaceDetectFaceRectangles: + type: Rectangle + description: | + Boundary rectangles of the detected faces. + The number of values should be the number of faces reported in + FaceDetectFaceRectangles. + + The FaceDetectFaceRectangles control can only be returned in metadata. + + Currently identical to ANDROID_STATISTICS_FACE_RECTANGLES. + + size: [n] + + - FaceDetectFaceScores: + type: uint8_t + description: | + Confidence score of each of the detected faces by face detector. + The range of score is [0, 100]. + The FaceDetectFaceScores control can only be returned in metadata. + The number of values should be the number of faces reported in + FaceDetectFaceRectangles. + + Currently identical to ANDROID_STATISTICS_FACE_SCORES. + + size: [n] + + - FaceDetectFaceLandmarks: + type: Point + description: | + Array of human face landmark coordinates in format: + [..., left_eye_i, right_eye_i, mouth_i, left_eye_i+1, ...], + with i = index of face. + The number of values should be 3 * the number of faces reported in + FaceDetectFaceRectangles. + + The FaceDetectFaceLandmarks control can only be returned in metadata. + + Currently identical to ANDROID_STATISTICS_FACE_LANDMARKS. + + size: [n] + + - FaceDetectFaceIds: + type: int32_t + description: | + Each detected face is given a unique ID that is valid for as long as + the face is visible to the camera device. A face that leaves the field + of view and later returns may be assigned a new ID. + The number of values should be the number of faces reported in + FaceDetectFaceRectangles. + + The FaceDetectFaceIds control can only be returned in metadata. + + Currently identical to ANDROID_STATISTICS_FACE_IDS. + + size: [n] + ... diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index dba74404..c452e607 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -60,6 +60,7 @@ static constexpr size_t ControlValueSize[] = { [ControlTypeString] = sizeof(char), [ControlTypeRectangle] = sizeof(Rectangle), [ControlTypeSize] = sizeof(Size), + [ControlTypePoint] = sizeof(Point), }; } /* namespace */ @@ -254,6 +255,11 @@ std::string ControlValue::toString() const str += value->toString(); break; } + case ControlTypePoint: { + const Point *value = reinterpret_cast(data); + str += value->toString(); + break; + } case ControlTypeNone: case ControlTypeString: break; From patchwork Wed Sep 25 08:12:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cheng-Hao Yang X-Patchwork-Id: 21352 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 D320EC0F1B for ; Wed, 25 Sep 2024 08:16:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 78FD863513; Wed, 25 Sep 2024 10:16:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="akeOn2os"; dkim-atps=neutral Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8AEA363513 for ; Wed, 25 Sep 2024 10:16:07 +0200 (CEST) Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-206bd1c6ccdso61060965ad.3 for ; Wed, 25 Sep 2024 01:16:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1727252165; x=1727856965; 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=wbC26ApX1s3jY2T8aakSTnoyjjRaO6JZdJgUgnelnAc=; b=akeOn2osiyvxQbFK98SndtCnRZQSkRTcwzRylm2T1IwKALAZWN5LTnvD2FhvWqxRPF sUlcnuecY0JgtGCo7gX1JWqgwrieED76D+Ib3cvMfDxU0uhY/QWxm9cTh+di0GSO8QMw 3InJGKXCcD83cALJs4x86H+X2xE2mX09ySkRY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727252165; x=1727856965; 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=wbC26ApX1s3jY2T8aakSTnoyjjRaO6JZdJgUgnelnAc=; b=Ncv60Q5OmtgXd9+CeANH79Pg1zZgyAvdx11bsSnnrQsnLpqIIsyDOA46oghcPz5ySY coywRHOXJgwDNTcaJeWzrcaHKMz2b4ziG4GK+dJbt3EYQ6sQW7NIKXpi7S3xm2y7OG4x zd3wUPdcpGfUit4hURb/l9LuKH0H8mUlFWGqAVyuOBs/CT6zPFy03FwyYf67XkMrPusI EuwO94qhLVH66Sz5CC7q7AOayh8uXyVK9SzIw1iESvReMrFKb1u2kN/s6DUfdeH1TC/E NLDSdAaeBUhduOznz+qxAnlmGr0eAZEAHcRuf7TSN9WWLwekfoN6t84ge7Z8mq2FEnET egzw== X-Gm-Message-State: AOJu0YwVzc+UKntBGBxVeOL7taHouwhwFm3xlf8U3t+wbQVszWg2OoVI w8BwLR93MvQlI3sJyq2l+EbZ+L4G5Eu65VTLLiZ+u8mX1fJDuu/knJfqkpP0h0dnUbMehjmkIS4 = X-Google-Smtp-Source: AGHT+IEWC5hzX5lmMv3nRzFu5mEiiHItJ+kI728bQJX+yVdV3kGw0UWZa1cLUgWsZmIjZKxV+EXC8A== X-Received: by 2002:a17:902:e54c:b0:1fb:90e1:c8c5 with SMTP id d9443c01a7336-20afc48670bmr28580705ad.33.1727252165506; Wed, 25 Sep 2024 01:16:05 -0700 (PDT) Received: from chenghaoyang-low.c.googlers.com.com (0.223.81.34.bc.googleusercontent.com. [34.81.223.0]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20b002aaa8fsm6336465ad.240.2024.09.25.01.16.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Sep 2024 01:16:05 -0700 (PDT) From: Harvey Yang X-Google-Original-From: Harvey Yang To: libcamera-devel@lists.libcamera.org Cc: Harvey Yang , Yudhistira Erlandinata , Jacopo Mondi Subject: [PATCH v8 3/3] libcamera: android: Add face detection control support Date: Wed, 25 Sep 2024 08:12:26 +0000 Message-ID: <20240925081551.3265942-4-chenghaoyang@google.com> X-Mailer: git-send-email 2.46.0.792.g87dc391469-goog In-Reply-To: <20240925081551.3265942-1-chenghaoyang@google.com> References: <20240925081551.3265942-1-chenghaoyang@google.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: Harvey Yang Allow Android HAL adapter to pass the face detection metadata control to the pipeline and also send face detection metadata to the camera client if the pipeline generates it. Signed-off-by: Yudhistira Erlandinata Co-developed-by: Harvey Yang Reviewed-by: Jacopo Mondi --- src/android/camera_capabilities.cpp | 45 +++++++++++++++++-- src/android/camera_device.cpp | 70 ++++++++++++++++++++++++++++- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp index 71043e12..a89a3115 100644 --- a/src/android/camera_capabilities.cpp +++ b/src/android/camera_capabilities.cpp @@ -7,6 +7,8 @@ #include "camera_capabilities.h" +#include + #include #include #include @@ -1176,11 +1178,46 @@ int CameraCapabilities::initializeStaticMetadata() maxFrameDuration_); /* Statistics static metadata. */ - uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, - faceDetectMode); - int32_t maxFaceCount = 0; + auto iter = camera_->controls().find(controls::draft::FaceDetectMode.id()); + if (iter != camera_->controls().end()) { + const ControlInfo &faceDetectCtrlInfo = iter->second; + std::vector faceDetectModes; + bool hasFaceDetection = false; + + for (const auto &value : faceDetectCtrlInfo.values()) { + uint8_t mode = value.get(); + uint8_t androidMode = 0; + + switch (mode) { + case controls::draft::FaceDetectModeOff: + androidMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + break; + case controls::draft::FaceDetectModeSimple: + androidMode = ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE; + hasFaceDetection = true; + break; + default: + LOG(HAL, Fatal) << "Received invalid face detect mode: " << mode; + } + faceDetectModes.push_back(androidMode); + } + if (hasFaceDetection) { + /* + * \todo Create new libcamera controls to query max + * possible faces detected. + */ + maxFaceCount = 10; + staticMetadata_->addEntry( + ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, + faceDetectModes.data(), faceDetectModes.size()); + } + } else { + uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, + faceDetectMode); + } + staticMetadata_->addEntry(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, maxFaceCount); diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 493f66e7..e80b9e17 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include "system/graphics.h" @@ -813,6 +815,11 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor) controls.set(controls::ScalerCrop, cropRegion); } + if (settings.getEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, &entry)) { + const uint8_t *data = entry.data.u8; + controls.set(controls::draft::FaceDetectMode, data[0]); + } + if (settings.getEntry(ANDROID_SENSOR_TEST_PATTERN_MODE, &entry)) { const int32_t data = *entry.data.i32; int32_t testPatternMode = controls::draft::TestPatternModeOff; @@ -1540,8 +1547,9 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons value32 = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; resultMetadata->addEntry(ANDROID_SENSOR_TEST_PATTERN_MODE, value32); - value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, value); + settings.getEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, &entry); + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, + entry.data.u8, 1); value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, @@ -1580,6 +1588,64 @@ CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) cons resultMetadata->addEntry(ANDROID_SENSOR_FRAME_DURATION, *frameDuration * 1000); + const auto &faceDetectRectangles = + metadata.get(controls::draft::FaceDetectFaceRectangles); + if (faceDetectRectangles) { + std::vector flatRectangles; + for (const Rectangle &rect : *faceDetectRectangles) { + flatRectangles.push_back(rect.x); + flatRectangles.push_back(rect.y); + flatRectangles.push_back(rect.x + rect.width); + flatRectangles.push_back(rect.y + rect.height); + } + resultMetadata->addEntry( + ANDROID_STATISTICS_FACE_RECTANGLES, flatRectangles); + } + + const auto &faceDetectFaceScores = + metadata.get(controls::draft::FaceDetectFaceScores); + if (faceDetectRectangles && faceDetectFaceScores) { + if (faceDetectFaceScores->size() != faceDetectRectangles->size()) { + LOG(HAL, Error) << "Pipeline returned wrong number of face scores; " + << "Expected: " + << faceDetectRectangles->size() + << ", got: " << faceDetectFaceScores->size(); + } + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_SCORES, + *faceDetectRectangles); + } + + const auto &faceDetectFaceLandmarks = + metadata.get(controls::draft::FaceDetectFaceLandmarks); + if (faceDetectRectangles && faceDetectFaceLandmarks) { + size_t expectedLandmarks = faceDetectRectangles->size() * 3; + if (faceDetectFaceLandmarks->size() != expectedLandmarks) { + LOG(HAL, Error) << "Pipeline returned wrong number of face landmarks; " + << "Expected: " << expectedLandmarks + << ", got: " << faceDetectFaceLandmarks->size(); + } + + std::vector androidLandmarks; + for (const auto &landmark : *faceDetectFaceLandmarks) { + androidLandmarks.push_back(landmark.x); + androidLandmarks.push_back(landmark.y); + } + resultMetadata->addEntry( + ANDROID_STATISTICS_FACE_LANDMARKS, androidLandmarks); + } + + const auto &faceDetectFaceIds = + metadata.get(controls::draft::FaceDetectFaceIds); + if (faceDetectRectangles && faceDetectFaceIds) { + if (faceDetectFaceIds->size() != faceDetectRectangles->size()) { + LOG(HAL, Error) << "Pipeline returned wrong number of face ids; " + << "Expected: " + << faceDetectRectangles->size() + << ", got: " << faceDetectFaceIds->size(); + } + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_IDS, *faceDetectFaceIds); + } + const auto &scalerCrop = metadata.get(controls::ScalerCrop); if (scalerCrop) { const Rectangle &crop = *scalerCrop;