[libcamera-devel,v3,1/3] libcamera: Add support for monochrome sensors
diff mbox series

Message ID 20210618220430.31457-2-david.plowman@raspberrypi.com
State Superseded
Headers show
Series
  • Support monochrome raw sensors
Related show

Commit Message

David Plowman June 18, 2021, 10:04 p.m. UTC
This commit adds support for monochrome (greyscale) raw sensors. These
are sensors that have no colour filter array, so all pixels are the
same and there are no distinct colour channels.

These sensors still require many of an ISP's processing stages, such
as denoise, tone mapping, but not those that involve colours (such as
demosaic, or colour matrices).

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 include/libcamera/internal/bayer_format.h |  3 ++-
 src/libcamera/bayer_format.cpp            | 14 ++++++++++++--
 src/libcamera/camera_sensor.cpp           |  3 +++
 src/libcamera/property_ids.yaml           |  4 ++++
 4 files changed, 21 insertions(+), 3 deletions(-)

Comments

Laurent Pinchart June 28, 2021, 6:08 a.m. UTC | #1
Hi David,

Thank you for the patch.

On Fri, Jun 18, 2021 at 11:04:28PM +0100, David Plowman wrote:
> This commit adds support for monochrome (greyscale) raw sensors. These
> are sensors that have no colour filter array, so all pixels are the
> same and there are no distinct colour channels.
> 
> These sensors still require many of an ISP's processing stages, such
> as denoise, tone mapping, but not those that involve colours (such as
> demosaic, or colour matrices).

At some point we may want to rename BayerFormat to CFAPattern or
something similar, what do you think ? It's not a dependency for this
patch, so

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>  include/libcamera/internal/bayer_format.h |  3 ++-
>  src/libcamera/bayer_format.cpp            | 14 ++++++++++++--
>  src/libcamera/camera_sensor.cpp           |  3 +++
>  src/libcamera/property_ids.yaml           |  4 ++++
>  4 files changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/include/libcamera/internal/bayer_format.h b/include/libcamera/internal/bayer_format.h
> index 5b8c1dc9..723382d4 100644
> --- a/include/libcamera/internal/bayer_format.h
> +++ b/include/libcamera/internal/bayer_format.h
> @@ -23,7 +23,8 @@ public:
>  		BGGR = 0,
>  		GBRG = 1,
>  		GRBG = 2,
> -		RGGB = 3
> +		RGGB = 3,
> +		MONO = 4
>  	};
>  
>  	enum Packing : uint16_t {
> diff --git a/src/libcamera/bayer_format.cpp b/src/libcamera/bayer_format.cpp
> index ed61202c..11355f14 100644
> --- a/src/libcamera/bayer_format.cpp
> +++ b/src/libcamera/bayer_format.cpp
> @@ -45,6 +45,8 @@ namespace libcamera {
>   * \brief G then R on the first row, B then G on the second row.
>   * \var BayerFormat::RGGB
>   * \brief R then G on the first row, G then B on the second row.
> + * \var BayerFormat::MONO
> + * \brief Monochrome image data, there is no colour filter array.
>   */
>  
>  /**
> @@ -111,6 +113,8 @@ const std::map<BayerFormat, V4L2PixelFormat, BayerFormatComparator> bayerToV4l2{
>  	{ { BayerFormat::GBRG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },
>  	{ { BayerFormat::GRBG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },
>  	{ { BayerFormat::RGGB, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },
> +	{ { BayerFormat::MONO, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_GREY) },
> +	{ { BayerFormat::MONO, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_Y10P) },
>  };
>  
>  const std::unordered_map<unsigned int, BayerFormat> mbusCodeToBayer{
> @@ -146,6 +150,8 @@ const std::unordered_map<unsigned int, BayerFormat> mbusCodeToBayer{
>  	{ MEDIA_BUS_FMT_SGBRG16_1X16, { BayerFormat::GBRG, 16, BayerFormat::None } },
>  	{ MEDIA_BUS_FMT_SGRBG16_1X16, { BayerFormat::GRBG, 16, BayerFormat::None } },
>  	{ MEDIA_BUS_FMT_SRGGB16_1X16, { BayerFormat::RGGB, 16, BayerFormat::None } },
> +	{ MEDIA_BUS_FMT_Y8_1X8, { BayerFormat::MONO, 8, BayerFormat::None } },
> +	{ MEDIA_BUS_FMT_Y10_1X10, { BayerFormat::MONO, 10, BayerFormat::None } },
>  };
>  
>  } /* namespace */
> @@ -198,9 +204,10 @@ std::string BayerFormat::toString() const
>  		"BGGR",
>  		"GBRG",
>  		"GRBG",
> -		"RGGB"
> +		"RGGB",
> +		"MONO"
>  	};
> -	if (isValid() && order <= RGGB)
> +	if (isValid() && order <= MONO)
>  		result = orderStrings[order];
>  	else
>  		return "INVALID";
> @@ -280,6 +287,9 @@ BayerFormat BayerFormat::transform(Transform t) const
>  {
>  	BayerFormat result = *this;
>  
> +	if (order == MONO)
> +		return result;
> +
>  	/*
>  	 * Observe that flipping bit 0 of the Order enum performs a horizontal
>  	 * mirror on the Bayer pattern (e.g. RGGB goes to GRBG). Similarly,
> diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
> index 3e135353..fb67c15a 100644
> --- a/src/libcamera/camera_sensor.cpp
> +++ b/src/libcamera/camera_sensor.cpp
> @@ -427,6 +427,9 @@ int CameraSensor::initProperties()
>  		case BayerFormat::RGGB:
>  			cfa = properties::draft::RGGB;
>  			break;
> +		case BayerFormat::MONO:
> +			cfa = properties::draft::MONO;
> +			break;
>  		}
>  
>  		properties_.set(properties::draft::ColorFilterArrangement, cfa);
> diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml
> index 104e9aaf..12ecbce5 100644
> --- a/src/libcamera/property_ids.yaml
> +++ b/src/libcamera/property_ids.yaml
> @@ -706,5 +706,9 @@ controls:
>            description: |
>              Sensor is not Bayer; output has 3 16-bit values for each pixel,
>              instead of just 1 16-bit value per pixel.
> +        - name: MONO
> +          value: 5
> +          description: |
> +            Sensor is not Bayer; output consists of a single colour channel.
>  
>  ...

Patch
diff mbox series

diff --git a/include/libcamera/internal/bayer_format.h b/include/libcamera/internal/bayer_format.h
index 5b8c1dc9..723382d4 100644
--- a/include/libcamera/internal/bayer_format.h
+++ b/include/libcamera/internal/bayer_format.h
@@ -23,7 +23,8 @@  public:
 		BGGR = 0,
 		GBRG = 1,
 		GRBG = 2,
-		RGGB = 3
+		RGGB = 3,
+		MONO = 4
 	};
 
 	enum Packing : uint16_t {
diff --git a/src/libcamera/bayer_format.cpp b/src/libcamera/bayer_format.cpp
index ed61202c..11355f14 100644
--- a/src/libcamera/bayer_format.cpp
+++ b/src/libcamera/bayer_format.cpp
@@ -45,6 +45,8 @@  namespace libcamera {
  * \brief G then R on the first row, B then G on the second row.
  * \var BayerFormat::RGGB
  * \brief R then G on the first row, G then B on the second row.
+ * \var BayerFormat::MONO
+ * \brief Monochrome image data, there is no colour filter array.
  */
 
 /**
@@ -111,6 +113,8 @@  const std::map<BayerFormat, V4L2PixelFormat, BayerFormatComparator> bayerToV4l2{
 	{ { BayerFormat::GBRG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },
 	{ { BayerFormat::GRBG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },
 	{ { BayerFormat::RGGB, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },
+	{ { BayerFormat::MONO, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_GREY) },
+	{ { BayerFormat::MONO, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_Y10P) },
 };
 
 const std::unordered_map<unsigned int, BayerFormat> mbusCodeToBayer{
@@ -146,6 +150,8 @@  const std::unordered_map<unsigned int, BayerFormat> mbusCodeToBayer{
 	{ MEDIA_BUS_FMT_SGBRG16_1X16, { BayerFormat::GBRG, 16, BayerFormat::None } },
 	{ MEDIA_BUS_FMT_SGRBG16_1X16, { BayerFormat::GRBG, 16, BayerFormat::None } },
 	{ MEDIA_BUS_FMT_SRGGB16_1X16, { BayerFormat::RGGB, 16, BayerFormat::None } },
+	{ MEDIA_BUS_FMT_Y8_1X8, { BayerFormat::MONO, 8, BayerFormat::None } },
+	{ MEDIA_BUS_FMT_Y10_1X10, { BayerFormat::MONO, 10, BayerFormat::None } },
 };
 
 } /* namespace */
@@ -198,9 +204,10 @@  std::string BayerFormat::toString() const
 		"BGGR",
 		"GBRG",
 		"GRBG",
-		"RGGB"
+		"RGGB",
+		"MONO"
 	};
-	if (isValid() && order <= RGGB)
+	if (isValid() && order <= MONO)
 		result = orderStrings[order];
 	else
 		return "INVALID";
@@ -280,6 +287,9 @@  BayerFormat BayerFormat::transform(Transform t) const
 {
 	BayerFormat result = *this;
 
+	if (order == MONO)
+		return result;
+
 	/*
 	 * Observe that flipping bit 0 of the Order enum performs a horizontal
 	 * mirror on the Bayer pattern (e.g. RGGB goes to GRBG). Similarly,
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 3e135353..fb67c15a 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -427,6 +427,9 @@  int CameraSensor::initProperties()
 		case BayerFormat::RGGB:
 			cfa = properties::draft::RGGB;
 			break;
+		case BayerFormat::MONO:
+			cfa = properties::draft::MONO;
+			break;
 		}
 
 		properties_.set(properties::draft::ColorFilterArrangement, cfa);
diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml
index 104e9aaf..12ecbce5 100644
--- a/src/libcamera/property_ids.yaml
+++ b/src/libcamera/property_ids.yaml
@@ -706,5 +706,9 @@  controls:
           description: |
             Sensor is not Bayer; output has 3 16-bit values for each pixel,
             instead of just 1 16-bit value per pixel.
+        - name: MONO
+          value: 5
+          description: |
+            Sensor is not Bayer; output consists of a single colour channel.
 
 ...