MomentObject¶
- class MomentObject(*args, **kwargs)¶
Bases:
pybind11_object
Class for generic objects.
It contains all basic moments often described by \(m_{ij}\) of order \(i+j\) going from \(m_{00}\) to the order used as parameter in vpMomentObject() constructor. All other moments implemented in ViSP (gravity center, alpha orientation, centered moments…) use this moment object as a combination of its different values.
When constructing a vpMomentObject() you need first to specify the maximum used moment order as parameter.
Then there are three ways to initialize a vpMomentObject . Firstly using fromImage() you can considerer a dense object O defined by an image. Secondly, as described in fromVector() you can also define a dense object O by a closed contour. In these two cases, 2D basic moments are defined by:
\[m_{ij} = \int \int_{O} x^i y^j dx dy\]Lastly, as presented in fromVector() you can consider a discrete set of n points. In that last case, the basic moments are defined by
\[m_{ij} = \sum_{k=1}^{n} x_k^i y_k^j \]With setType() method you can specify the object type.
The implementation is based on the following references [41] , [5] , [42] , [2] .
Warning
Be careful with the object order. When you specify a maximum order in the vpMomentObject::vpMomentObject constructor (see its detailed description), it will compute all moment orders up to the order you specified. If you want to access the values \(m_{ij}\) with the vpMomentObject::get method, you can do object.get()[j*(order+1)+i].
A few tips about which orders to use in different situations:
moment based visual servoing: use vpMomentObject(6) . This will compute moment values up to order 6 which will enable vpFeatureMoments up to order 5 which is the maximum order required for common moments.
computing gravity center: use vpMomentObject(1) . You only need \(m_{00},m_{01},m_{10}\) . You should compute moments up to order 1.
computing gravity center interaction matrix with vpFeatureMomentGravityCenter : use vpMomentObject(2) . This will compute moment values till order 2 since they are needed for the interaction matrix of vpFeatureMoments of order 1.
The following example shows how to create a moment object from 4 discrete points locate on a plane one meter in front of the camera. It shows also how to get the basic moments that are computed and how to compute other classical moments such as the gravity center or the centered moments.
#include <visp3/core/vpMomentCommon.h> #include <visp3/core/vpMomentObject.h> #include <visp3/core/vpPoint.h> #ifdef ENABLE_VISP_NAMESPACE using namespace VISP_NAMESPACE_NAME; #endif int main() { // Define an object as 4 clockwise points on a plane (Z=0) std::vector<vpPoint> vec_p; // vector that contains the 4 points vec_p.push_back( vpPoint(-0.2, 0.1, 0.0) ); // values in meters vec_p.push_back( vpPoint(+0.3, 0.1, 0.0) ); // values in meters vec_p.push_back( vpPoint(+0.2,-0.1, 0.0) ); // values in meters vec_p.push_back( vpPoint(-0.2,-0.15, 0.0) ); // values in meters // These points are observed by a camera vpHomogeneousMatrix cMo(0, 0, 1, 0, 0, 0); // We set the camera to be 1m far the object // ... update cMo from an image processing // Apply the perspective projection to update the points coordinates in the camera plane for (unsigned int i=0; i<vec_p.size(); ++i) vec_p[i].project(cMo); std::cout << "Considered points: " << std::endl; for(unsigned int i=0; i<vec_p.size(); ++i) std::cout << "point " << i << ": " << vec_p[i].get_x() << ", " << vec_p[i].get_y() << std::endl; // Define an image moment object from the previous points vpMomentObject obj(5); // use moments up to order 5 obj.setType(vpMomentObject::DISCRETE); // initialize the object as constituted by discrete points obj.fromVector(vec_p); // init the object from the points // --- Access the computed moments by querying the moment object // 1. Getting a vector of doubles std::vector<double> moment = obj.get(); std::cout << std::endl << "Basic moment available (from vector of doubles)" << std::endl; for(unsigned int k=0; k<=obj.getOrder(); k++) { for(unsigned int l=0; l<(obj.getOrder()+1)-k; l++) { std::cout << "m" << l << k << "=" << moment[k*(momobj.getOrder()+1)+ l] << "\t"; } std::cout<<std::endl; } // 2. Print the contents of moment object directly std::cout << std::endl << "Basic moment available: "; std::cout << obj << std::endl; // 3. Directly indexing the moment object std::cout << std::endl << "Direct access to some basic moments: " << std::endl; std::cout << "m00: " << obj.get(0, 0) << std::endl; std::cout << "m10: " << obj.get(1, 0) << std::endl; std::cout << "m01: " << obj.get(0, 1) << std::endl; std::cout << "m22: " << obj.get(2, 2) << std::endl; std::cout << "m20: " << obj.get(2, 0) << std::endl; std::cout << "m02: " << obj.get(0, 2) << std::endl; // Get common moments computed using basic moments double m00 = vpMomentCommon::getSurface(obj); // surface = m00 double alpha = vpMomentCommon::getAlpha(obj); // orientation std::vector<double> mu_3 = vpMomentCommon::getMu3(obj); // centered moment up to 3rd order std::cout << std::endl << "Common moments computed using basic moments:" << std::endl; std::cout << "Surface: " << m00 << std::endl; std::cout << "Alpha: " << alpha << std::endl; std::cout << "Centered moments (mu03, mu12, mu21, mu30): "; for(unsigned int i=0; i<mu_3.size(); ++i) std::cout << mu_3[i] << " "; std::cout << std::endl; return 0; }
This example produces the following results:
Considered points: point 0: -0.2, 0.1 point 1: 0.3, 0.1 point 2: 0.2, -0.1 point 3: -0.2, -0.15 Basic moment available (from vector of doubles): m00=4 m10=0.1 m20=0.21 m30=0.019 m40=0.0129 m50=0.00211 m01=-0.05 m11=0.02 m21=0.003 m31=0.0023 m41=0.00057 m02=0.0525 m12=-0.0015 m22=0.0026 m32=9e-05 m03=-0.002375 m13=0.000575 m23=-4.5e-05 m04=0.00080625 m14=-7.125e-05 m05=-6.59375e-05 Basic moment available: 4 0.1 0.21 0.019 0.0129 0.00211 -0.05 0.02 0.003 0.0023 0.00057 x 0.0525 -0.0015 0.0026 9e-05 x x -0.002375 0.000575 -4.5e-05 x x x 0.00080625 -7.125e-05 x x x x -6.59375e-05 x x x x x Direct access to some basic moments: m00: 4 m10: 0.1 m01: -0.05 m22: 0.0026 m20: 0.21 m02: 0.0525 Common moments computed using basic moments: Surface: 0.259375 Alpha: 0.133296 Centered moments (mu03, mu12, mu21, mu30): 0.003375 0.0045625 -0.00228125 -0.000421875
Note that in the continuous case, the moment object \(m_{00}\) corresponds to the surface \(a\) of the object. In the discrete case, it is the number of discrete points \(n\) .
Overloaded function.
__init__(self: visp._visp.core.MomentObject, order: int) -> None
__init__(self: visp._visp.core.MomentObject, srcobj: visp._visp.core.MomentObject) -> None
Copy constructor
Methods
Overloaded function.
Converts the raw moments contained in vpMomentObject to a vpMatrix This function returns a vpMatrix of size (order+1, order+1).
Overloaded function.
<unparsed orderedlist <doxmlparser.compound.docListType object at 0x7f4224fa6770>>
Overloaded function.
- return:
The maximal order. The basic moments \(m_{ij}\) that will be computed are for \(i+j \in [0:\mbox{order}]\) .
- return:
The type of object that is considered.
Overloaded function.
Outputs raw moments in indexed form like m[1,1] = value of moment m11Outputs the raw moment values \(m_{ij}\) in indexed form.
Specifies the type of the input data.
Inherited Methods
Operators
__doc__
Overloaded function.
__module__
__repr__
Attributes
BLACK
DENSE_FULL_OBJECT
DENSE_POLYGON
DISCRETE
WHITE
__annotations__
flg_normalize_intensity
- class CameraImgBckGrndType(self, value: int)¶
Bases:
pybind11_object
Type of camera image background.
Values:
BLACK: Black background.
WHITE: Not functional right now.
- class ObjectType(self, value: int)¶
Bases:
pybind11_object
Type of camera image background.
Values:
BLACK: Black background.
WHITE: Not functional right now.
- __init__(*args, **kwargs)¶
Overloaded function.
__init__(self: visp._visp.core.MomentObject, order: int) -> None
__init__(self: visp._visp.core.MomentObject, srcobj: visp._visp.core.MomentObject) -> None
Copy constructor
- static convertTovpMatrix(momobj: visp._visp.core.MomentObject) visp._visp.core.Matrix ¶
Converts the raw moments contained in vpMomentObject to a vpMatrix This function returns a vpMatrix of size (order+1, order+1).
vpMomentObject obj(8); obj.setType(vpMomentObject::DENSE_FULL_OBJECT); obj.fromImageWeighted(I, cam, vpMomentObject::BLACK); // cam should have the camera parameters vpMatrix Mpq = vpMomentObject::convertTovpMatrix(obj);
Instead of accessing the moment m21 as obj.get(2,1), you can now do Mpq[2][1]. This is useful when you want to use the functions available in vpMatrix . One use case i see now is to copy the contents of the matrix to a file or std::cout. For instance, like
// Print to console Mpq.maplePrint(std::cout); // Or write to a file std::ofstream fileMpq("Mpq.csv"); Mpq.maplePrint(fileMpq);
The output can be copied and pasted to MAPLE as a matrix.
Warning
The moments that are not calculated have zeros. For instance, for a vpMomentObject of order 8, the moment m[7,2] is not calculated. It will have 0 by default. User discretion is advised.
- Parameters:
- momobj: visp._visp.core.MomentObject¶
A vpMomentObject
- fromImage(*args, **kwargs)¶
Overloaded function.
fromImage(self: visp._visp.core.MomentObject, image: visp._visp.core.ImageGray, threshold: int, cam: visp._visp.core.CameraParameters) -> None
Computes basic moments from an image based on this reference [2] .
There is no assumption made about whether the input is dense or discrete but it’s more common to use vpMomentObject::DENSE_FULL_OBJECT with this method.
The code below shows how to use this function.
#include <visp3/core/vpImage.h> #include <visp3/core/vpMomentObject.h> #ifdef ENABLE_VISP_NAMESPACE using namespace VISP_NAMESPACE_NAME; #endif int main() { vpCameraParameters cam; // Camera parameters used for pixel to meter conversion vpImage<unsigned char> I(288, 384); // Image used to define the object // ... Initialize the image unsigned char threshold = 128; // Gray level used to define which part of the image belong to the dense object vpMomentObject obj(3); // Create an image moment object with 3 as maximum order obj.fromImage(I, threshold, cam); // Initialize the object from the image return 0; }
- Parameters:
- image
Image to consider.
- threshold
Pixels with a luminance lower than this threshold will be considered.
- cam
Camera parameters used to convert pixels coordinates in meters in the image plane.
fromImage(self: visp._visp.core.MomentObject, image: visp._visp.core.ImageGray, cam: visp._visp.core.CameraParameters, bg_type: visp._visp.core.MomentObject.CameraImgBckGrndType, normalize_with_pix_size: bool = true) -> None
Computes basic moments from an image based on this reference [2] .
Intended to be used by vpMomentObject with DENSE_FULL_OBJECT object type, see setType() .
- Parameters:
- image
Grayscale image
- cam
Camera parameters (to change to )
- bg_type
White/Black background surrounding the image
- normalize_with_pix_size
When this flag if set, the moments, after calculation are normalized w.r.t pixel size available from camera parameters.
- fromVector(self, points: list[visp._visp.core.Point]) list[visp._visp.core.Point] ¶
<unparsed orderedlist <doxmlparser.compound.docListType object at 0x7f4224fa6770>>
The code below shows how to use this function to consider a dense object defined by a closed contour.
#include <visp3/core/vpMomentObject.h> #include <visp3/core/vpPoint.h> #ifdef ENABLE_VISP_NAMESPACE using namespace VISP_NAMESPACE_NAME; #endif int main() { // Define the contour of an object by a 5 clockwise vertices on a plane vpPoint p; std::vector<vpPoint> vec_p; // vector that contains the vertices of the contour polygon p.set_x(-0.2); p.set_y(0.1); // coordinates in meters in the image plane (vertex 1) vec_p.push_back(p); p.set_x(+0.3); p.set_y(0.1); // coordinates in meters in the image plane (vertex 2) vec_p.push_back(p); p.set_x(+0.2); p.set_y(-0.1); // coordinates in meters in the image plane (vertex 3) vec_p.push_back(p); p.set_x(-0.2); p.set_y(-0.15); // coordinates in meters in the image plane (vertex 4) vec_p.push_back(p); p.set_x(-0.2); p.set_y(0.1); // close the contour (vertex 5 = vertex 1) vec_p.push_back(p); vpMomentObject obj(4); // Create an image moment object with 4 as maximum order obj.setType(vpMomentObject::DENSE_POLYGON); // The object is defined by a countour polygon obj.fromVector(vec_p); // Init the dense object with the polygon return 0; }
This other example shows how to consider an object as a discrete set of four points.
#include <visp3/core/vpMomentObject.h> #include <visp3/core/vpPoint.h> #ifdef ENABLE_VISP_NAMESPACE using namespace VISP_NAMESPACE_NAME; #endif int main() { // Define 4 discrete points on a plane vpPoint p; std::vector<vpPoint> vec_p; // vector that contains the 4 points p.set_x(-0.2); p.set_y(0.1); // coordinates in meters in the image plane (point 1) vec_p.push_back(p); p.set_x(+0.3); p.set_y(0.1); // coordinates in meters in the image plane (point 2) vec_p.push_back(p); p.set_x(+0.2); p.set_y(-0.1); // coordinates in meters in the image plane (point 3) vec_p.push_back(p); p.set_x(-0.2); p.set_y(-0.15); // coordinates in meters in the image plane (point 4) vec_p.push_back(p); vpMomentObject obj(4); // Create an image moment object with 4 as maximum order obj.setType(vpMomentObject::DISCRETE); // The object is constituted by discrete points obj.fromVector(vec_p); // Init the dense object with the points return 0; }
- Parameters:
- points: list[visp._visp.core.Point]¶
Vector of points.
- Returns:
A tuple containing:
points: Vector of points.
- get(*args, **kwargs)¶
Overloaded function.
get(self: visp._visp.core.MomentObject) -> list[float]
Returns all basic moment values \(m_{ij}\) with \(i \in [0:\mbox{order}]\) and \(j \in [0:\mbox{order}]\) .
For example, if the maximal order is 3, the following values are provided:
m00 m10 m20 m01 m11 m21 m02 m12 m12 m30 m03
To access for example to the basic moment m12, you should use this kind of code:
vpMomentObject obj(3); // ... initialise the object using fromVector() or fromImage() std::vector mij = obj.get(); double m12; m12 = mij[2*(obj.getOrder()+1)+1]; // i=1 and j=2
- Returns:
Vector of moment values. To access \(m_{ij}\) , you have to read vpMomentObject::get() [j*(order+1)+i].
get(self: visp._visp.core.MomentObject, i: int, j: int) -> float
Returns the basic moment value \(m_{ij}\) corresponding to i,j indexes
- Parameters:
- i
First moment index, with \(i+j \leq order\) .
- j
Second moment index, with \(i+j \leq order\) .
- getOrder(self) int ¶
- Returns:
The maximal order. The basic moments \(m_{ij}\) that will be computed are for \(i+j \in [0:\mbox{order}]\) .
- getType(self) visp._visp.core.MomentObject.ObjectType ¶
- Returns:
The type of object that is considered.
- init(*args, **kwargs)¶
Overloaded function.
init(self: visp._visp.core.MomentObject, orderinp: int) -> None
Does exactly the work of the default constructor as it existed in the very first version of vpMomentObject .
init(self: visp._visp.core.MomentObject, objin: visp._visp.core.MomentObject) -> None
Helper to copy constructor.
- static printWithIndices(momobj: visp._visp.core.MomentObject, os: std::ostream) None ¶
Outputs raw moments in indexed form like m[1,1] = value of moment m11Outputs the raw moment values \(m_{ij}\) in indexed form. The moment values are same as provided by the operator << which outputs x for uncalculated moments.
- Parameters:
- momobj
A vpMomentObject
- os
Output stream.
- setType(self, input_type: visp._visp.core.MomentObject.ObjectType) None ¶
Specifies the type of the input data.
- Parameters:
- input_type: visp._visp.core.MomentObject.ObjectType¶
An input type.