Rotieren PointCloud um die Z-Achse in open3d. Error "incompatible function arguments"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Dan88
User
Beiträge: 9
Registriert: Mittwoch 22. Januar 2020, 18:39

hallo zusammen,

Ich möchte eine Punktwolke um die Z-Achse drehen und habe dafür die folgende Methode geschrieben:

Code: Alles auswählen

 
def rotate_Geometry(pcd,is_pointcloud=True):

#Rotationsmatrix um die Z-Achse


  alpha = m.radians(angle_against_true_north)
  #rotation Matrix for Z-Axis
  rotationMatrix = [[m.cos(alpha),-m.sin(alpha)],
                      [m.sin(alpha), m.cos(alpha),0],
                      [0,0,1]]

  print(rotationMatrix)

#Rotate Pointcloud
  if is_pointcloud == True:
    print("Es wird ein PointCloud()-Objekt verarbeitet")
    pcd_rotate = o3d.geometry.PointCloud.rotate(pcd,rotationMatrix,center=True)

    return pcd_rotate,angle_against_true_north

#Rotate Points_np.shape()
  if is_pointcloud == False:
    print("Keine Punktwolke als Input")
 
die Methode wird folgendermaßen aufgerufen:

Code: Alles auswählen

#Imports

import open3d as o3d
import numpy as np
import pandas as pd
import math as m


# Randam Numpy-Array for testing
x = np.linspace(-3, 3, 401)
mesh_x, mesh_y = np.meshgrid(x, x)
z = np.sinc((np.power(mesh_x, 2) + np.power(mesh_y, 2)))
z_norm = (z - z.min()) / (z.max() - z.min())
xyz = np.zeros((np.size(mesh_x), 3))
xyz[:, 0] = np.reshape(mesh_x, -1)
xyz[:, 1] = np.reshape(mesh_y, -1)
xyz[:, 2] = np.reshape(z_norm, -1)
print('xyz')
print(xyz)

pcd_test = o3d.geometry.PointCloud()
pcd_test.points = o3d.utility.Vector3dVector(xyz)
print(pcd_test)
pcd_rotate, alpha = rotate_Geometry(pcd_test,is_pointcloud=True)

#Save Cropped PointCloud 
path_outcloud = ('/gdrive/My Drive/Colab Notebooks/Georeferenzierung/CropPointCloud/PointCloud/pcd_rotate_{}.pcd'.format(alpha))
o3d.io.write_point_cloud(path_outcloud, pcd_rotate)
ich erhalte dabei folgende Fehlermeldung:

Code: Alles auswählen

[[0.5417082102827399, -0.8405666034956842], [0.8405666034956842, 0.5417082102827399, 0], [0, 0, 1]]
Es wird ein PointCloud()-Objekt verarbeitet

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-262-a72bd2c346d8> in <module>()
      3 pcd_offground = pcd_offground.voxel_down_sample(voxel_size=0.05)
      4 #print(pcd_offground)
----> 5 pcd_rotate, alpha = rotate_Geometry(pcd_test,is_pointcloud=True)
      6 #Save Cropped PointCloud
      7 path_outcloud = ('/gdrive/My Drive/Colab Notebooks/Georeferenzierung/CropPointCloud/PointCloud/pcd_rotate_{}.pcd'.format(alpha))

<ipython-input-244-32aa39b15edc> in rotate_Geometry(pcd, is_pointcloud)
     15     if is_pointcloud == True:
     16       print("Es wird ein PointCloud()-Objekt verarbeitet")
---> 17       pcd_rotate = o3d.geometry.PointCloud.rotate(pcd,rotationMatrix,center=True)
     18 
     19       return pcd_rotate,angle_against_true_north

TypeError: rotate(): incompatible function arguments. The following argument types are supported:
    1. (self: open3d.open3d.geometry.Geometry3D, R: numpy.ndarray[float64[3, 3]], center: bool = True) -> open3d.open3d.geometry.Geometry3D

Invoked with: geometry::PointCloud with 160801 points., [[0.5417082102827399, -0.8405666034956842], [0.8405666034956842, 0.5417082102827399, 0], [0, 0, 1]]; kwargs: center=True

Ich verstehe nicht, warum ich eine Fehlermeldung erhalte. Ich übergebe ein Geometrieobjekt. Es hat bisher immer funktioniert und keine Probleme verursacht. Ich weiß nicht, was ich versehentlich geändert habe.

Für Anregungen bin ich dankbar.

Grüsse
Dan
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Das `is_pointcloud`-Argument ist ziemlich unsinnig. Entweder es ist eine Pointcloud, dann hat sie auch eine rotate-Methode oder es ist keine, dann hilft auch die Angabe eines zusätzlichen Arguments nichts.
Apropos Methode: Man ruft Methoden nicht über die Klasse auf, sondern direkt in über die Instanz. Funktionen schreibt man wie Variablennamen komplett klein. Der Funktion `rotate_Geometry fehlt das `angle_against_true_north`-Argument. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht 2. `math` schreibt man aus, und kürzt es nicht mit `m` ab. Der ersten Zeile von `rotation_matrix` fehlt ein dritter Wert. Einen Wert, den man als Argument bekommt (bekommen sollte) braucht man nicht zurückgeben.

Code: Alles auswählen

def rotate_geometry(pcd, angle_against_true_north):
    #Rotationsmatrix um die Z-Achse
    alpha = math.radians(angle_against_true_north)
    rotation_matrix = [[math.cos(alpha), -math.sin(alpha), 0],
                      [math.sin(alpha),  math.cos(alpha), 0],
                      [0,0,1]]
    pcd_rotate = pcd.rotate(rotation_matrix, center=True)
    return pcd_rotate
Dan88
User
Beiträge: 9
Registriert: Mittwoch 22. Januar 2020, 18:39

Hallo Sirius,

danke für deine Antwort.

ich möchte die Methode noch erweitern so das auch numpy arrays verarbeitet werden können, deshalb is dieses Argument dabei.

ich programmiere erst seit 6 Monaten und bin noch Änfänger. Ich bin leider gezwungen über google colab und jupyter notebook zu arbeiten. Da fällt mir das Debuggen schwer.

Danke für deine Tipps. Ich werde diese zukünftig aufjedenfall beherzigen. Wie man Methoden aufruft muss ich mir nochmal genauer anschauen.

gruß
Dan
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Dan88 hat geschrieben: Mittwoch 3. Juni 2020, 07:01 ich möchte die Methode noch erweitern so das auch numpy arrays verarbeitet werden können, deshalb is dieses Argument dabei.
Auch dann ist es nicht richtig, ein zusätzliches Argument zu übergeben. Der richtige Weg wäre es, zu prüfen, ob das übergebene Objekt eine `rotate`-Methode hat und falls nicht auf numpy.dot zurückzufallen.
Antworten