nudged


Namenudged JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/axelpale/nudged-py
SummaryEstimate scale, rotation, and translation between two sets of 2D points e.g. for multi-touch gestures or calibration
upload_time2016-02-26 18:11:33
maintainer
docs_urlNone
authorAkseli Palen
requires_pythonNone
licenseMIT
keywords transformation calibration multitouch affine estimation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ======================
nudged\ :sup:`0.3.1`
======================

A Python lib to estimate scale, rotation, and translation between two sets of 2D points. Applicable for example in cases where one wants to move objects by multiple fingers or where a large number of points from an eye tracker device are wanted to be corrected based on a few calibration points. In general, you can apply nudged in any situation where you want to move a number of points based on a few sample points.

.. image:: https://raw.githubusercontent.com/axelpale/nudged-py/master/doc/nudged-logo.png
   :alt: Example transformation
   :height: 353px
   :width: 300px

Mathematically speaking, nudged is an optimal least squares estimator for `affine transformation matrices
<https://en.wikipedia.org/wiki/Affine_transformation>`_ with uniform scaling, rotation, and translation and without reflection or shearing. The estimation has time complexity of O(*n*) that consists of *6n+22* multiplications and *11n+19* additions, where *n* is the cardinality (size) of the point sets. In other words, nudged solves an affine 2D to 2D point set registration problem in linear time.

Available also `in JavaScript
<https://www.npmjs.com/package/nudged>`_.



Install
=======

``$ pip install nudged``



Usage
=====

You have lists of points for the **domain** and **range** of the tranformation function to be estimated::

    dom = [[0,0], [2,0], [ 1,2]]
    ran  = [[1,1], [1,3], [-1,2]]

Compute optimal tranformation based on the points::

    trans = nudged.estimate(dom, ran);

Apply the transformation to other points::

    trans.transform([2,2])
    # [-1,3]

To explore the estimated transformation, you can::

    trans.get_matrix()
    # [[0,-1, 1],
    #  [1, 0, 1],
    #  [0, 0, 1]]

    trans.get_rotation()
    # 1.5707... = π / 2   (radians)

    trans.get_scale()
    # 1.0

    trans.get_translation()
    # [1, 1]



API
===


nudged.estimate(domain, range)
------------------------------------------

**Parameters**

- *domain*: list of [x,y] points
- *range*: list of [x,y] points

The *domain* and *range* should have equal length. Different lengths are allowed but additional points in the longer list are ignored.

**Return** a new *nudged.Transform(...)* instance.


nudged.estimate_error(transform, domain, range)
-----------------------------------------------

Compute mean squared distance between the point pairs of the domain after the given transformation and the range. If the transform was estimated with the given domain and range, then the result is the mean squared error (MSE) of the estimation.

**Parameters**

- *transform*: a *nudged.Transform* instance
- *domain*: list of [x,y] points
- *range*: list of [x,y] points

**Return** a float, the mean squared distance between the range and transformed domain point pairs.

**Usage example**::

    dom = [[0, 0], [1, 1], [2, 2]]
    ran = [[0,-1], [1, 2], [2,-1]]
    t = nudged.estimate(dom, ran)
    mse = nudged.estimate_error(t, dom, ran)
    # mse == 2.0


nudged.version
--------------

Contains the module version string equal to the version in *setup.py*.


nudged.Transform(s, r, tx, ty)
------------------------------

An instance returned by the *nudged.estimate(...)*.

In addition to the methods below, it has attributes *s*, *r*, *tx*, *ty* that define the `augmented transformation matrix
<https://en.wikipedia.org/wiki/Affine_transformation#Augmented_matrix>`_::

    |s  -r  tx|
    |r   s  ty|
    |0   0   1|

nudged.Transform#transform(points)
..................................

**Return** an list of transformed points or single point if only a point was given. For example::

    trans.transform([1,1])           # [2,2]
    trans.transform([[1,1]])         # [[2,2]]
    trans.transform([[1,1], [2,3]])  # [[2,2], [3,4]]

nudged.Transform#get_matrix()
.............................

**Return** an 3x3 augmented transformation matrix in the following list format::

    [[s,-r, tx],
     [r, s, ty],
     [0, 0,  1]]

nudged.Transform#get_rotation()
...............................

**Return** rotation in radians.

nudged.Transform#get_scale()
............................

**Return** scaling multiplier, e.g. ``0.333`` for a threefold shrink.

nudged.Transform#get_translation()
..................................

**Return** ``[tx, ty]`` where ``tx`` and ``ty`` denotes movement along x-axis and y-axis accordingly.



For developers
==============

Follow `instructions to install pyenv`
<http://sqa.stackexchange.com/a/15257/14918>`_ and then either run quick tests::

    $ python2.7 setup.py test

or comprehensive tests for multiple Python versions in ``tox.ini``::

    $ eval "$(pyenv init -)"
    $ pyenv rehash
    $ tox



Versioning
==========

`Semantic Versioning 2.0.0
<http://semver.org/>`_



License
=======

`MIT License
<http://github.com/axelpale/nudged-py/blob/master/LICENSE>`_
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/axelpale/nudged-py",
    "name": "nudged",
    "maintainer": "",
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": "",
    "keywords": "transformation calibration multitouch affine estimation",
    "author": "Akseli Palen",
    "author_email": "akseli.palen@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/77/f1/0aab175d8666c72627235dadd3955683c96aea954e8d2bdbeb3030cec077/nudged-0.3.1.tar.gz",
    "platform": "UNKNOWN",
    "description": "======================\r\nnudged\\ :sup:`0.3.1`\r\n======================\r\n\r\nA Python lib to estimate scale, rotation, and translation between two sets of 2D points. Applicable for example in cases where one wants to move objects by multiple fingers or where a large number of points from an eye tracker device are wanted to be corrected based on a few calibration points. In general, you can apply nudged in any situation where you want to move a number of points based on a few sample points.\r\n\r\n.. image:: https://raw.githubusercontent.com/axelpale/nudged-py/master/doc/nudged-logo.png\r\n   :alt: Example transformation\r\n   :height: 353px\r\n   :width: 300px\r\n\r\nMathematically speaking, nudged is an optimal least squares estimator for `affine transformation matrices\r\n<https://en.wikipedia.org/wiki/Affine_transformation>`_ with uniform scaling, rotation, and translation and without reflection or shearing. The estimation has time complexity of O(*n*) that consists of *6n+22* multiplications and *11n+19* additions, where *n* is the cardinality (size) of the point sets. In other words, nudged solves an affine 2D to 2D point set registration problem in linear time.\r\n\r\nAvailable also `in JavaScript\r\n<https://www.npmjs.com/package/nudged>`_.\r\n\r\n\r\n\r\nInstall\r\n=======\r\n\r\n``$ pip install nudged``\r\n\r\n\r\n\r\nUsage\r\n=====\r\n\r\nYou have lists of points for the **domain** and **range** of the tranformation function to be estimated::\r\n\r\n    dom = [[0,0], [2,0], [ 1,2]]\r\n    ran  = [[1,1], [1,3], [-1,2]]\r\n\r\nCompute optimal tranformation based on the points::\r\n\r\n    trans = nudged.estimate(dom, ran);\r\n\r\nApply the transformation to other points::\r\n\r\n    trans.transform([2,2])\r\n    # [-1,3]\r\n\r\nTo explore the estimated transformation, you can::\r\n\r\n    trans.get_matrix()\r\n    # [[0,-1, 1],\r\n    #  [1, 0, 1],\r\n    #  [0, 0, 1]]\r\n\r\n    trans.get_rotation()\r\n    # 1.5707... = \u03c0 / 2   (radians)\r\n\r\n    trans.get_scale()\r\n    # 1.0\r\n\r\n    trans.get_translation()\r\n    # [1, 1]\r\n\r\n\r\n\r\nAPI\r\n===\r\n\r\n\r\nnudged.estimate(domain, range)\r\n------------------------------------------\r\n\r\n**Parameters**\r\n\r\n- *domain*: list of [x,y] points\r\n- *range*: list of [x,y] points\r\n\r\nThe *domain* and *range* should have equal length. Different lengths are allowed but additional points in the longer list are ignored.\r\n\r\n**Return** a new *nudged.Transform(...)* instance.\r\n\r\n\r\nnudged.estimate_error(transform, domain, range)\r\n-----------------------------------------------\r\n\r\nCompute mean squared distance between the point pairs of the domain after the given transformation and the range. If the transform was estimated with the given domain and range, then the result is the mean squared error (MSE) of the estimation.\r\n\r\n**Parameters**\r\n\r\n- *transform*: a *nudged.Transform* instance\r\n- *domain*: list of [x,y] points\r\n- *range*: list of [x,y] points\r\n\r\n**Return** a float, the mean squared distance between the range and transformed domain point pairs.\r\n\r\n**Usage example**::\r\n\r\n    dom = [[0, 0], [1, 1], [2, 2]]\r\n    ran = [[0,-1], [1, 2], [2,-1]]\r\n    t = nudged.estimate(dom, ran)\r\n    mse = nudged.estimate_error(t, dom, ran)\r\n    # mse == 2.0\r\n\r\n\r\nnudged.version\r\n--------------\r\n\r\nContains the module version string equal to the version in *setup.py*.\r\n\r\n\r\nnudged.Transform(s, r, tx, ty)\r\n------------------------------\r\n\r\nAn instance returned by the *nudged.estimate(...)*.\r\n\r\nIn addition to the methods below, it has attributes *s*, *r*, *tx*, *ty* that define the `augmented transformation matrix\r\n<https://en.wikipedia.org/wiki/Affine_transformation#Augmented_matrix>`_::\r\n\r\n    |s  -r  tx|\r\n    |r   s  ty|\r\n    |0   0   1|\r\n\r\nnudged.Transform#transform(points)\r\n..................................\r\n\r\n**Return** an list of transformed points or single point if only a point was given. For example::\r\n\r\n    trans.transform([1,1])           # [2,2]\r\n    trans.transform([[1,1]])         # [[2,2]]\r\n    trans.transform([[1,1], [2,3]])  # [[2,2], [3,4]]\r\n\r\nnudged.Transform#get_matrix()\r\n.............................\r\n\r\n**Return** an 3x3 augmented transformation matrix in the following list format::\r\n\r\n    [[s,-r, tx],\r\n     [r, s, ty],\r\n     [0, 0,  1]]\r\n\r\nnudged.Transform#get_rotation()\r\n...............................\r\n\r\n**Return** rotation in radians.\r\n\r\nnudged.Transform#get_scale()\r\n............................\r\n\r\n**Return** scaling multiplier, e.g. ``0.333`` for a threefold shrink.\r\n\r\nnudged.Transform#get_translation()\r\n..................................\r\n\r\n**Return** ``[tx, ty]`` where ``tx`` and ``ty`` denotes movement along x-axis and y-axis accordingly.\r\n\r\n\r\n\r\nFor developers\r\n==============\r\n\r\nFollow `instructions to install pyenv`\r\n<http://sqa.stackexchange.com/a/15257/14918>`_ and then either run quick tests::\r\n\r\n    $ python2.7 setup.py test\r\n\r\nor comprehensive tests for multiple Python versions in ``tox.ini``::\r\n\r\n    $ eval \"$(pyenv init -)\"\r\n    $ pyenv rehash\r\n    $ tox\r\n\r\n\r\n\r\nVersioning\r\n==========\r\n\r\n`Semantic Versioning 2.0.0\r\n<http://semver.org/>`_\r\n\r\n\r\n\r\nLicense\r\n=======\r\n\r\n`MIT License\r\n<http://github.com/axelpale/nudged-py/blob/master/LICENSE>`_",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Estimate scale, rotation, and translation between two sets of 2D points e.g. for multi-touch gestures or calibration",
    "version": "0.3.1",
    "split_keywords": [
        "transformation",
        "calibration",
        "multitouch",
        "affine",
        "estimation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "1a1f80b144baab0177b132a37f5eb1cd",
                "sha256": "9029a7b8c27e3e5af9d7e12f5f55b51b5d51799a72aee3e53408ce68e607ec63"
            },
            "downloads": -1,
            "filename": "nudged-0.3.1-py2.py3-none-any.whl",
            "has_sig": true,
            "md5_digest": "1a1f80b144baab0177b132a37f5eb1cd",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 8011,
            "upload_time": "2016-02-26T18:11:26",
            "upload_time_iso_8601": "2016-02-26T18:11:26.647371Z",
            "url": "https://files.pythonhosted.org/packages/5a/73/1ac27893feda9773ed1c2d26521d0d5e67fe30df7acad81ef0142945297a/nudged-0.3.1-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "6f5feaea0927da774cc459ae17c2f065",
                "sha256": "7f576dcaab3c559171185de067c45469846a3c6cd00792e85bb4b603bb72bec5"
            },
            "downloads": -1,
            "filename": "nudged-0.3.1.tar.gz",
            "has_sig": true,
            "md5_digest": "6f5feaea0927da774cc459ae17c2f065",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 5832,
            "upload_time": "2016-02-26T18:11:33",
            "upload_time_iso_8601": "2016-02-26T18:11:33.804035Z",
            "url": "https://files.pythonhosted.org/packages/77/f1/0aab175d8666c72627235dadd3955683c96aea954e8d2bdbeb3030cec077/nudged-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2016-02-26 18:11:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "axelpale",
    "github_project": "nudged-py",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "tox": true,
    "lcname": "nudged"
}
        
Elapsed time: 0.01909s