<a id="easygauge"></a>

# EasyGauge - Measuring down to Sub-Pixel

<a id="easygauge-purpose"></a>

## Purpose

#### NOTE
This section is about the new **EasyGauge** API. The previous version of the API is described in the [Legacy EasyGauge](legacy_easygauge/index.html.md).

**EasyGauge** can measure and fit various geometrical shapes (rectangles, circles, polygons, wedges, lines and points) to edges in the images.

To find and measure a geometrical shape:

1. Create a gauge object that corresponds to the required geometrical shape.
2. Set the *nominal* shape on the object.
   - The *nominal* shape is an approximate definition of the shape to be measured.
   - Use [`EBaseGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#acdce2d3723431e85a43ef8a6540de2d8) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a863ce360bffcb103addc2f9bf39ae440) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a6a82b24a0dab559db837f5aafdb8e0b4) or the overloads in each gauge class ([`ERectangleGauge::SetRectangle`](../../../doxygen_cpp/classeVision_1_1ERectangleGauge.html#aeb8640af987367138ac9cfee35804bb7) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangleGauge.html#af9c9a5c9bbfa1afde43b249571dfd468) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGauge.html#a8dfe76b1909f94d248169e16c0bc3272) for example).
3. Set the tolerances of the shape.
   - The tolerances express how far away from the *nominal* shape to search for edge-crossing in the image.
4. Optionally change the various measurement and fitting parameters.
5. Call [`EBaseGauge::Measure`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a09dbcb0c1bb7681ba31870c626fd0231) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a3fa25d60234bce338c219c93e591626f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#addcbfdee6ba540ab56d43c653a06e8e2) to perform the measurement and get the measured shape.
   - It throws an exception if the shape cannot be found.

The nominal shape, tolerance, various measurement parameters and the measured shape can be expressed with respect to a reference frame ([`EFrame`](../../../doxygen_cpp/classeVision_1_1EFrame.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFrame.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFrame.html)) given as a parameter to [`EBaseGauge::Measure`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a09dbcb0c1bb7681ba31870c626fd0231) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a3fa25d60234bce338c219c93e591626f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#addcbfdee6ba540ab56d43c653a06e8e2).

To perform calibrated or metric gauging, use a calibrated reference frame.

#### NOTE
The theoretical best-case accuracy is 1/64<sub>th</sub> pixel for all **EasyGauge** operators. In practice, you can assume an accuracy of 1/10<sub>th</sub> pixel.

#### SEE ALSO
See [Geometrical Shapes](../../basic_operations/common_data_types/geometrical_shapes.html.md), [Frame and Alignment](../../basic_operations/frame_and_alignment.html.md), and [Calibration](../../advanced_operations/camera_calibration/index.html.md).

<a id="easygauge-gauge-types"></a>

## Gauge Types

<a id="easygauge-point-gauge"></a>

### Point Gauge

* **Description**: the point gauge finds points along a line probe segment that crosses the edges as specified by the measurement parameters.
* **Nominal shape**: a [line segment](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-line) ([`ELine`](../../../doxygen_cpp/classeVision_1_1ELine.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELine.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELine.html)).
  - Use [`EPointGauge::GetNominalLine`](../../../doxygen_cpp/classeVision_1_1EPointGauge.html#ae4dac3fb94c80969028334b88903e525) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointGauge.html#ab191d30d583c0e48ce1f4c702a9b2625) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointGauge.html#ae9bc87502a9863800719962d38eb85d6) to set the nominal line .
* **Measured shape**: a [point set](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-point-set) ([`EPointSet`](../../../doxygen_cpp/classeVision_1_1EPointSet.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointSet.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointSet.html)).
  - Use [`EPointGauge::GetMeasuredPointSet`](../../../doxygen_cpp/classeVision_1_1EPointGauge.html#af03dfcf709bb4867afd4073e087b684d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointGauge.html#abb7fee8d40777f4c8fe1d99fa0e5a7dc) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointGauge.html#a56957235c7daa2cbf6b2bf5ebc695e22) to get the measured set of points.
  - Use [`EPointSet::GetPoint`](../../../doxygen_cpp/classeVision_1_1EPointSet.html#a000743cfa924ec10cd93340131f6f61f) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointSet.html#a34150559f1f0394ee9918869123c85fa) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointSet.html#ab660819cd6c4d79e65c992383f3d345b) to get a measured point.
  - Use [`EPointSet::GetPoints`](../../../doxygen_cpp/classeVision_1_1EPointSet.html#a76f3e63f84b6054f44147907a89be406) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointSet.html#ab8dfddc6988bad27e7a3190f8a89f73c) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointSet.html#a82c414924261d4dae22df9a4877d4358) to get all the points.

![](assets/images/easygauge/pointgaugeboth.jpg)![](assets/images/easygauge/pointgaugeblacktowhite.jpg)

<a id="easygauge-line-gauge"></a>

### Line Gauge

* **Description**: the line gauge finds a line segment that follows an edge as specified by the measurement parameters.
* **Nominal shape**: a [line segment](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-line) ([`ELine`](../../../doxygen_cpp/classeVision_1_1ELine.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELine.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELine.html)).
  - Use [`ELineGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1ELineGauge.html#a7f3c2350fed384b601876559193a6099) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELineGauge.html#adc17b8584cd72b336a957f322e8752bb) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELineGauge.html#a654b173866c20386e26cc6fbbfd25b5e) to set the nominal line.
* **Measured shape**: a [line segment](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-line) ([`ELine`](../../../doxygen_cpp/classeVision_1_1ELine.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELine.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELine.html))
  - Use [`ELineGauge::GetMeasuredLine`](../../../doxygen_cpp/classeVision_1_1ELineGauge.html#a298e51da13e4d0a4ece74a2c87ce29d0) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELineGauge.html#a9a2958d6a7483fee8b4c9bfb9c1ba4d9) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELineGauge.html#a48e359efd876f0e36ee5b91a49e8ee94) to get the measured line.
* **Specific parameters**:
  - Set [`ELineGauge::GetKnownAngle`](../../../doxygen_cpp/classeVision_1_1ELineGauge.html#a057dd2f01eae02273533d26053690365) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELineGauge.html#ad00b02b456ac8d1c0a8496d9c802897c) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELineGauge.html#a1b9e8f75c763bbd394f4d913fb77a705) to `true` to fix the slope of the line.

![image](assets/images/easygauge/linegauge.jpg)

<a id="easygauge-rectangle-gauge"></a>

### Rectangle Gauge

* **Description**: the rectangle gauge finds a rectangle that fits edges of the image as specified by the measurement parameters.
* **Nominal shape**: a [rectangle](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-rectangle) ([`ERectangle`](../../../doxygen_cpp/classeVision_1_1ERectangle.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangle.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangle.html)).
  - Use [`ERectangleGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1ERectangleGauge.html#a8ee480b479bd40cce8bfb56d68d86d69) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangleGauge.html#ad01474590feb345c8c71f5f1e7ea2240) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGauge.html#a4af2f817ac753bab53f764d70932ff78) to set the nominal rectangle .
* **Measured shape**: a [rectangle](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-rectangle) ([`ERectangle`](../../../doxygen_cpp/classeVision_1_1ERectangle.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangle.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangle.html)).
  - Use [`ERectangleGauge::GetMeasuredRectangle`](../../../doxygen_cpp/classeVision_1_1ERectangleGauge.html#a20a207bc763326bd783f519fc9a6c1e0) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangleGauge.html#a240d4b376c8e2d87f388e194178dfd10) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGauge.html#a550bedc18966e143a55336fa428f4750) to get the measured rectangle.
* **Specific parameters**:
  - Use [`ERectangleGauge::GetActiveEdges`](../../../doxygen_cpp/classeVision_1_1ERectangleGauge.html#a449b6cfcac696aba3508b86097730300) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangleGauge.html#a75e14123d789aca30402144dd35838d9) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGauge.html#a570d710523ceabaaf8858d6240aa6c33) to set the edge to fit to the image.

    The active edges of the rectangles are a combination of the value of the enumerate [`ERectangleGaugeEdge`](../../../doxygen_cpp/namespaceeVision.html#a0080a0d04abf0368780e74f9d3096f5c) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#aac97e640018470e38a941c8eb7e9f105) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGaugeEdge.html) (`Left`, `Right`, `Bottom`, `Top`).
  - Set [`ERectangleGauge::GetKnownAngle`](../../../doxygen_cpp/classeVision_1_1ERectangleGauge.html#ad411a88799b237e5189995b077682e7e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ERectangleGauge.html#ae10e2e6dcbfac1be8d01280ffd2206c7) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ERectangleGauge.html#a49d71221bce8c2fbc88f62371fd6fe79) to `true` to fix the orientation of the rectangle.

![image](assets/images/easygauge/rectanglegauge.jpg)

<a id="easygauge-circle-gauge"></a>

### Circle Gauge

* **Description**: the circle gauge finds a circle that fits edges of the image as specified by the measurement parameters.
* **Nominal shape**: a [circle](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-circle) ([`ECircle`](../../../doxygen_cpp/classeVision_1_1ECircle.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ECircle.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ECircle.html))
  - Use [`ECircleGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1ECircleGauge.html#a9ca6cbf50035124f632b2b4fa2fa335c) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ECircleGauge.html#a4219dcf0a9343edabb667892f6f5329e) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ECircleGauge.html#a9714fb66ac94f5f907f9120f2a2848bd) to set the nominal line.
* **Measured shape**: a [circle](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-circle) ([`ECircle`](../../../doxygen_cpp/classeVision_1_1ECircle.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ECircle.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ECircle.html))
  - Use [`ECircleGauge::GetMeasuredCircle`](../../../doxygen_cpp/classeVision_1_1ECircleGauge.html#ae3d08dc1c2af872681c7d78c4c02d435) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ECircleGauge.html#ad9b238740b3909c351300627d4591083) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ECircleGauge.html#a9b1089299d90447d25f37e4ec1836d10) to get the measured circle.

![image](assets/images/easygauge/circlegauge.jpg)

<a id="easygauge-wedge-gauge"></a>

### Wedge Gauge

* **Description**: the wedge gauge finds a wedge that fits edges of the image as specified by the measurement parameters.
* **Nominal shape**: a [wedge](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-wedge) ([`EWedge`](../../../doxygen_cpp/classeVision_1_1EWedge.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedge.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedge.html))
  - Use [`EWedgeGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1EWedgeGauge.html#a193420aeefc6f891c48a986ea8bafb45) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedgeGauge.html#a8f153cbdadc671b91639038622a2cba0) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedgeGauge.html#a9ba56e963e453970503b684a736f199b) to set the nominal wedge.
* **Measured shape**: a [wedge](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-wedge) ([`EWedge`](../../../doxygen_cpp/classeVision_1_1EWedge.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedge.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedge.html))
  - Use [`EWedgeGauge::GetMeasuredWedge`](../../../doxygen_cpp/classeVision_1_1EWedgeGauge.html#a111ea5db2f6dcb0ecfdbde63698c2360) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedgeGauge.html#a1e8e2a946d5404be7736baf63cf458b5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedgeGauge.html#ab019313b0a8223a2196428424c518d43) to get the measured wedge.
* **Specific parameters**:
  - Use [`EWedgeGauge::GetActiveEdges`](../../../doxygen_cpp/classeVision_1_1EWedgeGauge.html#a243798098043bbe3c3f0ca32cb126b6b) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedgeGauge.html#a8eae80893da216705f665ea6f0740463) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedgeGauge.html#a9d2043907a4855b57f2df7514c214cb3) to set the edge to fit to the image.

    The active edges of the wedge are a combination of the value of the enumerate [`EWedgeGaugeEdge`](../../../doxygen_cpp/namespaceeVision.html#a268745f1ac93d315e3dbaac306706663) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#af518e7ceb3fff8c1fc2233f1df8df054) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedgeGaugeEdge.html):
    - `EWedgeGaugeEdge_Inner`: inner circle edge.
    - `EWedgeGaugeEdge_Outer`: outer circle edge.
    - `EWedgeGaugeEdge_Origin`: segment linking the inner and outer edge at the [`EWedge::GetAngle`](../../../doxygen_cpp/classeVision_1_1EWedge.html#a5a49118eb8bc28284c52a598cb7ee2bf) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedge.html#a41e84f71e9ff2608febf2c69a2850519) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedge.html#ac32ca3b7075a2f2049e06b226b1c2e2b).
    - `EWedgeGaugeEdge_End`: segment linking the inner and outer edge at [`EWedge::GetAngle`](../../../doxygen_cpp/classeVision_1_1EWedge.html#a5a49118eb8bc28284c52a598cb7ee2bf) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedge.html#a41e84f71e9ff2608febf2c69a2850519) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedge.html#ac32ca3b7075a2f2049e06b226b1c2e2b) and [`EWedge::GetAmplitude`](../../../doxygen_cpp/classeVision_1_1EWedge.html#af2e4f3cdb72b535f4ba5cba65c63eb43) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWedge.html#afa6c35604fcb269ca0c8ecea69d60cca) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWedge.html#a44c6fc231afc3364009cebd722db7f23).

![image](assets/images/easygauge/wedgegauge.jpg)

<a id="easygauge-polygon-gauge"></a>

### Polygon Gauge

![](assets/images/easygauge/polygon_shape_1.webp)![](assets/images/easygauge/polygon_shape_2.webp)
* **Description**: the polygon gauge finds a polygon that fits edges of the image as specified by the measurement parameters.
* **Nominal shape**: a [polygon](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-polygon) ([`EPolygon`](../../../doxygen_cpp/classeVision_1_1EPolygon.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygon.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygon.html))
  - Use [`EPolygonGauge::GetNominal`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#a68a93a327e953d997ec731d8acd59c8a) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#ac9053beb613cf0f2672fbaf4662b2800) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#a7b3e78b2bef669bca287c86ce7eba951) to set the nominal polygon.
* **Measured shape**: a [polygon](../../basic_operations/common_data_types/geometrical_shapes.html.md#geometrical-shape-polygon) ([`EPolygon`](../../../doxygen_cpp/classeVision_1_1EPolygon.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygon.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygon.html))
  - Use [`EPolygonGauge::GetMeasuredPolygon`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#a9bc2c225a6c5abe8cb9d42d7ae76b6e5) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#ab93f17d2199a789e7b1e54640258e590) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#aa5bd446dab8e881a47ad19c805da7285) to get the measured polygon.
  - When using the global measurement mode, the nominal polygon is transformed using an isotropic affine transform:
    - Use [`EPolygonGauge::GetMeasuredPolygonTransformation`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#a1015a8f966df06328fb9bd6ca1ec13ae) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#a50191a0b36709d12a73002b0e99eab1f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#a283307dcfbfcb775ee9e7cab0b33121a) to get the [`EFrame`](../../../doxygen_cpp/classeVision_1_1EFrame.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EFrame.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EFrame.html) object corresponding to this transformation.
    - Scaling is only considered if `EPolygonGauge.EnableScaling` is true.
    - Use [`EPolygonGauge::GetMeasuredOffset`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#a4d8eb377475a78a65526afd9bd411cf7) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#a9a26b1012073b99d569874633d7b9d18) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#a3417af029077197ffa50bf80cf787dd0), [`EPolygonGauge::GetMeasuredScale`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#aa78d8430110526c34ed009f0a35cbf31) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#ac9c4c123271c64f2d68bde8fd1622541) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#aad73a2eb09477055cdec9ddc57b8040b) and [`EPolygonGauge::GetMeasuredAngle`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#af90c2a9d6f454a5919fd8773df48be19) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#ae1daede2bd686bd20b9a9eea47832efd) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#af4c2c695f99de6a5ff65b0b9566a37c8) to directly get the offset, scale and angle of the transformation.
* **Specific parameters**:

  The measurement mode: [`EPolygonGauge::GetMeasurementMode`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#a1d84934ee4364069c9a06bfd5bf60b36) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#a225556a53047bf4759892d3234ed93b8) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#a54110ed13ddfe6186fa754a49f1ff397)
  - In the mode [`EPolygonMeasurementMode_Global`](../../../doxygen_cpp/namespaceeVision.html#a0dbcd45fa15584c368059f6b563c7ae5) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a353b4c9608f9ee2d6ab28e1e0bae0308) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonMeasurementMode.html), the polygon is rigid and the measured polygon is an isotropic affine transformation of the nominal polygon.
    - The position, orientation and optionally the scale of the polygon are adjusted to fit the measured points.
    - By default, the measurement mode is [`EPolygonMeasurementMode_Global`](../../../doxygen_cpp/namespaceeVision.html#a0dbcd45fa15584c368059f6b563c7ae5) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a353b4c9608f9ee2d6ab28e1e0bae0308) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonMeasurementMode.html).
    - If a scaling is required, you must enable it with [`EPolygonGauge::GetEnableScaling`](../../../doxygen_cpp/classeVision_1_1EPolygonGauge.html#afed632012f26368e9ede585585a97e42) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPolygonGauge.html#a5874f9e163870681d0c5692fa4b43592) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonGauge.html#ac6e8d9de3b0cbc0525c1c48675bbd745).

    ![image](assets/images/easygauge/polygon_shape_4.webp)
  - In the mode [`EPolygonMeasurementMode_Edge`](../../../doxygen_cpp/namespaceeVision.html#a0dbcd45fa15584c368059f6b563c7ae5) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a353b4c9608f9ee2d6ab28e1e0bae0308) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonMeasurementMode.html), the edges of the polygon are measured independently.
    - The result is a new polygon composed of each of the nominal edge fitted to the image.
    - The number of edges of the measured polygon is the same as the nominal polygon.

    ![image](assets/images/easygauge/polygon_shape_5.webp)
  - In the mode [`EPolygonMeasurementMode_Point`](../../../doxygen_cpp/namespaceeVision.html#a0dbcd45fa15584c368059f6b563c7ae5) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a353b4c9608f9ee2d6ab28e1e0bae0308) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPolygonMeasurementMode.html), the measured polygon edges are sampled to fit closely to all the measured points.
    - The measured polygon is simplified using a filtering threshold ([`EBaseGauge::GetFilteringThreshold`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a5aa4206d405442a6eab194fa3d3556ae) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ada249ceb11f155ce18e6278a98451991) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aa81f33b10f1ae80b5e48168d3944fdc7)) to reduce the number of edges while keeping the shape of the object.
    - The measured number of edges depends on the geometry of the contour of the object and on the filtering threshold.

    ![image](assets/images/easygauge/polygon_shape_6.webp)

    Depending on the filtering threshold, the number of vertices is reduced.

<a id="easygauge-principles"></a>

## Principles of EasyGauge

<a id="easygauge-principles-transitions"></a>

### Finding Transition Points

All gauges are based on finding the position of all the *transition* points, called  ***sample points***, along a line segment probe, called the  ***sample path***, that cross one or several object edges and selecting the most relevant ones.

To do that, **EasyGauge** extracts the pixel values along the  ***sample path*** (the red curve) then uses the *peak analysis* to determine the transition location. All the pixel values in the peak area are used to compute the transition location.

![](assets/images/easygauge/17811.webp)![](assets/images/easygauge/17812.webp)

On a sample path extracted from an image:

- An edge appears as a transition from dark to light (or vice versa).
- When plotting the pixel values along the sample path, this transition appears as an S-shaped curve.
- The first derivative of this curve exhibits a peak around the transition point.

#### HINT
* The better the contrast, the sharper the transition and the higher the peak.
* Sub-pixel accuracy is only possible if the transition is surrounded by almost uniform regions of at least 2 pixels wide.

<a id="easygauge-principles-complex-shapes"></a>

### Measuring Complex Shapes

Except for the [point gauge](#easygauge-point-gauge), all gauges try to find and measure *complex shapes* with the following algorithm:

1. Place *sample paths* along the nominal shape at regular interval
2. Measure each *sample path* to find *sample points* on this path.
3. Select one *sample point* for each *sample path*.
4. Fit the shape to the selected *sample points*.
   * Fitting the shape means adjusting its parameters to minimize the error residue (average distance of the *sample points* to the measured shape).
   * The fitting algorithm can include an iterative **outlier rejection** process, that will reject *sample points* that may harm the location accuracy:
     1. Apply the model fitting to the *valid* *sample points*.
     2. The *sample points* that are too far away from the fitted model and may harm the location accuracy are made *invalid*.
     3. Repeat the proccess.

<a id="easygauge-measure-fit"></a>

## Measurement and Fitting Parameters

<a id="easygauge-finding-sample-points"></a>

### Finding Sample Points

All the gauges and [`ESamplePath`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html) contain all the point measurement parameters, with default values that detect reasonably contrasted edges:

- **Transition strength**: [`SetThreshold`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a185e9cc49dccd3773d21e6dee807562d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a9e30f8e604bf1713eacad5aeb4c0ae97) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a7970541dc26319297a6de5118d56adb0), [`SetMinAmplitude`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a02cc4c1a2bb74b7bc391eda6a3f05f16) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a070930eaa83a8b025656051d398222d6) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#adeb59e24108f92a673cf357970b02aaf) and [`SetMinArea`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a628258955773334dce4d35178776c2e3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a6667ef228e55f1d15284a4983ccd2cd2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a55bee6e74aced823d537b8448f8bfc7e).
- **Transition type**:  [`SetTransitionType`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a4928445b5def3195d04ab248e2db5ec3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a347bd2f0467284f265cd27798d218fd4) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#ae4e84e7b046d97ee9358ad2d1a689429)
- **Transition choice**: [`SetTransitionChoice`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a7e122f57948b56f44164aa6a3038c192) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ad4a20a6e2f9f324ed51ef72b5f6654a7) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a3337480e3c1d23c584d251465937c048) and [`SetTransitionIndex`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a74f05fd0a12a15b7dffdb1e322753b2f) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#af638cb91bfe6f669f32c7d8d83b3dff7) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a3d6bf58ee9d9641337f1d489822e3348).
- **Local filtering** for noise immunity: [`SetThickness`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a08490f398c01c9fcc1e6b56ea622f05e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a8f7b6e322198dfdda118d58eea446e37) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a5d816ab2b39f8be256d6a3b7a822bbdf) and [`GetSmoothing`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#ab508543043a4bf3e61c10ca332fedaa8) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ac13eafc7ed3273beee7dcbcaf78c60e2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aaacc1ef9317b4201164e28c1bfb27393).
  - Sampling area (rectangular by default) for **transverse filtering** [`SetRectangularSamplingArea`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#ae01ba2fc95ef592c805c14d0a9700cba) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ab4baca8f0f0f17e35138a28bba3c26dd) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a32a4b5ac88fe6af78b0395d5dec41e16).

<a id="easygauge-transitions-parameters-strength"></a>

#### Transition Strength

The [`threshold`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a185e9cc49dccd3773d21e6dee807562d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a9e30f8e604bf1713eacad5aeb4c0ae97) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a7970541dc26319297a6de5118d56adb0) level is very important:

- Too high and significant transitions can be missed and insufficient pixel values can achieve good precision.
- Too low and noise can cause false transitions.

To resolve this dilemma, the **EasyGauge** transition selection mechanism can reject low contrast or false edges:

- The **transition strength** is measured by the peak amplitude and the area.
- Every edge measurement determine the peak amplitude and the area.
  - The peak amplitude is the difference between the peak value and the threshold.
  - The peak area is the area under the peak curve and the horizontal line at the threshold value.
- If either value falls below the [`minimum amplitude`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a02cc4c1a2bb74b7bc391eda6a3f05f16) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a070930eaa83a8b025656051d398222d6) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#adeb59e24108f92a673cf357970b02aaf) or the [`minimum area`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a628258955773334dce4d35178776c2e3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a6667ef228e55f1d15284a4983ccd2cd2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a55bee6e74aced823d537b8448f8bfc7e), the peak is disregarded and no point is assumed at that location.

![](assets/images/easygauge/17813.webp)![](assets/images/easygauge/17814.webp)

<a id="easygauge-transitions-parameters-selection-type"></a>

#### Transition Type

Select the type of transition to find with [`SetTransitionType`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a4928445b5def3195d04ab248e2db5ec3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a347bd2f0467284f265cd27798d218fd4) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#ae4e84e7b046d97ee9358ad2d1a689429):

- Simple edges:
  - White to Black ([`Wb`](../../../doxygen_cpp/namespaceeVision.html#a503eb9d53e76fdabfeec1a6049ce63faa1e92879f7233cddf64ae58f60a841f65) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6c6c76fcc0cfe176b06aa486c594fe71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionType.html#ad3d78ab737556dc4369cb384a5b92d9d))
  - Black to White ([`Bw`](../../../doxygen_cpp/namespaceeVision.html#a503eb9d53e76fdabfeec1a6049ce63faa09442b9e58afed0973aeddab0dd4af1f) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6c6c76fcc0cfe176b06aa486c594fe71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionType.html#a3dfdfdce8087e55eb23da95fbc45a975))
  - indifferent polarities ([`BwOrWb`](../../../doxygen_cpp/namespaceeVision.html#a503eb9d53e76fdabfeec1a6049ce63faa51af95d4719e4dd61a78828c727f6796) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6c6c76fcc0cfe176b06aa486c594fe71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionType.html#afc7190abe61996f230c94032f6e70337))

  ![](assets/images/easygauge/pointlocationblacktowhite.webp)![](assets/images/easygauge/pointlocationwhitetoblack.webp)![](assets/images/easygauge/pointlocationindifferent.webp)
- Complex edges:
  - Black to white to black ([`Bwb`](../../../doxygen_cpp/namespaceeVision.html#a503eb9d53e76fdabfeec1a6049ce63faa856a6d6f63eae15e3c4b370ce87470d5) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6c6c76fcc0cfe176b06aa486c594fe71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionType.html#a05bed095d891ac091f8df552d9cb215d))
  - White to black to white ([`Wbw`](../../../doxygen_cpp/namespaceeVision.html#a503eb9d53e76fdabfeec1a6049ce63faa5751815ca7c369c6a244ee7593cd5ad9) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6c6c76fcc0cfe176b06aa486c594fe71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionType.html#af3048797bf02c51bb5e5a576d72136d8))

  ![image](assets/images/easygauge/pointlocationbwb.webp)

  #### HINT
  You cannot normally detect transitions using the default threshold value (20) as BWB or WBW transitions base the peak analysis on the gray level profile along the sample path and not its first derivative.

<a id="easygauge-transitions-parameters-selection-choice"></a>

#### Selecting the Most Relevant Transition

There can be multiple transitions that match the transition detection parameters. The parameter [`SetTransitionChoice`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a7e122f57948b56f44164aa6a3038c192) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6f6ea8698bdeb6b9b55195dd5009f2cf) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionChoice.html) can be used to select the single most relevant transition. With point gauges, this parameter can have the value [`ETransitionChoice_All`](../../../doxygen_cpp/namespaceeVision.html#acd7f1f07a61c7557c8640005e32b48f8) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a6f6ea8698bdeb6b9b55195dd5009f2cf) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ETransitionChoice.html), which will return all the transitions matching the other parameter of the detection.

![](assets/images/easygauge/17815.webp)![](assets/images/easygauge/17816.webp)

You can select the single most relevant transition based on 4 criteria:

| ![Best area](assets/images/easygauge/17817.webp)   | ![Best amplitude](assets/images/easygauge/17818.webp)     |
|----------------------------------------------------|-----------------------------------------------------------|
| ![Closest](assets/images/easygauge/17819.webp)     | ![3rd from the start](assets/images/easygauge/17820.webp) |

#### NOTE
When several peaks have the same value (same area, same amplitude…), the last peak is selected.

<a id="easygauge-transitions-parameters-filtering"></a>

#### Filtering noise

Filtering the image locally can reduce the noise effects.

There are 2 types of filtering:

* The **transverse (lengthwise) filtering** averages several parallel lines when sampling the image.
  - The [`thickness`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a08490f398c01c9fcc1e6b56ea622f05e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a8f7b6e322198dfdda118d58eea446e37) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a5d816ab2b39f8be256d6a3b7a822bbdf) determines the number of parallel lines.

    ![Thick point gauge for filtering](assets/images/easygauge/17823.webp)
  - The parallel lines can be contained in a parallelogram or a rectangle ([`SetRectangularSamplingArea`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#ae01ba2fc95ef592c805c14d0a9700cba) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ab4baca8f0f0f17e35138a28bba3c26dd) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a32a4b5ac88fe6af78b0395d5dec41e16)).

    ![Best area](assets/images/easygauge/17824.webp)    ![Best amplitude](assets/images/easygauge/17825.webp)
* The **longitudinal (crosswise) uniform filtering** can also be applied to the resulting profile curve ([`SetSmoothing`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#afa38e86d24691d38f8e2b57c57936718) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ac13eafc7ed3273beee7dcbcaf78c60e2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aaacc1ef9317b4201164e28c1bfb27393))

<a id="easygauge-configuring-sample-paths"></a>

### Configuring Sample Paths

* Use [`SetSamplingStep`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a271a782827fb6a0bbedd089e35704d3f) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a18c5afeb682b35834c4f56bef2d28823) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a3610d7aa1dec72f7ca8f3056f3291731) to set the **spacing between the paths**.
  - Use [`GetNumSamples`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aaf4540259ba164d14fe45fc86918f3ed) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ac337e4244ee3ab86e4f5f3063dbcb1ae) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a090769142aa315864d11405814edf54b) to get the number of paths that are sampled.
* Use [`SetTolerance`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a2010988f5449f0c629d00af67817db03) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a99f6c19c11f551581aec80a247bb5d10) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a24ad68f60cd6d344dd957d234982a4bb) to set the length of these paths that is the half-length of the line segment. The **tolerance** is how far to look for edge crossings around the nominal shape.

  #### NOTE
  Note that the [`EPointGauge`](../../../doxygen_cpp/classeVision_1_1EPointGauge.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointGauge.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointGauge.html) has no tolerance because it consists in the measurement of edge-crossing on its nominal line.

![Point gauge](assets/images/easygauge/measurement_concepts.jpg)

<a id="easygauge-fit-shape"></a>

### Fitting Parameters

* **[Outlier rejection](#easygauge-principles-complex-shapes)** parameters:
  * The [`number of iterations`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a2acdae6bb39d4fe00cd9b1cfb320bcc3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a5aee3ba88c0ed7c889850e979fe35765) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a7011138fe9d9a0e19a4d2d3f9b2d075f) in the algorithm.
  * The [`threshold`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#af4a610377ecc31fc2676ea773e3aad51) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ada249ceb11f155ce18e6278a98451991) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aa81f33b10f1ae80b5e48168d3944fdc7) used to tag a sample point as an outlier.
* **Skip ranges**:
  - The skip ranges define the exclusion ranges for the paths. The sample point indexes in the skip ranges are not taken into account to fit the model.

    #### NOTE
    The skip ranges apply to all gauge models but the polygon gauge.
  - Use [`AddSkipRange`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aa24e6fe906f717ffac0e73f9faeb5213) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a32a44d421132f8cba02a998990dbd2b0) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#ab020d1dc4c47b8ff825ae507f559a95c) to define several skip ranges.
  - Use [`RemoveSkipRange`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a961d0135da9203abc953db20c15e5155) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a98f6626a8dcf2dc343264f1e38d01087) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a3aaa25672bca8719382867bba720a410), [`RemoveAllSkipRanges`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a797541d91b8c0125960b8001f791f0ab) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a88b5cacd95a0fc0142107c56871c91d6) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a84de91962cbb067f0042189ced8bbbbf) and [`GetSkipRange`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a18b1baa37972ee68aba05cfe9c2ba2c4) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a2a7af900125b5d3d73df9cc60233212b) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a12a47015d4826bfc243eb4df8ca107f6) to manage the skip ranges.
  - Use the attribute [`EDrawingMode_PointsInSkipRange`](../../../doxygen_cpp/namespaceeVision.html#a46a5eff0a429fb8f7157564a9c7e620c) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a22d98bfe7b35ea321e8d60e62e838438) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawingMode.html) with the method [`Draw`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aa8af0a9d89d6dbe0fcd676102f8876e0) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a238794f6aaf4c6af7759ed8549e8380a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a50c184a719e5c05380fa1ab57b54a157) to display the skipped points.

<a id="easygauge-advanced-usage"></a>

## Advanced Usage

<a id="easygauge-advanced-usage-analyze"></a>

### Analyzing the Results

* Use [`MeasureSamplePath(n)`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a675cb0d501015c87e0ec28479055bd31) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#af77230f583f0520bdcca677b1790417a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a19ff9fce228507c08a3f311b933f017e) to perform the measurement of the n-th sample path.
  * This measurement can be useful to tune the transition measurements parameters. See the [section below](#easygauge-transitions-tuning).
  * This method returns an [`ESamplePath`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html) object:
    * Use [`GetSamplePath`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#ada5869e81e15d5c4c4aa06eaf9aca53d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#ab817c20629eb088f4f47acb848c3f14a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a01d378951853e408718757d21aee9100) to get the line segment of the path.
    * Use [`GetMeasuredPoint`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#aadce42b9490904de0978489c8cf41e43) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#a5793e0aa05bd36d399e12eb77c408f88) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a98205125e7d8ce5885c4510fcdaff71a) to get the selected measured point or use [`GetMeasuredPoints`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#a5723497c0484d05b3abb9e249af8bb7e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#a8499dffd9090b99e707f69b185ad2ed4) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a6d02baddba532d513c917018497bc790) to get all the measured points.
    * Use [`Plot`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#a5f0df3c24f415d0e03b60ea470d5fa3e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#a565250bc0606785f67511654ff30dbb3) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a5ac5626792dc7280318b73409c4178df) to plot the profile and/or the derivative of the path.
    * Use [`DrawPath`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#a85630325d6952309938389ba038deded) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#ac65877d702eec9e70f644ef534f124d1) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a59b074fdfb741adeb450de31f02e0164) to draw the path.
* After having measured the gauge with [`EBaseGauge::Measure`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a09dbcb0c1bb7681ba31870c626fd0231) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a3fa25d60234bce338c219c93e591626f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#addcbfdee6ba540ab56d43c653a06e8e2)
  * Use [`GetSample(n)`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#ad8c734183ea33359237f662fbcc0395c) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#ab41393e2e281ce62bf2d19898f0148d5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a97669298f4de34aeff01df37e7804e35) to get the measured [`sample point`](../../../doxygen_cpp/classeVision_1_1ESamplePoint.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePoint.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePoint.html) of the n-th sample path. The sample point contains:
    * Its [`position`](../../../doxygen_cpp/classeVision_1_1ESamplePoint.html#a7b53a3bc047876b079b2a299f41519e3) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePoint.html#aa647f63bd3feb81ba831986115073ba0) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePoint.html#ab21b5e4c8d464f96555767b551c2f1b2).
    * Information about the edge crossing ([`EPeak`](../../../doxygen_cpp/classeVision_1_1ESamplePoint.html#ab5e1f6039178e781542f3b1cf1263cd7) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePoint.html#a2d826186b594ddeae8a6b935fc87a19a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePoint.html#a60c3a39bc16eac7f181b8f186074b141)).
    * Its [`validity`](../../../doxygen_cpp/classeVision_1_1ESamplePoint.html#addec7ebc15850c5987600d4675d0178b) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePoint.html#a385d9f6f6077adab7e02857ac2ba4ef5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePoint.html#a5fc40fcb522da4785f204cc9ee9e4d21): a point is valid if at least one transition point was found matching the transition measurement parameters and it wans’t rejected as an outlier or due to the skip ranges.
    * Whether it was rejected as an [`outlier`](../../../doxygen_cpp/classeVision_1_1ESamplePoint.html#aed7de3a10d498671a4079c28310b195b) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePoint.html#aa652356f0dca0bfe9bfdba60a327627a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePoint.html#aa9433ac0b2f4be2fac1ad37f63c393e0).
  * Use [`GetNumValidSamples`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#afac19326d6d23ea89410e6a040a8e1d9) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a971da697d294a055cbeab0a3700d89f2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a30251da40061fdf6380e9929aecfb0ed) to get the number of valid sample points remaining after the model fitting operation.
  * Use [`GetAverageDistance`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aee2e8789e129d26e1f2f8a0d8d248bc8) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a0dd5cd08cec568f5f6b91a0fd5bd2c60) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aa0429b7fbe5e1c0313ab612eab885841) to get the average distance of these points to the fitted model.

<a id="easygauge-transitions-tuning"></a>

### Tuning the Transition Measurement Parameters for Unclear Transitions

The **EasyGauge** default parameters and working modes are good for clear transitions.

More complex situations may need the tuning of additional parameters. Here, we show how to tune a point gauge. However, you can apply the same method to the other gauges by analyzing their sample paths.

1. **Set the gauge point location and tolerance.**
   - Sets the nominal line of the point gauge. Its [`center position`](../../../doxygen_cpp/classeVision_1_1ELine.html#a3df0fc707a72d8e064f18843aea4f54d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELine.html#a0803a690352c0e24f9b411f3ac1b5802) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELine.html#a29abdffffa0f79050c68cb1f5b39ae72) and [`orientation`](../../../doxygen_cpp/classeVision_1_1ELine.html#aadf02c440675419fd93968a6a238e022) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ELine.html#a20651aeef27892d7999900b2038c60be) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ELine.html#a31a78935bb1ffcfbb544c0fb14d48072) are easy to decide based on a sample image or on the coordinate considerations.
   - The [`tolerance`](../../../doxygen_cpp/classeVision_1_1EPointGauge.html#a07be747a927ab3989c81fc0b09da6744) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EPointGauge.html#adb712e65f7ef17a0af239636f880265f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EPointGauge.html#a5a8034e5061aec53b2838f6f179bec78) depends on the edge position variations. A larger tolerance increases the likelihood of hitting an edge, but it may be a false edge or an extraneous feature.

   ![image](assets/images/easygauge/17836.webp)
2. **Decide whether a noise reduction is required.**
   - Lay the gauge over the desired location and observe the profile curve and its derivative (play with the filtering parameters while looking at the plotted curve).
   - The curve regularity gives an indication of the spread of the gray-level values.
   - When these coefficients are set, the gray-level profile will not change anymore.

   ![image](assets/images/easygauge/17837.webp)
3. **Set the threshold value.**
   - Set a value low enough for useful parts of the peaks to cover enough pixels (to achieve better sub-pixel accuracy), but not lower than the ambient image noise.

   ![image](assets/images/easygauge/17838.webp)
4. **Remove weak or false transitions.**
   - Use the list of peak amplitudes and areas.
   - Plotting these values along with good and extraneous peaks can help find appropriate peak rejection limits.

   ![image](assets/images/easygauge/17839.webp)
5. **Choose whether all transition points are needed or just the most relevant**.
   - If all the transition points are required, you can query them one after the other.
   - Otherwise, choose a point selection strategy based on the strength, the order or the transition polarity (black to white and/or conversely).

   ![image](assets/images/easygauge/17840.webp)

<a id="easygauge-display-graphical-manipulation"></a>

## Display and Graphical Manipulation

<a id="easygauge-drawing"></a>

### Drawing

[`EBaseGauge::Draw`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aa8af0a9d89d6dbe0fcd676102f8876e0) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a238794f6aaf4c6af7759ed8549e8380a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a50c184a719e5c05380fa1ab57b54a157) gives a graphical representation of the gauge.

Use the enumerate [`EDrawingMode`](../../../doxygen_cpp/namespaceeVision.html#a46a5eff0a429fb8f7157564a9c7e620c) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a22d98bfe7b35ea321e8d60e62e838438) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawingMode.html) to specify the parts of the gauge that you want to draw:

- `EDrawingMode_Nominal` to draw the nominal shape, the gauge tolerances and the handles.
  ![Point gauge](assets/images/easygauge/edrawingmode_nominal.webp)
- `EDrawingMode_Actual` to draw the measured shape.
  ![Point gauge](assets/images/easygauge/edrawingmode_actual.webp)
- `EDrawingMode_Tolerances` to draw the tolerances around the nominal shape and its handles.
- `EDrawingMode_TransitionType` to draw the transition type of each edge of the shape.
  ![Point gauge](assets/images/easygauge/edrawingmode_transitiontype.webp)
- `EDrawingMode_SampledPaths` to draw the paths sampled along the nominal shape.
- `EDrawingMode_SampledPoints` to draw the points measured along each path sampled along the nominal shape that were used to fit the shape.
  ![Point gauge](assets/images/easygauge/edrawingmode_samplepoints.png.jpg)
- `EDrawingMode_InvalidSampledPoints` to draw the points measured along each path sampled along the nominal shape that were excluded from the shape fitting operation (outliers).
  ![Point gauge](assets/images/easygauge/edrawingmode_invalidsamplepoints.webp)
- `EDrawingMode_PointsInSkipRange` to draw the points in the skip ranges for the gauges that support skip ranges.

<a id="easygauge-graphical-manipulation"></a>

### Graphical Manipulations

* Use [`EBaseGauge::GetAvailableEditionModes`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#af0f7fc38e18ac177b387e1b454ed7eca) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a7ef109c887dc001fbb29abf468f64cc2) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a43b691978500433c9ea6f4d0430ac526) to get the available graphical edition mode.
  - It returns the edition modes of the underlying nominal shape and [`EEditionMode_Tolerances`](../../../doxygen_cpp/namespaceeVision.html#a7640350ea6abaa1b8568b578bfbd6222) [<sub>.NET</sub>](../../../doxygen_cs/namespaceeVision.html#a50693d260f38bf5e424f036c09ad4a6d) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EEditionMode.html) if the gauge has tolerances.
* Use [`EBaseGauge::SetEditionMode`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a276ae543b5e097a1c1c47d82bdc80970) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a21b9f2a46ad89240ef3da58d25d9cb8a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aa82d197b97aeb164302a0a9c4b85c7bd) to set the edition modes that you want to activate.
* Use [`EBaseGauge::HitTest`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a72d87e6c8188b33d14b73048d717f9a9) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a47d6d14123c93c3d1fd89a19e1ec5f50) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#afbf57a187990c99768220a8225f54eb1) to determine when the mouse cursor is over a handle and get the corresponding edition mode that you can use to change the shape of the mouse.
* Use [`EBaseGauge::Drag`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#aac134c1925ed13422e37c16150cf8044) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a3ae09dec3a529e76719aa09e18b6bc71) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#aba4e2c2c2aa63f049a56c0e6afd723f4) to move the handle and the corresponding gauge accordingly.

![image](assets/images/easygauge/tolerance_graphical_manipulation.svg)

#### NOTE
With the API, you can perform graphical manipulation on the *nominal* shape and on the tolerances of the gauge. However, in **eVision Studio**, only the tolerances can be manipulated in the gauge tools.

<a id="easygauge-plot"></a>

### Plot

**EasyGauge** can plot gray-level values along the sample paths and/or its derivative. This is useful to tune the parameters.

* Use [`EBaseGauge::MeasureSamplePath`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a675cb0d501015c87e0ec28479055bd31) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#af77230f583f0520bdcca677b1790417a) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#a19ff9fce228507c08a3f311b933f017e) to get the measured sample path for one of the sample paths of the gauge.
  - Use [`ESamplePath::Plot`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#a5f0df3c24f415d0e03b60ea470d5fa3e) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#a565250bc0606785f67511654ff30dbb3) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a5ac5626792dc7280318b73409c4178df) to plot the profile and/or the derivative.
    ![Point gauge](assets/images/easygauge/esamplepath_plot.jpg)
  - Use [`ESamplePath::DrawPath`](../../../doxygen_cpp/classeVision_1_1ESamplePath.html#a85630325d6952309938389ba038deded) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1ESamplePath.html#ac65877d702eec9e70f644ef534f124d1) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1ESamplePath.html#a59b074fdfb741adeb450de31f02e0164) to draw the sample path that was measured.
    ![Point gauge](assets/images/easygauge/esamplepath_drawpath.webp)

<a id="easygauge-frame"></a>

### Frame

* When calling the drawing and graphical manipulations methods, pass the frame in which the shape is defined.
* Also pass the same frame to [`EBaseGauge::Measure`](../../../doxygen_cpp/classeVision_1_1EBaseGauge.html#a09dbcb0c1bb7681ba31870c626fd0231) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EBaseGauge.html#a3fa25d60234bce338c219c93e591626f) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EBaseGauge.html#addcbfdee6ba540ab56d43c653a06e8e2).

#### SEE ALSO
Have a look at the [differences with the old legacy API](porting_from_legacy_gauge.html.md#easygauge-difference-legacy) of **EasyGauge** and how to port your application to the new API.
