From patchwork Mon May 16 14:10:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 15915 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 54B38C326C for ; Mon, 16 May 2022 14:11:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 02A0C65678; Mon, 16 May 2022 16:11:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1652710261; bh=IP2QL/5PkYu8iWZ2/e8dNVwMu0kVrrqLMzzix+9M7Vk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=JsRrYQR85pWh+muBYEVB84l5fuJylSDYa12Pk9kGdROCGchyJjY6k6r9Y6hmNAzVI m7HXkdcqAsqAZsb2dv/eprCeRdsW5n4lbOti4Y/ZIUrILbSA9hBfSTEWEuGzKdb10Q Ueugaoivr9eSsT8o2jC8t5ilqk1qy9SXzbnyRsXMpUWXajF8ye4YmcpCfrJBqe6Kyp SBSuSMy+SSsgGx1qamlUGbZ3F/bMIfhuJ2sxbVKPfOfQz+pi0JPpFeXXfBp1Wox2gp +VvoZ8/k9rBqfy72reIcqlvSTDSJaUgh/fgewPgSoMLEgj/bW6RwxwXwPw/zNrfo4D nOnLq1JSzqoYg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7DD8E65667 for ; Mon, 16 May 2022 16:10:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BzoYZ+k1"; dkim-atps=neutral Received: from deskari.lan (91-156-85-209.elisa-laajakaista.fi [91.156.85.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EC6D659D; Mon, 16 May 2022 16:10:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1652710252; bh=IP2QL/5PkYu8iWZ2/e8dNVwMu0kVrrqLMzzix+9M7Vk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BzoYZ+k1jHQFC6jrlye3iaDj3t/zanK2ns8Svwjewm+UcgKMFTgNRC/1J1B1bdH8K R6PK9cXdfvVJtGeW4xvnJmeWr/qS+iSRFePhH9VfiJLG65P4+3lsJQfaFTnjojq3WJ 8i0tmW6lbxhfqBdhnSLHl5Enr2mj7Ge50M35aIbA= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Mon, 16 May 2022 17:10:17 +0300 Message-Id: <20220516141022.96327-10-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220516141022.96327-1-tomi.valkeinen@ideasonboard.com> References: <20220516141022.96327-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/14] py: conv.py: minor cleanups 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: , X-Patchwork-Original-From: Tomi Valkeinen via libcamera-devel From: Tomi Valkeinen Reply-To: Tomi Valkeinen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Combine separate_components() with demosaic() and clean up the comments. Signed-off-by: Tomi Valkeinen --- src/py/libcamera/utils/conv.py | 54 ++++------------------------------ 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/src/py/libcamera/utils/conv.py b/src/py/libcamera/utils/conv.py index 71270671..2e483003 100644 --- a/src/py/libcamera/utils/conv.py +++ b/src/py/libcamera/utils/conv.py @@ -8,19 +8,8 @@ from numpy.lib.stride_tricks import as_strided import numpy as np -def separate_components(data, r0, g0, g1, b0): - # Now to split the data up into its red, green, and blue components. The - # Bayer pattern of the OV5647 sensor is BGGR. In other words the first - # row contains alternating green/blue elements, the second row contains - # alternating red/green elements, and so on as illustrated below: - # - # GBGBGBGBGBGBGB - # RGRGRGRGRGRGRG - # GBGBGBGBGBGBGB - # RGRGRGRGRGRGRG - # - # Please note that if you use vflip or hflip to change the orientation - # of the capture, you must flip the Bayer pattern accordingly +def demosaic(data, r0, g0, g1, b0): + # Separate the components from the Bayer data to RGB planes rgb = np.zeros(data.shape + (3,), dtype=data.dtype) rgb[r0[1]::2, r0[0]::2, 0] = data[r0[1]::2, r0[0]::2] # Red @@ -28,17 +17,9 @@ def separate_components(data, r0, g0, g1, b0): rgb[g1[1]::2, g1[0]::2, 1] = data[g1[1]::2, g1[0]::2] # Green rgb[b0[1]::2, b0[0]::2, 2] = data[b0[1]::2, b0[0]::2] # Blue - return rgb - - -def demosaic(rgb, r0, g0, g1, b0): - # At this point we now have the raw Bayer data with the correct values - # and colors but the data still requires de-mosaicing and - # post-processing. If you wish to do this yourself, end the script here! - # # Below we present a fairly naive de-mosaic method that simply # calculates the weighted average of a pixel based on the pixels - # surrounding it. The weighting is provided b0[1] a b0[1]te representation of + # surrounding it. The weighting is provided by a byte representation of # the Bayer filter which we construct first: bayer = np.zeros(rgb.shape, dtype=np.uint8) @@ -58,29 +39,6 @@ def demosaic(rgb, r0, g0, g1, b0): borders = (window[0] - 1, window[1] - 1) border = (borders[0] // 2, borders[1] // 2) - # rgb_pad = np.zeros(( - # rgb.shape[0] + borders[0], - # rgb.shape[1] + borders[1], - # rgb.shape[2]), dtype=rgb.dtype) - # rgb_pad[ - # border[0]:rgb_pad.shape[0] - border[0], - # border[1]:rgb_pad.shape[1] - border[1], - # :] = rgb - # rgb = rgb_pad - # - # bayer_pad = np.zeros(( - # bayer.shape[0] + borders[0], - # bayer.shape[1] + borders[1], - # bayer.shape[2]), dtype=bayer.dtype) - # bayer_pad[ - # border[0]:bayer_pad.shape[0] - border[0], - # border[1]:bayer_pad.shape[1] - border[1], - # :] = bayer - # bayer = bayer_pad - - # In numpy >=1.7.0 just use np.pad (version in Raspbian is 1.6.2 at the - # time of writing...) - # rgb = np.pad(rgb, [ (border[0], border[0]), (border[1], border[1]), @@ -157,7 +115,7 @@ def to_rgb(fmt, size, data): bayer_pattern = fmt[1:5] bitspp = int(fmt[5:]) - # TODO: shifting leaves the lowest bits 0 + # \todo shifting leaves the lowest bits 0 if bitspp == 8: data = data.reshape((h, w)) data = data.astype(np.uint16) << 8 @@ -184,8 +142,7 @@ def to_rgb(fmt, size, data): assert(idx != -1) b0 = (idx % 2, idx // 2) - rgb = separate_components(data, r0, g0, g1, b0) - rgb = demosaic(rgb, r0, g0, g1, b0) + rgb = demosaic(data, r0, g0, g1, b0) rgb = (rgb >> 8).astype(np.uint8) else: @@ -194,6 +151,7 @@ def to_rgb(fmt, size, data): return rgb +# A naive format conversion to 24-bit RGB def mfb_to_rgb(mfb:MappedFrameBuffer, cfg:StreamConfiguration): data = np.array(mfb.planes[0], dtype=np.uint8) rgb = to_rgb(cfg.pixel_format, cfg.size, data)