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

ubuntu install

sudo apt-get install -qq qtdeclarative5-dev qt5-qmake libqglviewer-dev-qt5 libsuitesparse-dev libeigen3-dev -y

For the new conda env

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

Then, install this package

pip install ubicoders-g2opy

windows dependencies

just do

pip install ubicoders-g2opy

intro

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 ✅

Test the installaton

create below and run

python tester.py

tester.py

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.5-cp313-cp313-win_amd64.whl (19.3 MB view details)

Uploaded CPython 3.13Windows x86-64

ubicoders_g2opy-2.1.5-cp313-cp313-manylinux_2_39_x86_64.whl (27.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.12Windows x86-64

ubicoders_g2opy-2.1.5-cp312-cp312-manylinux_2_39_x86_64.whl (27.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.11Windows x86-64

ubicoders_g2opy-2.1.5-cp311-cp311-manylinux_2_39_x86_64.whl (27.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.10Windows x86-64

ubicoders_g2opy-2.1.5-cp310-cp310-manylinux_2_39_x86_64.whl (27.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.39+ x86-64

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 030032406365a6afbf05d541cc75b6305bcb5bac7dd9a35eac8c100627b5e227
MD5 903aacad33ce4a03abf06e517a00c227
BLAKE2b-256 2bd5215cbce781f0fc7cfd4f0de43f7b77060ad2f41fcca03fdb547a2465467f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp313-cp313-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 c71dce2e40da0646434b38e8878be884dbfeaa89c15e11a121c26a3f1f532822
MD5 1b456274272a331eebe65ce63233d239
BLAKE2b-256 9c37a97b8e8b3d5495e5fd743d8155b42b8e991cfefa39cc07bd8b533703b738

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 4469e0dc6bf33f89abe55d4217c2fb9b91568422295e2495ccd8f84e6a3448fe
MD5 a0af963ab897ac457923f278ecdef834
BLAKE2b-256 bc0d1678e4086659bc3e459c128f2c8100b3a1ef75096db8d3476fc648006c43

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp312-cp312-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 094c60857c8e46ba9605693898052f7728349d3e62509493fda8cc4b3fdc57ba
MD5 a277711e92e17504718112727661b521
BLAKE2b-256 3d07e6b82163baa1632c222edfe6c7e6178a3389889c735dccc019f4524871c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 190f983c9ccdbdc5997c1137ebb1829391c21f865c45bac6af1690051991e3c7
MD5 9e2e59d6f75829cecf313562de567c6f
BLAKE2b-256 7ddd5e6f023d0c2852a280cbbe1747729996ff15bf4ac2992597ff66698817cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp311-cp311-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 62abc963c018d2105bcc5bbc8b45ac45c33b1e2af8ee8880d431b0d44ebc711b
MD5 96f59f444de3114c2f2d5da615b3b46d
BLAKE2b-256 38dc9baff65055ce910db416338c892d4c7c7f5f48cb591a739fb69bf166d86c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 64b0a212268fc6aa78367e2b314ab2fdee65163b69556ac50bb07a294ce2a335
MD5 bced250b2c3d7e14147fa47c5a676ecb
BLAKE2b-256 c9b9c823c8b874ae9bab71008252ee92a9d6312dd4c40e60d043d84babd0bbc7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.5-cp310-cp310-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 2dc23479186234f88defa385cd9762fbbcabaeed8a2083a58f329027e31b03f0
MD5 612d7fe3446aae024de59b1276ac2dda
BLAKE2b-256 2334850b88c7c09d26a5906e4a63190d0f3df3a91b512a4de1766fd7b2dd0146

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