Hierarchical-Localization icon indicating copy to clipboard operation
Hierarchical-Localization copied to clipboard

Exception in triangulation: 'pycolmap._core.Rigid3d' object has no attribute 'essential_matrix'

Open mattiasmar opened this issue 1 year ago • 5 comments

In an Ubuntu 22 docker container with COLMAP, PyColmap and HLOC installed from sources like documented below, in the method:

def compute_epipolar_errors(j_from_i: pycolmap.Rigid3d, p2d_i, p2d_j):
    j_E_i = j_from_i.essential_matrix()  

I get the exception:

Exception has occurred: AttributeError
'pycolmap._core.Rigid3d' object has no attribute 'essential_matrix'
  File "/hloc/Hierarchical-Localization/hloc/utils/geometry.py", line 10, in compute_epipolar_errors
    j_E_i = j_from_i.essential_matrix()
  File "/hloc/Hierarchical-Localization/hloc/triangulation.py", line 174, in geometric_verification
    errors0, errors1 = compute_epipolar_errors(
  File "/hloc/Hierarchical-Localization/hloc/triangulation.py", line 253, in main
    geometric_verification(
  ...
AttributeError: 'pycolmap._core.Rigid3d' object has no attribute 'essential_matrix'

Should I use another version of pycolmap (latest sources brings me pycolmap: 3.11.0, colmap: 3.11.0.dev0, Commit 9da34b21 on 2024-11-26 with CUDA)? Am I using hloc triangulation incorrectly?

I'm using it like this:

    # Step 3: Perform triangulation using the existing camera poses
    triangulation.main(
        reference_model=reconstruction_path,
        sfm_dir = sfm_path,
        image_dir=Path(output_dir),
        pairs=sfm_pairs,
        features=features_path,
        matches=matches_path,
        verbose = True
    )

where all of those paths point to this folder structure: image

WORKDIR /colmap
RUN git clone https://github.com/colmap/colmap.git 
RUN . /hloc/venv/bin/activate && cd colmap && mkdir build && cd build && cmake .. -GNinja  && ninja && ninja install
# Install the latest version of pycolmap
RUN . /hloc/venv/bin/activate && pip install ruff pyyaml
RUN . /hloc/venv/bin/activate && cd /colmap/colmap && python3 -m pip install ./pycolmap/

WORKDIR /hloc
RUN git clone --recursive https://github.com/cvg/Hierarchical-Localization/
RUN . /hloc/venv/bin/activate &&  cd Hierarchical-Localization/ && python3 -m pip install --upgrade setuptools && python3 -m pip install --no-build-isolation -e .

In debugger I see that this method fails at the first call and the input arguments are

j_from_i: pycolmap.Rigid3d, rotation_xyzw=[0.118801, -0.399306, 0.0515654, 0.907624], translation=[1.80276, 0.0961467, -2.12249])
p2d_j: <class 'numpy.ndarray'>, shape: (74, 2)
p2d_i: <class 'numpy.ndarray'>, shape: (74, 2)

mattiasmar avatar Nov 26 '24 11:11 mattiasmar

@sarlinpe This happens every time I call triangulation.main.

triangulation.main(
              reference_model=initial_sfm_model,
              sfm_dir = sfm_path,
              image_dir=Path(output_dir),
              pairs=sfm_pairs,
              features=features_path,
              matches=matches_path,
              verbose = False,
              skip_geometric_verification = False
          )

mattiasmar avatar Dec 11 '24 11:12 mattiasmar

May I suggest replacing the line j_E_i = j_from_i.essential_matrix() in compute_epipolar_errors as follows:

def compute_epipolar_errors(j_from_i: pycolmap.Rigid3d, p2d_i, p2d_j):
    # Extract rotation and translation from j_from_i
    R = j_from_i.rotation.matrix()
    t = j_from_i.translation

    # Compute the essential matrix
    t_e = np.array([
        [0, -t[2], t[1]],
        [t[2], 0, -t[0]],
        [-t[1], t[0], 0]
    ])
    j_E_i = t_e @ R
    ...

mattiasmar avatar Dec 11 '24 11:12 mattiasmar

Downgrade pycolmap to 3.10.0

shojint avatar Dec 12 '24 04:12 shojint

Not working in my case, the downgraded version gives a new error:vhttps://github.com/colmap/pycolmap/issues/289

my python version==3.9.0,pycolmap==3.10.0, this configuration works

warriorstx avatar Apr 28 '25 01:04 warriorstx

according to the changelog of 3.11.1 document: Rigid3d.essential_matrix becomes pycolmap.essential_matrix_from_pose.

pycolmap.essential_matrix_from_pose(cam2_from_cam1: pycolmap.Rigid3d)→ numpy.ndarray[numpy.float64[3, 3]]

May I suggest replacing the line j_E_i = j_from_i.essential_matrix() in compute_epipolar_errors as follows:

j_E_i = pycolmap.essential_matrix_from_pose(j_from_i)

willgan916 avatar May 31 '25 00:05 willgan916

according to the changelog of 3.11.1 document: Rigid3d.essential_matrix becomes pycolmap.essential_matrix_from_pose.

pycolmap.essential_matrix_from_pose(cam2_from_cam1: pycolmap.Rigid3d)→ numpy.ndarray[numpy.float64[3, 3]]

May I suggest replacing the line j_E_i = j_from_i.essential_matrix() in compute_epipolar_errors as follows:

j_E_i = pycolmap.essential_matrix_from_pose(j_from_i)

Thank you very much!!!!!!!!!! you are my hero!!!!!!!!!

hfwuyanzu avatar Jul 30 '25 05:07 hfwuyanzu