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

Uploaded CPython 3.13Windows x86-64

ubicoders_g2opy-2.1.6-cp313-cp313-manylinux_2_39_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.12Windows x86-64

ubicoders_g2opy-2.1.6-cp312-cp312-manylinux_2_39_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.11Windows x86-64

ubicoders_g2opy-2.1.6-cp311-cp311-manylinux_2_39_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.39+ x86-64

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

Uploaded CPython 3.10Windows x86-64

ubicoders_g2opy-2.1.6-cp310-cp310-manylinux_2_39_x86_64.whl (8.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.39+ x86-64

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 5d1aebabcc619a3c6519fd48c841164da6a1c119a099eafc23337047bedcd8cf
MD5 79403940114371f199630139926fb60a
BLAKE2b-256 615752188a2748fc2c4809a0620ab26510c83c28b167f652e158e2a014356d31

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp313-cp313-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 9f7e5901c3c2aff53f73709fb37c15ccb25b34bc57421585da8590f551d847a9
MD5 210a80aefd49f8218777e74b0e669610
BLAKE2b-256 af829998e9e7765b4413df2ef782ad60789d7127c7d3450b5fe0d41d0ec68d02

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6109ff90dc6eaee7a4b5eed2f21f8764c96a99e6355ebf2670ef73765269ce5e
MD5 f174dc6b89329f0b63b4c7b911553f10
BLAKE2b-256 ba893eece392772bb2d2402c214a263cbf0c1ef4b678123e6dfd816b36fc43b5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp312-cp312-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 3fdf28933e64cabb5d8b24f6ea8dbc03b1e1d4a6a1d2e2b0326e5f4f7f50bf91
MD5 c480d448032a4116965c9f174f13af0f
BLAKE2b-256 ba1017981f068382cfbc78fec9a1483046f3a8299049254ae9ee1306933916a9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 8607371bfd8f517c5ee43b374a56cb064130100648605f39b054786520030e41
MD5 399ab09f1a6adabae20bc223ec052d60
BLAKE2b-256 168a0bc3d536a2b493214cba1dafbbfc51ad5067e0ed61948e139fb2f99f2c1c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp311-cp311-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 bf7d410ce7f36e1d528ba7c89290e324ec98ddfff02bf4e96232eb429176534f
MD5 9e93c4c81e9e0867e99b3b971b053eec
BLAKE2b-256 931222d153640e946a79ae2bfba3dd6dff96916e4acfd9b9b8ad7330bd1da57f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 91ab6ca1f102ec397ad929976944cf85b82baf2f05c3bc4e01f1130ba22def9e
MD5 d7b521a1c66403ee59036a5cc04edd9a
BLAKE2b-256 8eec11bf90c59275af8ef614f363173686ec9e1dfca5b5678d78b43787251390

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for ubicoders_g2opy-2.1.6-cp310-cp310-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 7277ec37e9d7e16288e389c778e3029ce04981ca8bcbd89e805d185d505abfcb
MD5 820deba69c423d821f8de1cb5caa9c8f
BLAKE2b-256 d08f09056f5aa6f42e0b810fcbe692b032aab8e8eb0f0cc5a1aab8002e234907

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