Ich habe 3D -Punkte aus der lauten Erkennung einer planaren Oberfläche. Ich möchte für diese Punkte ein orientiertes Begrenzungsfeld einfügen. Ich filtere es ungefähr durch Intensität, um nur Punkte in der Nähe der Kanten zu erhalten. Die Erkennung ist jedoch ziemlich laut Um diese ursprüngliche Schätzung so zu verschieben und zu drehen, so dass sie so viele Grenzpunkte wie möglich passt. Ich bin jedoch Erfahrung mit dem Problem, bei dem ich eine solche Optimierung erstellt habe. Ich verwende scipy.optimize.minimize und das Begrenzungsfeld scheint nur zufällig überall zu überall zu sein, wobei das Endergebnis, das nicht mit der interessierenden Struktur übereinstimmt Bei der ursprünglichen Schätzung, wenn ich die Nicht-Powell-Methode verwende. Sowohl zufälliges Rauschen innerhalb der Struktur + einige benachbarte Struktur;
import open3d as o3d
def generate_noisy_boundary_pcd(center, width, height, depth, margin, noise_level, num_points):
"""
Generate a 3D Open3D point cloud with noisy points only on the boundary of a 3D rectangle.
Args:
center (tuple): Center of the rectangle (x, y, z).
width (float): Width of the rectangle in the X direction.
height (float): Height of the rectangle in the Y direction.
depth (float): Thickness of the rectangle in the Z direction.
margin (float): Thickness of the boundary region to retain.
noise_level (float): Standard deviation of Gaussian noise.
num_points (int): Number of points to generate.
Returns:
open3d.geometry.PointCloud: Open3D point cloud containing only noisy boundary points.
"""
# Generate rectangle points in 3D space
x_vals = np.linspace(-width / 2, width / 2, int(np.sqrt(num_points)))
y_vals = np.linspace(-height / 2, height / 2, int(np.sqrt(num_points)))
x_grid, y_grid = np.meshgrid(x_vals, y_vals)
# Front and back face at ±depth/2
z_front = np.full_like(x_grid, depth / 2)
z_back = np.full_like(x_grid, -depth / 2)
# Create front and back faces
rect_points = np.column_stack((x_grid.ravel(), y_grid.ravel(), z_front.ravel()))
# Filter only boundary points (margin region)
boundary_mask = (
(np.abs(x_grid) >= (width / 2 - margin)) | # Vertical boundary
(np.abs(y_grid) >= (height / 2 - margin)) # Horizontal boundary
)
boundary_points = rect_points[boundary_mask.ravel()]
# Apply noise
noise = np.random.normal(0, noise_level, boundary_points.shape)
noisy_boundary_points = boundary_points + noise
# Shift to the desired center
noisy_boundary_points += np.array(center)
# Convert to Open3D point cloud
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(noisy_boundary_points)
return pcd
# Generate noisy boundary point cloud
pcd_noisy_boundary = generate_noisy_boundary_pcd(center=(0, 0, 0), width=0.8, height=1.0, depth=0.1, margin=0.1, noise_level=0.02, num_points=500)
# Visualize with Open3D
o3d.visualization.draw_geometries([pcd_noisy_boundary])
def apply_random_shift_and_rotation(obb, max_shift=0.05, max_rotation=np.radians(5)):
"""
Apply a small random shift and rotation to an oriented bounding box.
Args:
obb (o3d.geometry.OrientedBoundingBox): The original oriented bounding box.
max_shift (float): Maximum translation shift in each direction.
max_rotation (float): Maximum rotation in radians for each axis.
Returns:
o3d.geometry.OrientedBoundingBox: The transformed OBB.
"""
# Generate a small random shift
shift = np.random.uniform(-max_shift, max_shift, 3)
# Generate small random rotations around each axis
delta_angle_x = np.random.uniform(-max_rotation, max_rotation)
delta_angle_y = np.random.uniform(-max_rotation, max_rotation)
delta_angle_z = np.random.uniform(-max_rotation, max_rotation)
# Compute the new rotation matrix
delta_Rx = o3d.geometry.get_rotation_matrix_from_xyz((delta_angle_x, 0, 0))
delta_Ry = o3d.geometry.get_rotation_matrix_from_xyz((0, delta_angle_y, 0))
delta_Rz = o3d.geometry.get_rotation_matrix_from_xyz((0, 0, delta_angle_z))
# Apply rotation perturbation on top of existing rotation
R_new = obb.R @ (delta_Rz @ delta_Ry @ delta_Rx)
# Apply translation shift
center_new = obb.center + shift
# Create the transformed OBB
transformed_obb = o3d.geometry.OrientedBoundingBox(center_new, R_new, obb.extent)
return transformed_obb
# Compute the initial oriented bounding box from the noisy boundary point cloud
obb_original = o3d.geometry.OrientedBoundingBox.create_from_points(pcd_noisy_boundary.points)
obb_original.color = (1, 0, 0) # Red for original
# Apply random shift and rotation
obb_transformed = apply_random_shift_and_rotation(obb_original)
obb_transformed.color = (0, 1, 0) # Green for transformed
# Visualize both original and transformed bounding boxes
o3d.visualization.draw_geometries([pcd_noisy_with_cluster, obb_original, obb_transformed])
< /code>
Alle oben genannten sind nur Spielzeugdatengenerierung. Unten ist Code, den ich für Optimierung versuche: < /p>
from scipy.optimize import minimize
def fit_obb_to_points(params, pcd, obb, margin=0.1):
"""
Optimize the OBB center and refine its rotation so that it encloses the most points.
Args:
params (list): [cx, cy, cz, delta_angle_x, delta_angle_y, delta_angle_z].
pcd (o3d.geometry.PointCloud): Input 3D point cloud.
obb (o3d.geometry.OrientedBoundingBox): Initial OBB.
expand_factor (float): Factor to expand the bounding box slightly.
Returns:
int: Negative count of points inside the OBB (to be minimized).
"""
# Extract parameters
cx, cy, cz, delta_angle_x, delta_angle_y, delta_angle_z = params
center = np.array([cx, cy, cz])
# Compute refined rotation by applying small delta angles to the existing rotation
delta_Rx = o3d.geometry.get_rotation_matrix_from_xyz((delta_angle_x, 0, 0))
delta_Ry = o3d.geometry.get_rotation_matrix_from_xyz((0, delta_angle_y, 0))
delta_Rz = o3d.geometry.get_rotation_matrix_from_xyz((0, 0, delta_angle_z))
# Apply small rotation adjustments on top of the original OBB rotation
R_new = obb.R @ (delta_Rz @ delta_Ry @ delta_Rx)
expanded_obb = o3d.geometry.OrientedBoundingBox(center, R_new, [obb.extent[0] + margin, obb.extent[1] + margin, obb.extent[2]])
o3d.visualization.draw_geometries([expanded_obb, pcd])
# Count inliers inside both bounding boxes
inliers_large = expanded_obb.get_point_indices_within_bounding_box(pcd.points)
# Compute number of boundary inliers
boundary_inliers = len(inliers_large)
print(boundary_inliers)
return -boundary_inliers
def optimize_bounding_box(pcd, initial_obb):
"""
Adjusts the center and fine-tunes the rotation of the OBB so that it fits as many points as possible.
Args:
pcd (o3d.geometry.PointCloud): The point cloud.
initial_obb (o3d.geometry.OrientedBoundingBox): Initial bounding box (rotation should be preserved).
Returns:
o3d.geometry.OrientedBoundingBox: Optimized OBB.
"""
# Initial parameters: [center_x, center_y, center_z, delta_angle_x, delta_angle_y, delta_angle_z]
initial_params = [
*initial_obb.center,
0, 0, 0 # Start with no change to rotation
]
# Optimize the bounding box parameters
result = minimize(
fit_obb_to_points, initial_params,
args=(pcd, initial_obb),
# method="Powell"
)
# Extract optimized parameters
optimized_center = np.array(result.x[:3])
delta_angles = result.x[3:]
# Compute the final refined rotation
delta_Rx = o3d.geometry.get_rotation_matrix_from_xyz((delta_angles[0], 0, 0))
delta_Ry = o3d.geometry.get_rotation_matrix_from_xyz((0, delta_angles[1], 0))
delta_Rz = o3d.geometry.get_rotation_matrix_from_xyz((0, 0, delta_angles[2]))
optimized_rotation = initial_obb.R @ (delta_Rz @ delta_Ry @ delta_Rx)
# Create the final optimized OBB
optimized_obb = o3d.geometry.OrientedBoundingBox(optimized_center, optimized_rotation, initial_obb.extent)
return optimized_obb
optimized_obb = optimize_bounding_box(pcd_noisy_with_cluster, obb_transformed)
obb_transformed.color = (255, 0, 0)
optimized_obb.color = (0, 255, 0)
o3d.visualization.draw_geometries([pcd_noisy_with_cluster, obb_transformed, optimized_obb])
Wenn Sie o3d.visualisation.draw_geometries ([expanded_obb, pcd]) wie im Optimierungscode hinterlassen, werden Sie feststellen, dass eines der beiden Begrenzungsboxen viel springt, Manchmal ganz ganz von allen Punkten (Powell-Methode) entfernt oder ist nur für eine Nicht-Powell-Methode festgefahren. < /p>
Es scheint klar, dass diese Methode nicht wirklich geeignet ist. Aber ich kann mir keine Alternative vorstellen. Im 2D -Bild würde ich einige Konturfindungsmethoden anwenden, aber ich kann nicht für 3D -Punkte etwas finden. In Open3D gibt es natürlich die Erkennungsmethoden für Flugzeugen. Ich möchte jedoch eine Methode finden, um die Schätzung basierend auf den Open3D < /code> -Methoden zu verfeinern. Ich benutze?
oder wenn es völlig ungeeignet ist, welchen Ansatz soll ich verfolgen?>
Ich habe 3D -Punkte aus der lauten Erkennung einer planaren Oberfläche. Ich möchte für diese Punkte ein orientiertes Begrenzungsfeld einfügen. Ich filtere es ungefähr durch Intensität, um nur Punkte in der Nähe der Kanten zu erhalten. Die Erkennung ist jedoch ziemlich laut Um diese ursprüngliche Schätzung so zu verschieben und zu drehen, so dass sie so viele Grenzpunkte wie möglich passt. Ich bin jedoch Erfahrung mit dem Problem, bei dem ich eine solche Optimierung erstellt habe. Ich verwende scipy.optimize.minimize und das Begrenzungsfeld scheint nur zufällig überall zu überall zu sein, wobei das Endergebnis, das nicht mit der interessierenden Struktur übereinstimmt Bei der ursprünglichen Schätzung, wenn ich die Nicht-Powell-Methode verwende. Sowohl zufälliges Rauschen innerhalb der Struktur + einige benachbarte Struktur;[code]import open3d as o3d
def generate_noisy_boundary_pcd(center, width, height, depth, margin, noise_level, num_points): """ Generate a 3D Open3D point cloud with noisy points only on the boundary of a 3D rectangle.
Args: center (tuple): Center of the rectangle (x, y, z). width (float): Width of the rectangle in the X direction. height (float): Height of the rectangle in the Y direction. depth (float): Thickness of the rectangle in the Z direction. margin (float): Thickness of the boundary region to retain. noise_level (float): Standard deviation of Gaussian noise. num_points (int): Number of points to generate.
Returns: open3d.geometry.PointCloud: Open3D point cloud containing only noisy boundary points. """ # Generate rectangle points in 3D space x_vals = np.linspace(-width / 2, width / 2, int(np.sqrt(num_points))) y_vals = np.linspace(-height / 2, height / 2, int(np.sqrt(num_points))) x_grid, y_grid = np.meshgrid(x_vals, y_vals)
# Front and back face at ±depth/2 z_front = np.full_like(x_grid, depth / 2) z_back = np.full_like(x_grid, -depth / 2)
# Create front and back faces rect_points = np.column_stack((x_grid.ravel(), y_grid.ravel(), z_front.ravel()))
# Visualize with Open3D o3d.visualization.draw_geometries([pcd_noisy_boundary])
def apply_random_shift_and_rotation(obb, max_shift=0.05, max_rotation=np.radians(5)): """ Apply a small random shift and rotation to an oriented bounding box.
Args: obb (o3d.geometry.OrientedBoundingBox): The original oriented bounding box. max_shift (float): Maximum translation shift in each direction. max_rotation (float): Maximum rotation in radians for each axis.
Returns: o3d.geometry.OrientedBoundingBox: The transformed OBB. """ # Generate a small random shift shift = np.random.uniform(-max_shift, max_shift, 3)
# Generate small random rotations around each axis delta_angle_x = np.random.uniform(-max_rotation, max_rotation) delta_angle_y = np.random.uniform(-max_rotation, max_rotation) delta_angle_z = np.random.uniform(-max_rotation, max_rotation)
# Create the transformed OBB transformed_obb = o3d.geometry.OrientedBoundingBox(center_new, R_new, obb.extent)
return transformed_obb
# Compute the initial oriented bounding box from the noisy boundary point cloud obb_original = o3d.geometry.OrientedBoundingBox.create_from_points(pcd_noisy_boundary.points) obb_original.color = (1, 0, 0) # Red for original
# Apply random shift and rotation obb_transformed = apply_random_shift_and_rotation(obb_original) obb_transformed.color = (0, 1, 0) # Green for transformed
# Visualize both original and transformed bounding boxes o3d.visualization.draw_geometries([pcd_noisy_with_cluster, obb_original, obb_transformed]) < /code> Alle oben genannten sind nur Spielzeugdatengenerierung. Unten ist Code, den ich für Optimierung versuche: < /p> from scipy.optimize import minimize
def fit_obb_to_points(params, pcd, obb, margin=0.1): """ Optimize the OBB center and refine its rotation so that it encloses the most points.
Args: params (list): [cx, cy, cz, delta_angle_x, delta_angle_y, delta_angle_z]. pcd (o3d.geometry.PointCloud): Input 3D point cloud. obb (o3d.geometry.OrientedBoundingBox): Initial OBB. expand_factor (float): Factor to expand the bounding box slightly.
Returns: int: Negative count of points inside the OBB (to be minimized). """ # Extract parameters cx, cy, cz, delta_angle_x, delta_angle_y, delta_angle_z = params center = np.array([cx, cy, cz])
# Compute refined rotation by applying small delta angles to the existing rotation delta_Rx = o3d.geometry.get_rotation_matrix_from_xyz((delta_angle_x, 0, 0)) delta_Ry = o3d.geometry.get_rotation_matrix_from_xyz((0, delta_angle_y, 0)) delta_Rz = o3d.geometry.get_rotation_matrix_from_xyz((0, 0, delta_angle_z))
# Apply small rotation adjustments on top of the original OBB rotation R_new = obb.R @ (delta_Rz @ delta_Ry @ delta_Rx)
# Count inliers inside both bounding boxes inliers_large = expanded_obb.get_point_indices_within_bounding_box(pcd.points)
# Compute number of boundary inliers boundary_inliers = len(inliers_large) print(boundary_inliers) return -boundary_inliers
def optimize_bounding_box(pcd, initial_obb): """ Adjusts the center and fine-tunes the rotation of the OBB so that it fits as many points as possible.
Args: pcd (o3d.geometry.PointCloud): The point cloud. initial_obb (o3d.geometry.OrientedBoundingBox): Initial bounding box (rotation should be preserved).
Returns: o3d.geometry.OrientedBoundingBox: Optimized OBB. """ # Initial parameters: [center_x, center_y, center_z, delta_angle_x, delta_angle_y, delta_angle_z] initial_params = [ *initial_obb.center, 0, 0, 0 # Start with no change to rotation ]
# Optimize the bounding box parameters result = minimize( fit_obb_to_points, initial_params, args=(pcd, initial_obb), # method="Powell" )
# Create the final optimized OBB optimized_obb = o3d.geometry.OrientedBoundingBox(optimized_center, optimized_rotation, initial_obb.extent)
return optimized_obb
optimized_obb = optimize_bounding_box(pcd_noisy_with_cluster, obb_transformed) obb_transformed.color = (255, 0, 0) optimized_obb.color = (0, 255, 0) o3d.visualization.draw_geometries([pcd_noisy_with_cluster, obb_transformed, optimized_obb]) [/code] Wenn Sie o3d.visualisation.draw_geometries ([expanded_obb, pcd]) wie im Optimierungscode hinterlassen, werden Sie feststellen, dass eines der beiden Begrenzungsboxen viel springt, Manchmal ganz ganz von allen Punkten (Powell-Methode) entfernt oder ist nur für eine Nicht-Powell-Methode festgefahren. < /p> Es scheint klar, dass diese Methode nicht wirklich geeignet ist. Aber ich kann mir keine Alternative vorstellen. Im 2D -Bild würde ich einige Konturfindungsmethoden anwenden, aber ich kann nicht für 3D -Punkte etwas finden. In Open3D gibt es natürlich die Erkennungsmethoden für Flugzeugen. Ich möchte jedoch eine Methode finden, um die Schätzung basierend auf den Open3D < /code> -Methoden zu verfeinern. Ich benutze? oder wenn es völlig ungeeignet ist, welchen Ansatz soll ich verfolgen?>
Ich habe 3D -Punkte aus der lauten Erkennung einer planaren Oberfläche. Ich möchte für diese Punkte ein orientiertes Begrenzungsfeld einfügen. Ich filtere es ungefähr durch Intensität, um nur Punkte...
Ich versuche, ein MP4 -Video mit
folium.raster_layers.videooverlay () auf eine Folium -Karte zu überlagern. Das Ergebnis ist ein Video, das ich Dyevideo.html nenne. Das Bild erscheint jedoch nicht im...
Vor kurzem wollte ich mit Panda3D mit Python ein 3D -Testerspiel mit Pandhon machen. Ich kann jedoch nicht die Mausrotation in der Umgebung nachahmen, die andere beliebte Spiele aus der ersten Person...
Ich versuche, 10 GameObject zu instanziieren, und dafür habe ich ein Array, das ihre Position und Rotation speichert. Die Funktion mazestart () wählt zufällig die Koordinaten und die Rotation aus dem...
Ich versuche, die Zoomfunktion für eine Anwendung zu implementieren, die Formen auf dem Bildschirm zeichnet. Diese Formen werden in Millimetern erstellt, die je nach dpi-Wert in Pixel umgewandelt...