Skip to main content

g2o: A General Framework for Graph Optimization (Python bindings)

Project description

g2o - General Graph Optimization

Ubicoders g2opy edition

Static Badge Static Badge Static Badge Static Badge

This project is based on the original g2o maintainer as below.

This porject provide windows and linux off the shelf packge including the .dll and .so files as well as the types of the apis for intellisense.

Otherthan that, same as g2o's pymem branch

Latest Commit base:

  • 70f058fde4516505ecb3b392b25bd66b2f4fdf47 (Sep 21, 2025)

How it works

Built the .whl with the damn .dll and .so files for god xxxxing sake.

The pip packge name is pyg2o. But import with import g2opy as g2o

Intellisense Enhanced

sample1

sample2

Supported Python Versions

  • 3.10 ✅
  • 3.11 ✅
  • 3.12 ✅
  • 3.13 ✅

Supproted Numpy Version

  • numpy 1 ⬜
  • numpy 2 ✅

Tested OS and Python

  • Windows 11 ✅
  • Ubuntu 20 ⬜
  • Ubuntu 22 ⬜
  • Ubuntu 24 ✅
  • Ubuntu 25 ✅

ubuntu dependencies

sudo apt-get install -qq qtdeclarative5-dev qt5-qmake libqglviewer-dev-qt5 libsuitesparse-dev libeigen3-dev -y
pip install "numpy>=2.0"

For the new conda env

conda install -y -c conda-forge "libstdcxx-ng>=12" "libgcc-ng>=12" libgomp

Test the installaton

import numpy as np
import g2opy as g2o
np.set_printoptions(precision=3)
np.set_printoptions(suppress=True)
from collections import defaultdict

def showCameraPoses(optim, idx, N):
    for i in range(idx, idx + N):
        T = optim.vertex(i).estimate().matrix()
        trans = T[:3, 3]
        print('camera pose at ', i, ': ', trans)

def calcSSE(optim, idx, wPts):
    sse = 0
    N = wPts.shape[0]
    for i in range(idx, idx + N):
        guessedWpt = optim.vertex(i)
        error = guessedWpt.estimate() - wPts[i-idx]
        sse += np.sum(error ** 2)
    return sse

def showWpts(optim, idx, N):
    for i in range(idx, idx + N):
        T = optim.vertex(i).estimate()
        #T = np.round(T, 0)
        print('guessed wPt at ', i-idx, ': ', T)

def main():   
    optimizer = g2o.SparseOptimizer()
    solver = g2o.BlockSolverSE3(g2o.LinearSolverCSparseSE3())
    solver = g2o.OptimizationAlgorithmLevenberg(solver)
    optimizer.set_algorithm(solver)

    f, p = 200, 256
    baseline = 0.3
    K = np.array([[f, 0, p],
                  [0, f, p],
                  [0, 0, 1]])

    wPts = np.array([
        [0, 0, 10],
        [-1, 3, 30],
        [2, 2, 37.2],
    ])

    num_pose = 10
    for i in range(0, int(num_pose/2)):
        pose = g2o.Isometry3d(np.identity(3), [(i-2)*10, 0, 0])
        v_se3 = g2o.VertexSCam()
        v_se3.set_cam(f, f, p, p, baseline)
        v_se3.set_id(i)
        v_se3.set_estimate(pose)
        if i < 2:
            v_se3.set_fixed(True)
        v_se3.set_all() # sets transfrom, projection, dR (angle)
        optimizer.add_vertex(v_se3)

    for i in range(int(num_pose/2), num_pose):
        pose = g2o.Isometry3d(np.identity(3), [0, (i - int(num_pose/2)- 2) * 10, 0])
        v_se3 = g2o.VertexSCam()
        v_se3.set_cam(f, f, p, p, baseline)
        v_se3.set_id(i)
        v_se3.set_estimate(pose)
        v_se3.set_fixed(False)
        v_se3.set_all() # sets transfrom, projection, dR (angle)
        optimizer.add_vertex(v_se3)

    point_id = 0

    for i, wpt in enumerate(wPts):
        guessed_wPt = g2o.VertexPointXYZ()
        guessed_wPt.set_id(num_pose + point_id)
        guessed_wPt.set_marginalized(True)
        guessed_wPt.set_estimate(wpt + np.random.randn(3) )
        optimizer.add_vertex(guessed_wPt)

        for j in range(num_pose):
            z = optimizer.vertex(j).map_point(wpt)
            if i > 1:
                z +=  np.random.randn(3)
            edge = g2o.EdgeXyzVsc()
            edge.set_vertex(0, guessed_wPt)
            edge.set_vertex(1, optimizer.vertex(j))
            edge.set_measurement(z)
            edge.set_information(np.identity(3))
            optimizer.add_edge(edge)

        point_id += 1

    sse0 = calcSSE(optimizer, num_pose, wPts)
    print('\nRMSE (inliers only):')
    print('before optimization:', np.sqrt(sse0 / wPts.shape[0]))
    showCameraPoses(optimizer, 0, num_pose)
    showWpts(optimizer, num_pose, 3)


    print('Performing full BA:')
    optimizer.initialize_optimization()
    optimizer.set_verbose(False)
    optimizer.optimize(100)

    sse1 = calcSSE(optimizer, num_pose, wPts)

    print('\nRMSE (inliers only):')
    print('after  optimization:', np.sqrt(sse1 / wPts.shape[0]))
    showCameraPoses(optimizer, 0, num_pose)
    showWpts(optimizer, num_pose, 3)


if __name__ == '__main__':
    main()

see the orignal readme at https://github.com/RainerKuemmerle/g2o

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ubicoders_g2opy-2.1.3-cp313-cp313-win_amd64.whl (19.3 MB view details)

Uploaded CPython 3.13Windows x86-64

ubicoders_g2opy-2.1.3-cp313-cp313-manylinux_2_39_x86_64.whl (23.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.39+ x86-64

ubicoders_g2opy-2.1.3-cp312-cp312-win_amd64.whl (19.3 MB view details)

Uploaded CPython 3.12Windows x86-64

ubicoders_g2opy-2.1.3-cp312-cp312-manylinux_2_39_x86_64.whl (23.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.39+ x86-64

ubicoders_g2opy-2.1.3-cp311-cp311-win_amd64.whl (19.3 MB view details)

Uploaded CPython 3.11Windows x86-64

ubicoders_g2opy-2.1.3-cp311-cp311-manylinux_2_39_x86_64.whl (23.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.39+ x86-64

ubicoders_g2opy-2.1.3-cp310-cp310-win_amd64.whl (19.3 MB view details)

Uploaded CPython 3.10Windows x86-64

ubicoders_g2opy-2.1.3-cp310-cp310-manylinux_2_39_x86_64.whl (23.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.39+ x86-64

File details

Details for the file ubicoders_g2opy-2.1.3-cp313-cp313-win_amd64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 fdf22317730041cc47a48d4667860f36f8684bea03440a518009dd74aef12060
MD5 73eb5caa02f31cd41dbda048f658a62b
BLAKE2b-256 e38cfc97538ca8bcc39f3b5584efa73c1d0329d15456dd1891a843bd06d3c4cc

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp313-cp313-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp313-cp313-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 6a456210fd5994dd228349bacdb1cdb530c126fb73528b3f0e5164c55438d848
MD5 be46c22e643f3a286f469cae6a337a27
BLAKE2b-256 7c35ee2ac303649d74b572580e83d2b217784cd66bf749a8a0e9ddc3286188b9

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 5e4d0dd6b8ca15826b95f8fd45bc09df5df6d3002dcca6f2c55b2e7ee32fc40d
MD5 9955bced30b27a775eca74de4a14c91d
BLAKE2b-256 7100cb8146d255ee81e77e4657480eed983271141f7783940d32541a2a6392fc

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp312-cp312-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp312-cp312-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 699b6387fa34e95ea7c354da1d207b73b4bcd52bea1aa63703a7e634f959f735
MD5 da7508cec78b66c9667e961da53ef4b5
BLAKE2b-256 0e17e2c842a0c6561528d2e5154536b71b2a62a2f8d179f18152bbda41e2cb78

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 66fc5e440ea9f93cdb10be2c61a03c6367008855a68369d945416ea0c37ba5a0
MD5 34c142f4519f25578372ea22a4369ed0
BLAKE2b-256 e390f7b8b11b85a7eb50c4a042f76938dfc10dcc1043acc3888e20d8448ab125

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp311-cp311-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp311-cp311-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 8462523b9c5acd99e04d3c6abba6f86914dfa10605c569bc5e2dc50efda61745
MD5 3386a3c62403206ffbd4b10c0ae0c2ae
BLAKE2b-256 6a06b114de5dcb08557578b3655d7a3dd2ed85f1712be1d4a20dd552732a1813

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 5d0d0b6317683036cf5456f358bc16307f52ce5b0e2ee5145dfcd801d5eacb92
MD5 c5fe0a5a85541e2d40182811b48fd540
BLAKE2b-256 886dedd76b20ed3add82018aab5cd6a20c7433347c999265133cff8562713c6f

See more details on using hashes here.

File details

Details for the file ubicoders_g2opy-2.1.3-cp310-cp310-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.3-cp310-cp310-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 77b75682e60ed7f9711b330b6852e5a69889a5b3848439754d432e0e3f603cf8
MD5 1ca9497c1fd8c22e4bd4a25f2f4c0cd9
BLAKE2b-256 f458e752adbdee81996cf73e85217046c5ebbabd22146f743ef86aeac6cf265d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page