[v1,5/6] libtuning: Add initial AWB module
diff mbox series

Message ID 20240805120522.1613342-6-stefan.klug@ideasonboard.com
State Superseded
Headers show
Series
  • rkisp1: Add manual colour temperature control
Related show

Commit Message

Stefan Klug Aug. 5, 2024, 12:05 p.m. UTC
This AWB modules uses the awb function from Raspberry Pi to calculate
the needed white balance gains per colour temperature. It stores these
gains in the tuning file. Currently they are only used for the manual
colour temperature control. It is likely that they will be used with
more complex awb algorithms.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 .../tuning/libtuning/modules/awb/__init__.py  |  6 +++
 utils/tuning/libtuning/modules/awb/awb.py     | 42 +++++++++++++++++++
 utils/tuning/libtuning/modules/awb/rkisp1.py  | 27 ++++++++++++
 3 files changed, 75 insertions(+)
 create mode 100644 utils/tuning/libtuning/modules/awb/__init__.py
 create mode 100644 utils/tuning/libtuning/modules/awb/awb.py
 create mode 100644 utils/tuning/libtuning/modules/awb/rkisp1.py

Comments

Kieran Bingham Aug. 5, 2024, 1:50 p.m. UTC | #1
Quoting Stefan Klug (2024-08-05 13:05:06)
> This AWB modules uses the awb function from Raspberry Pi to calculate
> the needed white balance gains per colour temperature. It stores these
> gains in the tuning file. Currently they are only used for the manual
> colour temperature control. It is likely that they will be used with
> more complex awb algorithms.
> 
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> ---
>  .../tuning/libtuning/modules/awb/__init__.py  |  6 +++
>  utils/tuning/libtuning/modules/awb/awb.py     | 42 +++++++++++++++++++
>  utils/tuning/libtuning/modules/awb/rkisp1.py  | 27 ++++++++++++
>  3 files changed, 75 insertions(+)
>  create mode 100644 utils/tuning/libtuning/modules/awb/__init__.py
>  create mode 100644 utils/tuning/libtuning/modules/awb/awb.py
>  create mode 100644 utils/tuning/libtuning/modules/awb/rkisp1.py
> 
> diff --git a/utils/tuning/libtuning/modules/awb/__init__.py b/utils/tuning/libtuning/modules/awb/__init__.py
> new file mode 100644
> index 000000000000..2d67f10cfc4f
> --- /dev/null
> +++ b/utils/tuning/libtuning/modules/awb/__init__.py
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2024, Ideas On Board
> +
> +from libtuning.modules.awb.awb import AWB
> +from libtuning.modules.awb.rkisp1 import AWBRkISP1
> diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py
> new file mode 100644
> index 000000000000..5680a44fd3e3
> --- /dev/null
> +++ b/utils/tuning/libtuning/modules/awb/awb.py
> @@ -0,0 +1,42 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2024, Ideas On Board
> +
> +import logging
> +
> +from ..module import Module
> +
> +from libtuning.ctt_awb import awb
> +import numpy as np
> +
> +logger = logging.getLogger(__name__)
> +
> +
> +class AWB(Module):
> +    type = 'awb'
> +    hr_name = 'AWB (Base)'
> +    out_name = 'GenericAWB'
> +
> +    def __init__(self, *,
> +                 debug: list):
> +        super().__init__()
> +
> +        self.debug = debug
> +
> +    def do_calculation(self, images):
> +        logger.info('Starting AWB calculation')
> +
> +        imgs = [img for img in images if img.macbeth is not None]
> +
> +        gains, _, _ = awb(imgs, None, None, False)
> +        gains = np.array(gains)
> +        gains = gains.reshape(-1, 3)
> +
> +        res = []
> +        for v in gains:
> +            res.append({
> +                'ct': int(v[0]),
> +                'gains': [float(1.0 / v[1]), float(1.0 / v[2])]
> +            })
> +
> +        return res
> diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py
> new file mode 100644
> index 000000000000..e3ddeb50c9a1
> --- /dev/null
> +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2024, Ideas On Board
> +#
> +# AWB module for tuning rkisp1

I think I'm not familiar enough yet with how we're handling platform
specific details here.

Is there anything in this that is RkISP1 specific? Or will it be ?
It feels like these are generic so far...

> +
> +from .awb import AWB
> +
> +import libtuning as lt
> +
> +
> +class AWBRkISP1(AWB):
> +    hr_name = 'AWB (RkISP1)'
> +    out_name = 'Awb'
> +
> +    def __init__(self, **kwargs):
> +        super().__init__(**kwargs)
> +
> +    def validate_config(self, config: dict) -> bool:
> +        return True
> +
> +    def process(self, config: dict, images: list, outputs: dict) -> dict:
> +        output = {}
> +
> +        output['gains'] = self.do_calculation(images)
> +
> +        return output
> -- 
> 2.43.0
>
Stefan Klug Aug. 6, 2024, 6:53 a.m. UTC | #2
Hi Kieran,

Thank you for the review. 

On Mon, Aug 05, 2024 at 02:50:54PM +0100, Kieran Bingham wrote:
> Quoting Stefan Klug (2024-08-05 13:05:06)
> > This AWB modules uses the awb function from Raspberry Pi to calculate
> > the needed white balance gains per colour temperature. It stores these
> > gains in the tuning file. Currently they are only used for the manual
> > colour temperature control. It is likely that they will be used with
> > more complex awb algorithms.
> > 
> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> > ---
> >  .../tuning/libtuning/modules/awb/__init__.py  |  6 +++
> >  utils/tuning/libtuning/modules/awb/awb.py     | 42 +++++++++++++++++++
> >  utils/tuning/libtuning/modules/awb/rkisp1.py  | 27 ++++++++++++
> >  3 files changed, 75 insertions(+)
> >  create mode 100644 utils/tuning/libtuning/modules/awb/__init__.py
> >  create mode 100644 utils/tuning/libtuning/modules/awb/awb.py
> >  create mode 100644 utils/tuning/libtuning/modules/awb/rkisp1.py
> > 
> > diff --git a/utils/tuning/libtuning/modules/awb/__init__.py b/utils/tuning/libtuning/modules/awb/__init__.py
> > new file mode 100644
> > index 000000000000..2d67f10cfc4f
> > --- /dev/null
> > +++ b/utils/tuning/libtuning/modules/awb/__init__.py
> > @@ -0,0 +1,6 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2024, Ideas On Board
> > +
> > +from libtuning.modules.awb.awb import AWB
> > +from libtuning.modules.awb.rkisp1 import AWBRkISP1
> > diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py
> > new file mode 100644
> > index 000000000000..5680a44fd3e3
> > --- /dev/null
> > +++ b/utils/tuning/libtuning/modules/awb/awb.py
> > @@ -0,0 +1,42 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2024, Ideas On Board
> > +
> > +import logging
> > +
> > +from ..module import Module
> > +
> > +from libtuning.ctt_awb import awb
> > +import numpy as np
> > +
> > +logger = logging.getLogger(__name__)
> > +
> > +
> > +class AWB(Module):
> > +    type = 'awb'
> > +    hr_name = 'AWB (Base)'
> > +    out_name = 'GenericAWB'
> > +
> > +    def __init__(self, *,
> > +                 debug: list):
> > +        super().__init__()
> > +
> > +        self.debug = debug
> > +
> > +    def do_calculation(self, images):
> > +        logger.info('Starting AWB calculation')
> > +
> > +        imgs = [img for img in images if img.macbeth is not None]
> > +
> > +        gains, _, _ = awb(imgs, None, None, False)
> > +        gains = np.array(gains)
> > +        gains = gains.reshape(-1, 3)
> > +
> > +        res = []
> > +        for v in gains:
> > +            res.append({
> > +                'ct': int(v[0]),
> > +                'gains': [float(1.0 / v[1]), float(1.0 / v[2])]
> > +            })
> > +
> > +        return res
> > diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py
> > new file mode 100644
> > index 000000000000..e3ddeb50c9a1
> > --- /dev/null
> > +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py
> > @@ -0,0 +1,27 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2024, Ideas On Board
> > +#
> > +# AWB module for tuning rkisp1
> 
> I think I'm not familiar enough yet with how we're handling platform
> specific details here.
> 
> Is there anything in this that is RkISP1 specific? Or will it be ?
> It feels like these are generic so far... 

Valid point. At the moment I just follow the structure that was there
before. On the other hand we do not yet know exactly where we end up
(The Raspberry Pi awb section looks quite different from this one.) So
maybe there is also a benefit in keeping it separate for now and to see
which parts settle on a common denominator.

I can merge it into one class if you like that more. Maybe Paul has an
opinion on that.

Best regards,
Stefan

> > +
> > +from .awb import AWB
> > +
> > +import libtuning as lt
> > +
> > +
> > +class AWBRkISP1(AWB):
> > +    hr_name = 'AWB (RkISP1)'
> > +    out_name = 'Awb'
> > +
> > +    def __init__(self, **kwargs):
> > +        super().__init__(**kwargs)
> > +
> > +    def validate_config(self, config: dict) -> bool:
> > +        return True
> > +
> > +    def process(self, config: dict, images: list, outputs: dict) -> dict:
> > +        output = {}
> > +
> > +        output['gains'] = self.do_calculation(images)
> > +
> > +        return output
> > -- 
> > 2.43.0
> >
Kieran Bingham Aug. 6, 2024, 8:56 a.m. UTC | #3
Quoting Stefan Klug (2024-08-06 07:53:40)
> Hi Kieran,
> 
> Thank you for the review. 
> 
> On Mon, Aug 05, 2024 at 02:50:54PM +0100, Kieran Bingham wrote:
> > Quoting Stefan Klug (2024-08-05 13:05:06)
> > > This AWB modules uses the awb function from Raspberry Pi to calculate
> > > the needed white balance gains per colour temperature. It stores these
> > > gains in the tuning file. Currently they are only used for the manual
> > > colour temperature control. It is likely that they will be used with
> > > more complex awb algorithms.
> > > 
> > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> > > ---
> > >  .../tuning/libtuning/modules/awb/__init__.py  |  6 +++
> > >  utils/tuning/libtuning/modules/awb/awb.py     | 42 +++++++++++++++++++
> > >  utils/tuning/libtuning/modules/awb/rkisp1.py  | 27 ++++++++++++
> > >  3 files changed, 75 insertions(+)
> > >  create mode 100644 utils/tuning/libtuning/modules/awb/__init__.py
> > >  create mode 100644 utils/tuning/libtuning/modules/awb/awb.py
> > >  create mode 100644 utils/tuning/libtuning/modules/awb/rkisp1.py
> > > 
> > > diff --git a/utils/tuning/libtuning/modules/awb/__init__.py b/utils/tuning/libtuning/modules/awb/__init__.py
> > > new file mode 100644
> > > index 000000000000..2d67f10cfc4f
> > > --- /dev/null
> > > +++ b/utils/tuning/libtuning/modules/awb/__init__.py
> > > @@ -0,0 +1,6 @@
> > > +# SPDX-License-Identifier: GPL-2.0-or-later
> > > +#
> > > +# Copyright (C) 2024, Ideas On Board
> > > +
> > > +from libtuning.modules.awb.awb import AWB
> > > +from libtuning.modules.awb.rkisp1 import AWBRkISP1
> > > diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py
> > > new file mode 100644
> > > index 000000000000..5680a44fd3e3
> > > --- /dev/null
> > > +++ b/utils/tuning/libtuning/modules/awb/awb.py
> > > @@ -0,0 +1,42 @@
> > > +# SPDX-License-Identifier: GPL-2.0-or-later
> > > +#
> > > +# Copyright (C) 2024, Ideas On Board
> > > +
> > > +import logging
> > > +
> > > +from ..module import Module
> > > +
> > > +from libtuning.ctt_awb import awb
> > > +import numpy as np
> > > +
> > > +logger = logging.getLogger(__name__)
> > > +
> > > +
> > > +class AWB(Module):
> > > +    type = 'awb'
> > > +    hr_name = 'AWB (Base)'
> > > +    out_name = 'GenericAWB'
> > > +
> > > +    def __init__(self, *,
> > > +                 debug: list):
> > > +        super().__init__()
> > > +
> > > +        self.debug = debug
> > > +
> > > +    def do_calculation(self, images):
> > > +        logger.info('Starting AWB calculation')
> > > +
> > > +        imgs = [img for img in images if img.macbeth is not None]
> > > +
> > > +        gains, _, _ = awb(imgs, None, None, False)
> > > +        gains = np.array(gains)
> > > +        gains = gains.reshape(-1, 3)
> > > +
> > > +        res = []
> > > +        for v in gains:
> > > +            res.append({
> > > +                'ct': int(v[0]),
> > > +                'gains': [float(1.0 / v[1]), float(1.0 / v[2])]
> > > +            })
> > > +
> > > +        return res
> > > diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py
> > > new file mode 100644
> > > index 000000000000..e3ddeb50c9a1
> > > --- /dev/null
> > > +++ b/utils/tuning/libtuning/modules/awb/rkisp1.py
> > > @@ -0,0 +1,27 @@
> > > +# SPDX-License-Identifier: GPL-2.0-or-later
> > > +#
> > > +# Copyright (C) 2024, Ideas On Board
> > > +#
> > > +# AWB module for tuning rkisp1
> > 
> > I think I'm not familiar enough yet with how we're handling platform
> > specific details here.
> > 
> > Is there anything in this that is RkISP1 specific? Or will it be ?
> > It feels like these are generic so far... 
> 
> Valid point. At the moment I just follow the structure that was there
> before. On the other hand we do not yet know exactly where we end up
> (The Raspberry Pi awb section looks quite different from this one.) So
> maybe there is also a benefit in keeping it separate for now and to see
> which parts settle on a common denominator.
> 
> I can merge it into one class if you like that more. Maybe Paul has an
> opinion on that.

I'll leave that to your discretion ... as long as we're considering
things!

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> 
> Best regards,
> Stefan
> 
> > > +
> > > +from .awb import AWB
> > > +
> > > +import libtuning as lt
> > > +
> > > +
> > > +class AWBRkISP1(AWB):
> > > +    hr_name = 'AWB (RkISP1)'
> > > +    out_name = 'Awb'
> > > +
> > > +    def __init__(self, **kwargs):
> > > +        super().__init__(**kwargs)
> > > +
> > > +    def validate_config(self, config: dict) -> bool:
> > > +        return True
> > > +
> > > +    def process(self, config: dict, images: list, outputs: dict) -> dict:
> > > +        output = {}
> > > +
> > > +        output['gains'] = self.do_calculation(images)
> > > +
> > > +        return output
> > > -- 
> > > 2.43.0
> > >

Patch
diff mbox series

diff --git a/utils/tuning/libtuning/modules/awb/__init__.py b/utils/tuning/libtuning/modules/awb/__init__.py
new file mode 100644
index 000000000000..2d67f10cfc4f
--- /dev/null
+++ b/utils/tuning/libtuning/modules/awb/__init__.py
@@ -0,0 +1,6 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2024, Ideas On Board
+
+from libtuning.modules.awb.awb import AWB
+from libtuning.modules.awb.rkisp1 import AWBRkISP1
diff --git a/utils/tuning/libtuning/modules/awb/awb.py b/utils/tuning/libtuning/modules/awb/awb.py
new file mode 100644
index 000000000000..5680a44fd3e3
--- /dev/null
+++ b/utils/tuning/libtuning/modules/awb/awb.py
@@ -0,0 +1,42 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2024, Ideas On Board
+
+import logging
+
+from ..module import Module
+
+from libtuning.ctt_awb import awb
+import numpy as np
+
+logger = logging.getLogger(__name__)
+
+
+class AWB(Module):
+    type = 'awb'
+    hr_name = 'AWB (Base)'
+    out_name = 'GenericAWB'
+
+    def __init__(self, *,
+                 debug: list):
+        super().__init__()
+
+        self.debug = debug
+
+    def do_calculation(self, images):
+        logger.info('Starting AWB calculation')
+
+        imgs = [img for img in images if img.macbeth is not None]
+
+        gains, _, _ = awb(imgs, None, None, False)
+        gains = np.array(gains)
+        gains = gains.reshape(-1, 3)
+
+        res = []
+        for v in gains:
+            res.append({
+                'ct': int(v[0]),
+                'gains': [float(1.0 / v[1]), float(1.0 / v[2])]
+            })
+
+        return res
diff --git a/utils/tuning/libtuning/modules/awb/rkisp1.py b/utils/tuning/libtuning/modules/awb/rkisp1.py
new file mode 100644
index 000000000000..e3ddeb50c9a1
--- /dev/null
+++ b/utils/tuning/libtuning/modules/awb/rkisp1.py
@@ -0,0 +1,27 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2024, Ideas On Board
+#
+# AWB module for tuning rkisp1
+
+from .awb import AWB
+
+import libtuning as lt
+
+
+class AWBRkISP1(AWB):
+    hr_name = 'AWB (RkISP1)'
+    out_name = 'Awb'
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+
+    def validate_config(self, config: dict) -> bool:
+        return True
+
+    def process(self, config: dict, images: list, outputs: dict) -> dict:
+        output = {}
+
+        output['gains'] = self.do_calculation(images)
+
+        return output