openGL+open3d+python 鼠标拖动画矩形框选出点云数据的感兴趣区域代码
时间: 2023-06-25 18:07:04 浏览: 232
OpenGL-3D框选.rar_3d opengl_3d点云_opengl_任意角度框选_框选点云
5星 · 资源好评率100%
下面是一个简单的示例代码,它使用OpenGL和Open3D库来实现鼠标拖动画矩形框,并选择点云数据中的感兴趣区域。您可以根据自己的需求进行修改和扩展。
```python
import glfw
from OpenGL.GL import *
from OpenGL.GLU import *
import open3d as o3d
import numpy as np
# 定义顶点坐标、颜色和法向量
vertices = np.array([
[-0.5, -0.5, 0.0],
[0.5, -0.5, 0.0],
[0.5, 0.5, 0.0],
[-0.5, 0.5, 0.0]
], dtype=np.float32)
colors = np.array([
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 1.0, 0.0]
], dtype=np.float32)
normals = np.array([
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0]
], dtype=np.float32)
# 定义顶点索引
indices = np.array([
[0, 1, 2],
[2, 3, 0]
], dtype=np.uint32)
# 创建一个窗口
def create_window(width, height):
if not glfw.init():
return None
glfw.window_hint(glfw.SAMPLES, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
window = glfw.create_window(width, height, "Select points", None, None)
if not window:
glfw.terminate()
return None
glfw.make_context_current(window)
glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_NORMAL)
glfw.set_cursor_pos_callback(window, cursor_pos_callback)
glfw.set_mouse_button_callback(window, mouse_button_callback)
return window
# 绘制矩形框
def draw_rect(x1, y1, x2, y2):
glLoadIdentity()
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
gluOrtho2D(0, 800, 600, 0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glDisable(GL_DEPTH_TEST)
glDisable(GL_LIGHTING)
glColor3f(1.0, 0.0, 0.0)
glBegin(GL_LINE_LOOP)
glVertex2f(x1, y1)
glVertex2f(x2, y1)
glVertex2f(x2, y2)
glVertex2f(x1, y2)
glEnd()
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
# 鼠标按下时记录起始坐标和标志位
def mouse_button_callback(window, button, action, mods):
global g_mouse_pressing, g_mouse_x1, g_mouse_y1, g_mouse_x2, g_mouse_y2
if button == glfw.MOUSE_BUTTON_LEFT and action == glfw.PRESS:
g_mouse_pressing = True
x, y = glfw.get_cursor_pos(window)
g_mouse_x1, g_mouse_y1 = x, y
g_mouse_x2, g_mouse_y2 = x, y
elif button == glfw.MOUSE_BUTTON_LEFT and action == glfw.RELEASE:
g_mouse_pressing = False
x, y = glfw.get_cursor_pos(window)
g_mouse_x2, g_mouse_y2 = x, y
# 鼠标移动时更新矩形框坐标并选择点云数据
def cursor_pos_callback(window, x, y):
global g_mouse_x2, g_mouse_y2
if g_mouse_pressing:
g_mouse_x2, g_mouse_y2 = x, y
width, height = glfw.get_window_size(window)
y = height - y
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width) / height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0)
# 绘制矩形框
draw_rect(g_mouse_x1, g_mouse_y1, g_mouse_x2, g_mouse_y2)
# 选择点云数据
rect = np.array([[g_mouse_x1, y], [g_mouse_x2, y], [g_mouse_x2, g_mouse_y2], [g_mouse_x1, g_mouse_y2]])
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(vertices)
pcd.colors = o3d.utility.Vector3dVector(colors)
pcd.normals = o3d.utility.Vector3dVector(normals)
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
points = []
for i in range(4):
_, idx, _ = pcd_tree.search_knn_vector_3d(rect[i], 1)
points.append(idx[0])
selected_pcd = pcd.select_down_sample(points)
# 绘制点云数据
glPointSize(5.0)
glBegin(GL_POINTS)
for i in range(len(selected_pcd.points)):
glColor3f(selected_pcd.colors[i][0], selected_pcd.colors[i][1], selected_pcd.colors[i][2])
glVertex3f(selected_pcd.points[i][0], selected_pcd.points[i][1], selected_pcd.points[i][2])
glEnd()
# 主函数
def main():
window = create_window(800, 600)
if not window:
return
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glShadeModel(GL_SMOOTH)
while not glfw.window_should_close(window):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glClearColor(0.0, 0.0, 0.0, 1.0)
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glVertexPointer(3, GL_FLOAT, 0, vertices)
glColorPointer(3, GL_FLOAT, 0, colors)
glNormalPointer(GL_FLOAT, 0, normals)
glDrawElements(GL_TRIANGLES, len(indices.flatten()), GL_UNSIGNED_INT, indices.flatten())
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
glfw.swap_buffers(window)
glfw.poll_events()
glfw.terminate()
if __name__ == '__main__':
main()
```
在运行该代码时,您可以使用鼠标左键点击并拖动以绘制矩形框,并选择点云数据中的感兴趣区域。
阅读全文