[PATCH] libcamera: geometry: Rename Rectangle's top-left corner
Cheng-Hao Yang
chenghaoyang at google.com
Thu Sep 26 11:28:13 CEST 2024
Hi Jacopo,
On Thu, Sep 26, 2024, 4:38 PM Jacopo Mondi <jacopo.mondi at ideasonboard.com>
wrote:
> Hi Harvey
>
> On Thu, Sep 26, 2024 at 04:29:50PM GMT, Cheng-Hao Yang wrote:
> > Hi Jacopo,
> >
> > On Thu, Sep 26, 2024, 4:03 PM Jacopo Mondi <
> jacopo.mondi at ideasonboard.com>
> > wrote:
> >
> > > Hi Harvey
> > >
> > > On Wed, Sep 25, 2024 at 03:09:38PM GMT, Cheng-Hao Yang wrote:
> > > > Hi Jacopo,
> > > >
> > > > Thank you for the patch.
> > > >
> > > > On Wed, Sep 25, 2024 at 2:36 PM Umang Jain <
> umang.jain at ideasonboard.com>
> > > wrote:
> > > > >
> > > > > Hi Jacopo
> > > > >
> > > > > Thank you for the patch
> > > > >
> > > > > On 24/09/24 6:15 pm, Jacopo Mondi wrote:
> > > > > > The libcamera::Rectangle class should allow defining rectangles
> > > > > > regardless of the reference system where an instance is used in.
> > > > > >
> > > > > > However the class documentation assumes the reference system
> origin
> > > > > > point to be in the visual top-left side and that rectangles are
> > > > > > constructed by specifying the top-left corner position and sizes.
> > > > > >
> > > > > > However this is ambiguous when using a different reference
> system as,
> > > > > > in example, constructing a rectangle (x, y, w, h) in the
> following
> > > > > > scenario, with the origin corner in the top-left position, would
> > > require
> > > > > > a negative decrement along the y-axis.
> > > > > >
> > > > > > ^
> > > > > > |
> > > > > > y| o------------------
> > > > > > | | | h
> > > > > > | | |
> > > > > > | -------------------
> > > > > > | w
> > > > > > ------------------------------->
> > > > > > (0,0) x
> > > > > >
> > > > > > To remove ambiguities, drop references to the visual top-left
> corner
> > > and
> > > > > > define the rectangle's origin corner as the corner closer to the
> > > > > > reference system origin point, and specify the horizontal and
> > > vertical
> > > > > > dimensions always increment along their respective axis, as in
> the
> > > > > > following example.
> > > > > >
> > > > > > ^
> > > > > > |
> > > > > > | -------------------
> > > > > > | ^ | h
> > > > > > | | |
> > > > > > y| o---->-------------
> > > > > > | w
> > > > > > ------------------------------->
> > > > > > (0,0) x
> > > > > >
> > > > > > (0,0) x
> > > > > > ------------------------------>
> > > > > > | w
> > > > > > y| o---->-------------
> > > > > > | | | h
> > > > > > | v |
> > > > > > | -------------------
> > > > > > |
> > > > > > V
> > > > > >
> > > > > > Also rename for consistency the Rectangle::topLeft() function to
> > > > > > Rectangle::origin() and update its in-tree users.
> > > > > >
> > > > > > Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > > > > > ---
> > > > > > include/libcamera/geometry.h | 2 +-
> > > > > > src/ipa/ipu3/algorithms/af.cpp | 2 +-
> > > > > > src/libcamera/geometry.cpp | 85
> > > ++++++++++++++-----
> > > > > > .../pipeline/rpi/common/pipeline_base.cpp | 4 +-
> > > > > > src/py/libcamera/py_geometry.cpp | 2 +-
> > > > > > test/geometry.cpp | 8 +-
> > > > > > 6 files changed, 75 insertions(+), 28 deletions(-)
> > > > > >
> > > > > > diff --git a/include/libcamera/geometry.h
> > > b/include/libcamera/geometry.h
> > > > > > index 3e6f0f5d7fab..07cb0a7866fe 100644
> > > > > > --- a/include/libcamera/geometry.h
> > > > > > +++ b/include/libcamera/geometry.h
> > > > > > @@ -277,7 +277,7 @@ public:
> > > > > > return { width, height };
> > > > > > }
> > > > > >
> > > > > > - Point topLeft() const
> > > > > > + Point origin() const
> > > > > > {
> > > > > > return { x, y };
> > > > > > }
> > > > > > diff --git a/src/ipa/ipu3/algorithms/af.cpp
> > > b/src/ipa/ipu3/algorithms/af.cpp
> > > > > > index cf68fb59c49b..1b707e9dd9ab 100644
> > > > > > --- a/src/ipa/ipu3/algorithms/af.cpp
> > > > > > +++ b/src/ipa/ipu3/algorithms/af.cpp
> > > > > > @@ -155,7 +155,7 @@ int Af::configure(IPAContext &context, const
> > > IPAConfigInfo &configInfo)
> > > > > > * - Return the AF ROI as metadata in the Request
> > > > > > */
> > > > > > Rectangle roi = gridSize.centeredTo(bds.center());
> > > > > > - Point start = roi.topLeft();
> > > > > > + Point start = roi.origin();
> > > > > >
> > > > > > /* x_start and y_start should be even */
> > > > > > grid.x_start = utils::alignDown(start.x, 2);
> > > > > > diff --git a/src/libcamera/geometry.cpp
> b/src/libcamera/geometry.cpp
> > > > > > index 000151364c7f..45ba81a99920 100644
> > > > > > --- a/src/libcamera/geometry.cpp
> > > > > > +++ b/src/libcamera/geometry.cpp
> > > > > > @@ -593,11 +593,39 @@ std::ostream &operator<<(std::ostream &out,
> > > const SizeRange &sr)
> > > > > > * \brief Describe a rectangle's position and dimensions
> > > > > > *
> > > > > > * Rectangles are used to identify an area of an image. They
> are
> > > specified by
> > > > > > - * the coordinates of top-left corner and their horizontal and
> > > vertical size.
> > > > > > + * the coordinates of the corner closer to the reference
> system's
> > > origin point
> > > > > > + * and by horizontal and vertical increments from there.
> > > > > > *
> > > > > > - * The measure unit of the rectangle coordinates and size, as
> well
> > > as the
> > > > > > - * reference point from which the Rectangle::x and Rectangle::y
> > > displacements
> > > > > > - * refers to, are defined by the context were rectangle is used.
> > > > > > + * The corner closer to the reference system's origin point is
> the
> > > rectangle's
> > > > > > + * origin corner.
> > > > > > + *
> > > > > > + * \verbatim
> > > > > > +
> > > > > > + o = origin corner
> > > > > > +
> > > > > > + ^
> > > > > > + |
> > > > > > + | -------------------
> > > > > > + | ^ |
> > > > > > + | | |
> > > > > > + | o---->-------------
> > > > > > + |
> > > > > > + ------------------------------->
> > > > > > + (0,0)
> > > > > > +
> > > > > > + (0,0)
> > > > > > + ------------------------------->
> > > > > > + |
> > > > > > + | o---->-------------
> > > > > > + | | |
> > > > > > + | v |
> > > > > > + | -------------------
> > > > > > + |
> > > > > > + V
> > > > > > + \endverbatim
> > > > > > + *
> > > > > > + * The measure unit of the rectangle coordinates and size are
> > > defined by the
> > > > > > + * context were the rectangle is used.
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > @@ -608,35 +636,50 @@ std::ostream &operator<<(std::ostream &out,
> > > const SizeRange &sr)
> > > > > > /**
> > > > > > * \fn Rectangle::Rectangle(int x, int y, const Size &size)
> > > > > > * \brief Construct a Rectangle with the given position and
> size
> > > > > > - * \param[in] x The horizontal coordinate of the top-left corner
> > > > > > - * \param[in] y The vertical coordinate of the top-left corner
> > > > > > + * \param[in] x The horizontal coordinate of the origin corner
> > > > > > + * \param[in] y The vertical coordinate of the origin corner
> > > > > > * \param[in] size The size
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > >
> > > > I think we should stick to the previous description:
> > > > `"origin" point defined as the point with the lower x and
> > > > lower y of the rectangle`, as `x` and `y` are signed integers.
> > > >
> > > > If we only support coordinates that are positive or 0, which
> > > > I'm not sure if it's the case, how about making the type to be
> > > > `unsigned int`?
> > > >
> > >
> > > To be honest I would rather make width and heigh signed to allow
> > > constructing (x, y, -w, -h)
> > >
> > >
> > >
> > >
> > > -------------------
> > > | ^
> > > | ------------->
> > > | | |
> > > ------<-----|-----o
> > > |
> > > |
> > > V
> > >
> > > Not sure if it's useful or not though
> > >
> >
> > Hmm... I find it pretty weird. What if all four corners have all negative
> > coordinates?
> >
> >
>
> Don't know, maybe if the reference system where the rectangle is used
> into has 4 planes and so an all-negative rectangle makes sense.
>
> My point is that we should allow users of this class to express
> Rectangle in any context they plan to use them. Not sure if I'm going
> overboard here or it makes sense.
>
Yeah I agree, while doesn't that mean the description doesn't fit all
cases, like the corner closer to the reference system origin point of a
rectangle that has all negative coordinates is actually the "bottom-right"
corner, and currently libcamera::Size only allows non-negative width and
height [1].
[1]:
https://git.libcamera.org/libcamera/libcamera.git/tree/include/libcamera/geometry.h#n65
> >
> >
> > >
> > > > BR,
> > > > Harvey
> > > >
> > > >
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > * \fn Rectangle::Rectangle(int x, int y, unsigned int width,
> > > unsigned int height)
> > > > > > * \brief Construct a Rectangle with the given position and
> size
> > > > > > - * \param[in] x The horizontal coordinate of the top-left corner
> > > > > > - * \param[in] y The vertical coordinate of the top-left corner
> > > > > > + * \param[in] x The horizontal coordinate of the origin corner
> > > > > > + * \param[in] y The vertical coordinate of the origin corner
> > > > > > * \param[in] width The width
> > > > > > * \param[in] height The height
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > * \fn Rectangle::Rectangle(const Size &size)
> > > > > > - * \brief Construct a Rectangle of \a size with its top left
> corner
> > > located
> > > > > > + * \brief Construct a Rectangle of \a size with its origin
> corner
> > > located
> > > > > > * at (0,0)
> > > > > > * \param[in] size The desired Rectangle size
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > * \var Rectangle::x
> > > > > > - * \brief The horizontal coordinate of the rectangle's top-left
> > > corner
> > > > > > + * \brief The horizontal coordinate of the rectangle's origin
> corner
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > * \var Rectangle::y
> > > > > > - * \brief The vertical coordinate of the rectangle's top-left
> corner
> > > > > > + * \brief The vertical coordinate of the rectangle's origin
> corner
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > @@ -683,9 +726,13 @@ Point Rectangle::center() const
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > - * \fn Point Rectangle::topLeft() const
> > > > > > - * \brief Retrieve the coordinates of the top left corner of
> this
> > > Rectangle
> > > > > > - * \return The Rectangle's top left corner
> > > > > > + * \fn Point Rectangle::origin() const
> > > > > > + * \brief Retrieve the coordinates of the origin corner of this
> > > Rectangle
> > > > > > + *
> > > > > > + * The rectangle's origin corner is the corner closer to the
> > > reference system
> > > > > > + * origin point (0, 0).
> > > > > > + *
> > > > > > + * \return The Rectangle's origin corner
> > > > >
> > > > > I think you can drop "corner" from "origin corner"
> > > > >
> > > > > Probably throughout the patch:
> > > > > s/origin corner/origin/
> > > > >
> > > > > Otherwise, LGTM
> > > > >
> > > > > Reviewed-by: Umang Jain <umang.jain at ideasonboard.com>
> > > > > > */
> > > > > >
> > > > > > /**
> > > > > > @@ -740,15 +787,15 @@ Rectangle &Rectangle::translateBy(const
> Point
> > > &point)
> > > > > > */
> > > > > > Rectangle Rectangle::boundedTo(const Rectangle &bound) const
> > > > > > {
> > > > > > - int topLeftX = std::max(x, bound.x);
> > > > > > - int topLeftY = std::max(y, bound.y);
> > > > > > + int originX = std::max(x, bound.x);
> > > > > > + int originY = std::max(y, bound.y);
> > > > > > int bottomRightX = std::min<int>(x + width, bound.x +
> > > bound.width);
> > > > > > int bottomRightY = std::min<int>(y + height, bound.y +
> > > bound.height);
> > > > > >
> > > > > > - unsigned int newWidth = std::max(bottomRightX - topLeftX,
> 0);
> > > > > > - unsigned int newHeight = std::max(bottomRightY - topLeftY,
> 0);
> > > > > > + unsigned int newWidth = std::max(bottomRightX - originX,
> 0);
> > > > > > + unsigned int newHeight = std::max(bottomRightY - originY,
> 0);
> > > > > >
> > > > > > - return { topLeftX, topLeftY, newWidth, newHeight };
> > > > > > + return { originX, originY, newWidth, newHeight };
> > > > > > }
> > > > > >
> > > > > > /**
> > > > > > diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
> > > b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
> > > > > > index 3041fd1ed9fd..8d2440026689 100644
> > > > > > --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
> > > > > > +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
> > > > > > @@ -1289,7 +1289,7 @@ Rectangle CameraData::scaleIspCrop(const
> > > Rectangle &ispCrop) const
> > > > > > */
> > > > > > Rectangle nativeCrop =
> > > ispCrop.scaledBy(sensorInfo_.analogCrop.size(),
> > > > > >
> > > sensorInfo_.outputSize);
> > > > > > - nativeCrop.translateBy(sensorInfo_.analogCrop.topLeft());
> > > > > > + nativeCrop.translateBy(sensorInfo_.analogCrop.origin());
> > > > > > return nativeCrop;
> > > > > > }
> > > > > >
> > > > > > @@ -1303,7 +1303,7 @@ void CameraData::applyScalerCrop(const
> > > ControlList &controls)
> > > > > > nativeCrop = { 0, 0, 1, 1 };
> > > > > >
> > > > > > /* Create a version of the crop scaled to ISP
> (camera
> > > mode) pixels. */
> > > > > > - Rectangle ispCrop =
> > > nativeCrop.translatedBy(-sensorInfo_.analogCrop.topLeft());
> > > > > > + Rectangle ispCrop =
> > > nativeCrop.translatedBy(-sensorInfo_.analogCrop.origin());
> > > > > > ispCrop.scaleBy(sensorInfo_.outputSize,
> > > sensorInfo_.analogCrop.size());
> > > > > >
> > > > > > /*
> > > > > > diff --git a/src/py/libcamera/py_geometry.cpp
> > > b/src/py/libcamera/py_geometry.cpp
> > > > > > index c7e303609427..8dee365b25dd 100644
> > > > > > --- a/src/py/libcamera/py_geometry.cpp
> > > > > > +++ b/src/py/libcamera/py_geometry.cpp
> > > > > > @@ -105,7 +105,7 @@ void init_py_geometry(py::module &m)
> > > > > > .def_property_readonly("is_null",
> &Rectangle::isNull)
> > > > > > .def_property_readonly("center",
> &Rectangle::center)
> > > > > > .def_property_readonly("size", &Rectangle::size)
> > > > > > - .def_property_readonly("topLeft",
> &Rectangle::topLeft)
> > > > > > + .def_property_readonly("origin",
> &Rectangle::origin)
> > > > > > .def("scale_by", &Rectangle::scaleBy)
> > > > > > .def("translate_by", &Rectangle::translateBy)
> > > > > > .def("bounded_to", &Rectangle::boundedTo)
> > > > > > diff --git a/test/geometry.cpp b/test/geometry.cpp
> > > > > > index 64169206ad16..a4ee6f6e167a 100644
> > > > > > --- a/test/geometry.cpp
> > > > > > +++ b/test/geometry.cpp
> > > > > > @@ -363,16 +363,16 @@ protected:
> > > > > > return TestFail;
> > > > > > }
> > > > > >
> > > > > > - /* Rectangle::size(), Rectangle::topLeft() and
> > > Rectangle::center() tests */
> > > > > > + /* Rectangle::size(), Rectangle::origin() and
> > > Rectangle::center() tests */
> > > > > > if (Rectangle(-1, -2, 3, 4).size() != Size(3, 4) ||
> > > > > > Rectangle(0, 0, 100000, 200000).size() !=
> > > Size(100000, 200000)) {
> > > > > > cout << "Rectangle::size() test failed" <<
> > > endl;
> > > > > > return TestFail;
> > > > > > }
> > > > > >
> > > > > > - if (Rectangle(1, 2, 3, 4).topLeft() != Point(1, 2)
> ||
> > > > > > - Rectangle(-1, -2, 3, 4).topLeft() != Point(-1,
> > > -2)) {
> > > > > > - cout << "Rectangle::topLeft() test failed"
> <<
> > > endl;
> > > > > > + if (Rectangle(1, 2, 3, 4).origin() != Point(1, 2)
> ||
> > > > > > + Rectangle(-1, -2, 3, 4).origin() != Point(-1,
> -2))
> > > {
> > > > > > + cout << "Rectangle::origin() test failed"
> <<
> > > endl;
> > > > > > return TestFail;
> > > > > > }
> > > > > >
> > > > > > --
> > > > > > 2.46.1
> > > > > >
> > > > >
> > > >
> > > >
> > > > --
> > > > BR,
> > > > Harvey Yang
> > >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20240926/1a5aa85b/attachment.htm>
More information about the libcamera-devel
mailing list