[libcamera-devel] [PATCH v2 4/6] src: ipa: raspberrypi: Compute inverse of piecewise linear function

David Plowman david.plowman at raspberrypi.com
Tue Dec 8 13:05:25 CET 2020


Hi Laurent

Thanks for the review.

On Tue, 8 Dec 2020 at 11:46, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi David,
>
> Thank you for the patch.
>
> On Mon, Dec 07, 2020 at 06:01:19PM +0000, David Plowman wrote:
> > Add a method to the piecewise linear function (Pwl) class to compute
> > the inverse of a given Pwl. If the input function is non-monotonic we
> > can only produce a best effort "pseudo" inverse, and we signal this to
> > the caller.
> >
> > Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
> > ---
> >  src/ipa/raspberrypi/controller/pwl.cpp | 27 ++++++++++++++++++++++++++
> >  src/ipa/raspberrypi/controller/pwl.hpp |  3 +++
> >  2 files changed, 30 insertions(+)
> >
> > diff --git a/src/ipa/raspberrypi/controller/pwl.cpp b/src/ipa/raspberrypi/controller/pwl.cpp
> > index aa134a1f..70206418 100644
> > --- a/src/ipa/raspberrypi/controller/pwl.cpp
> > +++ b/src/ipa/raspberrypi/controller/pwl.cpp
> > @@ -114,6 +114,33 @@ Pwl::PerpType Pwl::Invert(Point const &xy, Point &perp, int &span,
> >       return PerpType::None;
> >  }
> >
> > +Pwl Pwl::Inverse(bool *true_inverse, const double eps) const
> > +{
> > +     bool appended = false, prepended = false, neither = false;
> > +     Pwl inverse;
> > +
> > +     for (Point const &p : points_) {
> > +             if (inverse.Empty())
> > +                     inverse.Append(p.y, p.x, eps);
> > +             else if (p.y > inverse.points_.back().x - eps) {
>
> Shouldn't this be + eps (and - eps below), based on Pwl::Append() and
> Pwm::Prepend() ?

Yes, as always these numerical things are a bit icky. So if I had

else if (p.y > inverse.points_.back().x + eps) {

then a point that is eps/2 beyond back().x would end up triggering the
"neither" case, which seems harsh. I guess there's a possibility the
input function was constructed with a smaller value for eps. On
balance I felt that "within eps of the end" was probably good enough
to accept the point, and either create a new segment, or drop it
without complaint.

Though on reflection I can see an argument for explicitly checking the
"within eps of the start/end" case and then deliberately doing nothing
(not setting appended/prepended), so I might add that.

Thanks
David

>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>
> > +                     inverse.Append(p.y, p.x, eps);
> > +                     appended = true;
> > +             } else if (p.y < inverse.points_.front().x + eps) {
> > +                     inverse.Prepend(p.y, p.x, eps);
> > +                     prepended = true;
> > +             } else
> > +                     neither = true;
> > +     }
> > +
> > +     // This is not a proper inverse if we found ourselves putting points
> > +     // onto both ends of the inverse, or if there were points that couldn't
> > +     // go on either.
> > +     if (true_inverse)
> > +             *true_inverse = !(neither || (appended && prepended));
> > +
> > +     return inverse;
> > +}
> > +
> >  Pwl Pwl::Compose(Pwl const &other, const double eps) const
> >  {
> >       double this_x = points_[0].x, this_y = points_[0].y;
> > diff --git a/src/ipa/raspberrypi/controller/pwl.hpp b/src/ipa/raspberrypi/controller/pwl.hpp
> > index 4f168551..484672f6 100644
> > --- a/src/ipa/raspberrypi/controller/pwl.hpp
> > +++ b/src/ipa/raspberrypi/controller/pwl.hpp
> > @@ -80,6 +80,9 @@ public:
> >       };
> >       PerpType Invert(Point const &xy, Point &perp, int &span,
> >                       const double eps = 1e-6) const;
> > +     // Compute the inverse function. Indicate if it is a proper (true)
> > +     // inverse, or only a best effort (e.g. input was non-monotonic).
> > +     Pwl Inverse(bool *true_inverse = nullptr, const double eps = 1e-6) const;
> >       // Compose two Pwls together, doing "this" first and "other" after.
> >       Pwl Compose(Pwl const &other, const double eps = 1e-6) const;
> >       // Apply function to (x,y) values at every control point.
>
> --
> Regards,
>
> Laurent Pinchart


More information about the libcamera-devel mailing list