summaryrefslogtreecommitdiff
path: root/src/ipa/libipa
AgeCommit message (Collapse)Author
4 dayslibipa: awb_grey: Minor comment fixesLaurent Pinchart
Fix the top-level file description to mention the file contains an AWB grey world implementation, not a base class, and fix a grammar mistake in a documentation block. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Tidy up includesLaurent Pinchart
Drop unneeded headers and add missing ones. The yaml_parser.h header is dropped from awb_grey.h as the classes it provides are only used in virtual functions defined by the base class, so any required definitions are guaranteed to be available already. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Rename AwbStats::getRGBMeans() to rgbMeans()Laurent Pinchart
The convention in libcamera is not to prefix getters with a 'get' prefix. Rename the AwbStats::getRGBMeans() function accordingly. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Pass lux value to calculateAwb() as unsigned intLaurent Pinchart
The lux value can never be negative. Pass it as an unsigned int. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Replace reference to pipeline handle with IPA moduleLaurent Pinchart
The AwbStats documentation incorrectly references pipeline handlers when it means IPA modules. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Standardize spelling on 'grey' worldLaurent Pinchart
All locations but one spell 'grey' instead of 'gray'. Fix the outlier. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Follow function names with '()' in doxygen documentationLaurent Pinchart
Function names are followed by parentheses in doxygen documentation blocks as convention in libcamera. Add missing parentheses in the AwbAlgorithm documentation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Capitalize AWBLaurent Pinchart
AWB is an abbreviation, capitalize it in comments and log messages for consistency. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
4 dayslibipa: awb: Sort class member documentation according to header orderLaurent Pinchart
Sort the documentation of the class members in the same order as the member declaration in the class definition, as is customary in libcamera. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
7 dayslibipa: awb_bayes: Change the probabilities from log space to linear spaceStefan Klug
The original code used to specify the probabilities in log space and scaled for the RaspberryPi hardware with 192 AWB measurement points. This is reasonable as the whole algorithm makes use of unitless numbers to prefer some colour temperatures based on a lux level. These numbers are then hand tuned with the specific device in mind. This has two shortcomings: 1. The linear interpolation of PWLs in log space is mathematically incorrect. The outcome might still be ok, as both spaces (log and linear) are monotonic, but it is still not "right". 2. Having unitless numbers gets more error prone when we try to harmonize the behavior over multiple platforms. Change the algorithm to interpret the numbers as being in linear space. This makes the interpolation mathematically correct at the expense of a few log operations. To account for that change, update the numbers in the tuning example file with the linear counterparts scaled to one AWB zone measurement. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: awb_bayes: Remove overly verbose log messagesStefan Klug
Logging every search step is too verbose even with debug messages enabled and it hides the more important messages (min max values of errors and likelihoods). Remove the debug messages in a separate commit, so that it can easily be reverted if needed. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: awb_bayes: Add logging of value limitsStefan Klug
When tuning the AWB algorithm it is more helpful to get a feeling for the value ranges than to get verbose output of every single step. Add a small utility class to track the limits and log them. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: lux: Normalize referenceY to 1Stefan Klug
By normalizing the referenceY value to 1 (which is the usual range for Y) in the tuning file, the bins_ value is no longer needed. Remove it. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: Add bayesian AWB algorithmStefan Klug
The bayesian AWB algorithm is an AWB algorithm that takes prior probabilities for a given light source dependent on the current lux level into account. The biggest improvement compared to the grey world model comes from the search of the ideal white point on the CT curve. The algorithm walks the CT curve to minimize the colour error for a given statistics. After the minimium is found it additionally tries to search the area around that spot and also off the curve. So even without defined prior probabilities this algorithm provides much better results than the grey world algorithm. The logic for this code was taken from the RaspberryPi implementation. The logic was only minimally adjusted for usage with the rkisp1 and a few things were left out (see doxygen doc for the AwbBayes class). The code is refactored to better fit the libcamera code style and to make use of the syntactic sugar provided by the Interpolator and Vector classes. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: Add grey world AWB algorithmStefan Klug
Add the grey world algorithm that is currently used in rkisp1 to libipa. No changes in functionality were made. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
7 dayslibipa: awb: Add helper functions for AWB mode supportStefan Klug
The AWB modes are specified in the libcamera core controls. It is therefore quite likely that every AWB algorithm will implement them. Add helper functions for parsing and storing the configured modes in the AwbAlgorithm base class. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: Add AWB algorithm base classStefan Klug
Add a class to provide a generic interface for auto white balance algorithms. Concrete AWB algorithms are expected to subclass the AwbAlgorithm class to implement their functionality. IPAs are expected to subclass the AwbStats class and implement the necessary functions to give the algorithm access to the hardware specific statistics data. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
7 dayslibipa: pwl: Add clear() functionStefan Klug
Sometimes it is necessary to clear a pwl. Add a function for that. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
7 dayslibipa: interpolator: Add accessor to internal dataStefan Klug
The only way to access the internal data of an Interpolator is through the getInterpolated() method. Sometimes it is necessary to to access the internal data directly to iterate over it. Add an accessor for that. While at it, remove a line break from the doxygen documentation for interpolate() so that doxygen is able to correctly match the function. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2025-02-12libipa: Drop Vector classStefan Klug
The Vector class from libipa is not used anymore. Drop it. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-02-12ipa: Use Vector class from libcameraStefan Klug
Now that there is a Vector class in libcamera, use that one. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2025-01-24ipa: libipa: lux: Fix indentationLaurent Pinchart
Indentation in a doxygen comment is wrong, fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2024-12-23ipa: libipa: Add Lux helperPaul Elder
Add a Lux helper to libipa that does the estimation of the lux level given gain, exposure, and luminance histogram. The helper also handles reading the reference values from the tuning file. These are expected to be common operations of lux algorithm modules in IPAs, and is modeled/copied from Raspberry Pi. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
2024-12-17libipa: Centralise Fixed / Floating point convertorsDaniel Scally
The rkisp1 IPA has some utility functions to convert between fixed and floating point numbers. Move those to libipa so they're available for use in other IPA modules too. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-09libcamera: libipa: camera_sensor_helper: Use `variant` instead of `union`Barnabás Pőcze
Use an `std::variant` to store the analogue gain instead of a bare union + tag. Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-04libipa: agc_mean_luminance: Rename yaml key from exposure-time to exposureTimeStefan Klug
In d0478c41f432 ("libcamera: Rename "shutter speed" to "exposure time"") the tuning file entry "shutter" was renamed to "exposure-time". As the tuning files use camel cased key names, change "exposure-time" to "exposureTime" for consistency. It doesn't break our users setups as there are no tuning files using that entry in the wild (at least officially). Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-12-03libipa: Drop Matrix classStefan Klug
There are no users of the libipa::Matrix class anymore. Drop it. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-12-03libipa: Use Matrix class from libcameraStefan Klug
Use the Matrix class from libcamera/internal in libipa so that the one from libipa can be dropped later. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-29libcamera: libipa: camera_sensor: Add GalaxyCore gc08a3 sensor propertiesHarvey Yang
Provide the GalaxyCore gc08a3 camera sensor properties and registration with libipa for the gain code helpers. Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org> Co-developed-by: Xing Gu <xinggu@chromium.org> Signed-off-by: Xing Gu <xinggu@chromium.org> Co-developed-by: Yudhistira Erlandinata <yerlandinata@chromium.org> Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-29libcamera: libipa: camera_sensor: Add GalaxyCore gc05a2 sensor propertiesHarvey Yang
Provide the GalaxyCore gc05a2 camera sensor properties and registration with libipa for the gain code helpers. Signed-off-by: Han-Lin Chen <hanlinchen@chromium.org> Co-developed-by: Xing Gu <xinggu@chromium.org> Signed-off-by: Xing Gu <xinggu@chromium.org> Co-developed-by: Yudhistira Erlandinata <yerlandinata@chromium.org> Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-26ipa: libipa: colour: Use Vector and Matrix for linear algebraLaurent Pinchart
Replace the manual vector and matrix calculations with usage of the Vector and Matrix classes. This simplifies the code and improves readability. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: colour: Use the RGB class to model RGB valuesLaurent Pinchart
The rec601LuminanceFromRGB() and estimateCCT() functions take RGB triplets as three variables. Replace them with instances of the RGB class and adapt the users accordingly. Only variables passed directly to these functions are converted to RGB instances, further conversion of IPA modules to the RGB class will be performed separately. While at it, fix a typo in the documentation of the estimateCCT() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add sum() functionLaurent Pinchart
Add a function to calculate the sum of a vector. It will be useful for algorithms. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add element-wise min() and max() functionsLaurent Pinchart
Add functions to calculate the element-wise minimum and maximum of two vectors or of a vector and a scalar. This will be used in algorithm implementations. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add compound assignment operatorsLaurent Pinchart
Extend the Vector class with compound assignment operators that match the binary arithmetic operators. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add missing binary arithemtic operatorsLaurent Pinchart
The Vector class defines multiple element-wise arithmetic operators between vectors or between a vector and a scalar. A few variants are missing. Add them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Generalize arithmetic operatorsLaurent Pinchart
Instead of hand-coding all arithmetic operators, implement them based on a generic apply() function that takes an operator-specific binary operators. This will simplify adding missing arithmetic operators. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Rename the dot product operator*() to dot()Laurent Pinchart
The Vector class defines a set of arithmetic operators between two vectors or a vector and a scalar. All the operators perform element-wise operations, except for the operator*() that computes the dot product. This is inconsistent and confusing. Replace the operator with a dot() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add scalar constructorLaurent Pinchart
The default constructor leaves the vector data uninitialized. Add a constructor to fill the vector with copies of a scalar value, and fix the documentation of the default constructor. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add r(), g() and b() accessorsLaurent Pinchart
The Vector class can be useful to represent RGB pixel values. Add r(), g() and b() accessors, similar to x(), y() and z(), along with an RGB type that aliases Vector<T, 3>. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26ipa: libipa: vector: Add mutable x(), y() and z() accessorsLaurent Pinchart
The x(), y() and z() functions of the Vector class are convenience accessors for the first, second and third element of the vector respectively, meant to improve readability of class users when a vector represents coordinates in 1D, 2D or 3D space. Those accessors are limited to immutable access to the vector elements, as they return a copy. Extend the API with mutable accessors. The immutable accessors are modified to return a reference to the vector elements instead of a copy for consistency. As they are inline functions, this should make no difference in terms of performance as the compiler can perform the same optimizations in their case. While at it, reorder functions to declare operators before other member functions, to be consistent with the usual coding style. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2024-11-26libcamera: Rename "shutter speed" to "exposure time"Laurent Pinchart
The terms "shutter" and "shutter speed" are used through libcamera to mean "exposure time". This is confusing, both due to "speed" being used as "time" while it should be the inverse (i.e. a maximum speed should correspond to the minimum time), and due to "shutter speed" and "exposure time" being used in different places with the same meaning. To improve clarity of the code base and the documentation, use "exposure time" consistently to replace "shutter speed". This rename highlighted another vocabulary issue in libcamera. The ExposureModeHelper::splitExposure() function used to document that it splits "exposure time into shutter time and gain". It has been reworded to "split exposure into exposure time and gain". That is not entirely satisfactory, as "exposure" has a defined meaning in photography (see https://en.wikipedia.org/wiki/Exposure_(photography)) that is not expressed as a duration. This issue if left to be addressed separately. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-11-25libcamera: libipa: camera_sensor_helper: add IMX290 black levelGeoffrey Van Landeghem
Report the default sensor black level reported by the datasheet. Note that IMX327 and IMX462 depend on the IMX290 CameraSensorHelper. That's fine since those sensors report the same defaults for the black level as the Sony IMX290. Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25libcamera: libipa: camera_sensor: Provide helper and properties for Sony IMX462Geoffrey Van Landeghem
The sensor is largely compatible with the already supported Sony IMX290 so we can reuse the same helpers for the analogue gain conversion functions. Signed-off-by: Geoffrey Van Landeghem <geoffrey.vl@gmail.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-11-25libipa: FCQueue: Make sure FrameContext#0 is initializedJacopo Mondi
Some IPA modules, like the RkISP1 one, call FCQueue::get(0) at IPA::start() time, before any frame context has been allocated with FCQueue::alloc() called at queueRequest() time. The FCQueue implementation aims to detect when a FrameContext is get() before it is alloc()-ated, Warns about it, and initializes the FrameContext before returning it. In case of frame#0, a get() preceding an alloc() call is not detected as the "frame == frameContext.frame" test returns success, as FrameContexts are zeroed by default. As a result, the first returned FrameContext is not initialized. Explicitly test for frame#0 to make sure the FrameContext is initialized if get(0) is called before alloc(0). To avoid re-initializing a frame context, in case alloc() has been called correctly before get(), introduce an "initialised" state variable that tracks the FrameContext initialisation state. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-11-18ipa: libipa: Add colour helpersDaniel Scally
We start to have some functions relating to colour that are effectively identical crop up across the IPA modules. Add a file allowing those to be centralised within libipa so that a single implementation can be used in all of the IPAs. Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-11-13ipa: libipa: Add data accessor to HistogramStefan Klug
For debugging purposes it is helpful to access the internal data of the histogram. Add an accessor for that. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-10-28ipa: libipa: Fix ExposureModeHelper function name in documentationLaurent Pinchart
Previous iterations of the ExposureModeHelper class had a setShutterGainLimits() function, which got renamed to setLimits(). The documentation still uses the old name. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-09-23libcamera: libipa: camera_sensor: Add Sony IMX214 sensor propertiesAndré Apitzsch
Provide the Sony IMX214 camera sensor properties and registration with libipa for the gain code helpers. Signed-off-by: André Apitzsch <git@apitzsch.eu> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-09-23ipa: libipa: Add lsc polynomial classStefan Klug
Add a basic class to represent polynomials as specified in the DNG spec for vignetting correction. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>