---
name: v.rectify
description: Rectifies a vector by computing a coordinate transformation for each object in the vector based on the control points.
keywords: [ vector, rectify, level1, geometry ]
---

# v.rectify

Rectifies a vector by computing a coordinate transformation for each object in the vector based on the control points.

=== "Command line"

    **v.rectify**
    [**-3orb**]
    **input**=*name*
    **output**=*name*
    [**group**=*name*]
    [**points**=*name*]
    [**rmsfile**=*name*]
    [**order**=*integer*]
    [**separator**=*character*]
    [**--overwrite**]
    [**--verbose**]
    [**--quiet**]
    [**--qq**]
    [**--ui**]

    Example:

    ```sh
    v.rectify input=name output=name
    ```

=== "Python (grass.tools)"

    *grass.tools.Tools.v_rectify*(**input**,
        **output**,
        **group**=*None*,
        **points**=*None*,
        **rmsfile**=*None*,
        **order**=*1*,
        **separator**=*"pipe"*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    tools = Tools()
    tools.v_rectify(input="name", output="name")
    ```

    This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.

=== "Python (grass.script)"

    *grass.script.run_command*("***v.rectify***",
        **input**,
        **output**,
        **group**=*None*,
        **points**=*None*,
        **rmsfile**=*None*,
        **order**=*1*,
        **separator**=*"pipe"*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    gs.run_command("v.rectify", input="name", output="name")
    ```

## Parameters

=== "Command line"

    **input**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source for direct OGR access  
    **output**=*name* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    **group**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input imagery group  
    **points**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input file with control points  
    **rmsfile**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of output file with RMS errors (if omitted or '-' output to stdout  
    **order**=*integer*  
    &nbsp;&nbsp;&nbsp;&nbsp;Rectification polynomial order (1-3)  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-3*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **separator**=*character*  
    &nbsp;&nbsp;&nbsp;&nbsp;Field separator for RMS report  
    &nbsp;&nbsp;&nbsp;&nbsp;Special characters: pipe, comma, space, tab, newline  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *pipe*  
    **-3**  
    &nbsp;&nbsp;&nbsp;&nbsp;Perform 3D transformation  
    **-o**  
    &nbsp;&nbsp;&nbsp;&nbsp;Perform orthogonal 3D transformation  
    **-r**  
    &nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors  
    &nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors and exit without rectifying the input map  
    **-b**  
    &nbsp;&nbsp;&nbsp;&nbsp;Do not build topology  
    &nbsp;&nbsp;&nbsp;&nbsp;Advantageous when handling a large number of points  
    **--overwrite**  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    **--help**  
    &nbsp;&nbsp;&nbsp;&nbsp;Print usage summary  
    **--verbose**  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    **--quiet**  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    **--qq**  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    **--ui**  
    &nbsp;&nbsp;&nbsp;&nbsp;Force launching GUI dialog

=== "Python (grass.tools)"

    **input** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source for direct OGR access  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **output** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **group** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input imagery group  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, group, *name*  
    **points** : str | io.StringIO, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input file with control points  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, file, *name*  
    **rmsfile** : str | io.StringIO, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of output file with RMS errors (if omitted or '-' output to stdout  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, file, *name*  
    **order** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Rectification polynomial order (1-3)  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-3*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **separator** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Field separator for RMS report  
    &nbsp;&nbsp;&nbsp;&nbsp;Special characters: pipe, comma, space, tab, newline  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, separator, *character*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *pipe*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *3*, *o*, *r*, *b*  
    &nbsp;&nbsp;&nbsp;&nbsp;**3**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform 3D transformation  
    &nbsp;&nbsp;&nbsp;&nbsp;**o**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform orthogonal 3D transformation  
    &nbsp;&nbsp;&nbsp;&nbsp;**r**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors and exit without rectifying the input map  
    &nbsp;&nbsp;&nbsp;&nbsp;**b**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not build topology  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Advantageous when handling a large number of points  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  

    Returns:

    **result** : grass.tools.support.ToolResult | None  
    If the tool produces text as standard output, a *ToolResult* object will be returned. Otherwise, `None` will be returned.

    Raises:

    *grass.tools.ToolError*: When the tool ended with an error.

=== "Python (grass.script)"

    **input** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Or data source for direct OGR access  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, vector, *name*  
    **output** : str, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output vector map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, vector, *name*  
    **group** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input imagery group  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, group, *name*  
    **points** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of input file with control points  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, file, *name*  
    **rmsfile** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Name of output file with RMS errors (if omitted or '-' output to stdout  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, file, *name*  
    **order** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Rectification polynomial order (1-3)  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-3*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *1*  
    **separator** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Field separator for RMS report  
    &nbsp;&nbsp;&nbsp;&nbsp;Special characters: pipe, comma, space, tab, newline  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: input, separator, *character*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *pipe*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *3*, *o*, *r*, *b*  
    &nbsp;&nbsp;&nbsp;&nbsp;**3**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform 3D transformation  
    &nbsp;&nbsp;&nbsp;&nbsp;**o**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Perform orthogonal 3D transformation  
    &nbsp;&nbsp;&nbsp;&nbsp;**r**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Print RMS errors and exit without rectifying the input map  
    &nbsp;&nbsp;&nbsp;&nbsp;**b**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not build topology  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Advantageous when handling a large number of points  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*

## DESCRIPTION

*v.rectify* uses control points to calculate a 2D or 3D transformation
matrix based on a first, second, or third order polynomial and then
converts x,y(, z) coordinates to standard map coordinates for each
object in the vector map. The result is a vector map with a transformed
coordinate system (i.e., a different coordinate system than before it
was rectified).

The *-o* flag enforces orthogonal rotation (currently for 3D only) where
the axes remain orthogonal to each other, e.g. a cube with right angles
remains a cube with right angles after transformation. This is not
guaranteed even with affine (1st order) 3D transformation.

Great care should be taken with the placement of Ground Control Points.
For 2D transformation, the control points must not lie on a line,
instead 3 of the control points must form a triangle. For 3D
transformation, the control points must not lie on a plane, instead 4 of
the control points must form a triangular pyramid. It is recommended to
investigate RMS errors and deviations of the Ground Control Points prior
to transformation.

2D Ground Control Points can be identified in
*[g.gui.gcp](g.gui.gcp.md)*.

3D Ground Control Points must be provided in a text file with the
**points** option. The 3D format is equivalent to the format for 2D
ground control points with an additional third coordinate:

```sh
 x y z east north height status
```

where *x, y, z* are source coordinates, *east, north, height* are target
coordinates and status (0 or 1) indicates whether a given point should
be used. Numbers must be separated by space and must use a point (.) as
decimal separator.

If no **group** is given, the rectified vector will be written to the
current mapset. If a **group** is given and a target has been set for
this group with *[i.target](i.target.md)*, the rectified vector will be
written to the target project and mapset.

### Coordinate transformation and RMSE

The desired order of transformation (1, 2, or 3) is selected with the
**order** option. If the **-r** flag is given, *v.rectify* will
calculate the Root Mean Square Error (RMSE) and print out statistics in
tabular format. The last row gives a summary with the first column
holding the number of active points, followed by average deviations for
each dimension and both forward and backward transformation and finally
forward and backward overall RMSE.

#### 2D linear affine transformation (1st order transformation)

x' = a1 + b1 \* x + c1 \* y

y' = a2 + b2 \* x + c2 \* y

#### 3D linear affine transformation (1st order transformation)

x' = a1 + b1 \* x + c1 \* y + d1 \* z

y' = a2 + b2 \* x + c2 \* y + d2 \* z

z' = a3 + b3 \* x + c3 \* y + d3 \* z

The a,b,c,d coefficients are determined by least squares regression
based on the control points entered. This transformation applies
scaling, translation and rotation. It is NOT a general purpose
rubber-sheeting, nor is it ortho-photo rectification using a DEM, not
second order polynomial, etc. It can be used if (1) you have
geometrically correct data, and (2) the terrain or camera distortion
effect can be ignored.

#### Polynomial Transformation Matrix (2nd, 3d order transformation)

*v.rectify* uses a first, second, or third order transformation matrix
to calculate the registration coefficients. The minimum number of
control points required for a 2D transformation of the selected order
(represented by n) is

((n + 1) \* (n + 2) / 2)

or 3, 6, and 10 respectively. For a 3D transformation of first, second,
or third order, the minimum number of required control points is 4, 10,
and 20, respectively. It is strongly recommended that more than the
minimum number of points be identified to allow for an overly-determined
transformation calculation which will generate the Root Mean Square
(RMS) error values for each included point. The polynomial equations are
determined using a modified Gaussian elimination method.

## SEE ALSO

The GRASS 4 *[Image Processing
manual](https://grass.osgeo.org/gdp/imagery/grass4_image_processing.pdf)*

*[g.gui.gcp](g.gui.gcp.md), [i.group](i.group.md),
[i.rectify](i.rectify.md), [i.target](i.target.md),
[m.transform](m.transform.md), [r.proj](r.proj.md), [v.proj](v.proj.md),
[v.transform](v.transform.md)*  
*[Manage Ground Control Points](wxGUI.gcp.md)*

## AUTHOR

Markus Metz

based on [i.rectify](i.rectify.md)

## SOURCE CODE

Available at: [v.rectify source code](https://github.com/OSGeo/grass/tree/main/vector/v.rectify)
([history](https://github.com/OSGeo/grass/commits/main/vector/v.rectify))  
Latest change: Friday Apr 17 01:04:26 2026 in commit [32a1433](https://github.com/OSGeo/grass/commit/32a143358df26b2e518b03c7e0d79541e8d1e5b1)
