openGL+open3d+python 鼠标拖动画矩形框选出点云数据的感兴趣区域代码
时间: 2023-07-14 20:11:43 浏览: 108
以下是一个基于Open3D和PyOpenGL的示例代码,演示如何使用鼠标拖动矩形框来选择点云数据的感兴趣区域:
```python
import open3d as o3d
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import numpy as np
# 用于存储点云数据的全局变量
pcd = None
# 定义矩形框的起点和终点坐标
start_x, start_y, end_x, end_y = 0, 0, 0, 0
# OpenGL 窗口宽度和高度
window_width, window_height = 640, 480
def init():
# 初始化窗口和 OpenGL 环境
glutInit()
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(window_width, window_height)
glutCreateWindow("Select Point Cloud ROI")
# 注册回调函数
glutDisplayFunc(display)
glutKeyboardFunc(keyboard)
glutMouseFunc(mouse)
glutMotionFunc(motion)
# 设置 OpenGL 渲染模式和深度测试
glShadeModel(GL_SMOOTH)
glEnable(GL_DEPTH_TEST)
def display():
global pcd
# 清除屏幕和深度缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# 如果有点云数据就显示
if pcd is not None:
# 设置 OpenGL 投影矩阵
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, window_width / window_height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
# 设置 OpenGL 模型视图矩阵
glLoadIdentity()
gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0)
# 绘制点云数据
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_POINTS)
for point in np.asarray(pcd.points):
glVertex3f(point[0], point[1], point[2])
glEnd()
# 绘制矩形框
if start_x != end_x and start_y != end_y:
glColor3f(0.0, 1.0, 0.0)
glLineWidth(2)
glBegin(GL_LINE_LOOP)
glVertex3f(start_x, start_y, 0)
glVertex3f(end_x, start_y, 0)
glVertex3f(end_x, end_y, 0)
glVertex3f(start_x, end_y, 0)
glEnd()
glutSwapBuffers()
def keyboard(key, x, y):
# 按下 ESC 键退出程序
if key == chr(27):
sys.exit(0)
def mouse(button, state, x, y):
global start_x, start_y, end_x, end_y, pcd
if button == GLUT_LEFT_BUTTON:
if state == GLUT_DOWN:
start_x, start_y = x, y
elif state == GLUT_UP:
# 使用 Open3D 进行点云数据截取
bbox = o3d.geometry.AxisAlignedBoundingBox.from_points(
pcd.select_down_sample(np.array([[start_x, start_y], [end_x, end_y]])).points)
pcd_crop = pcd.crop(bbox)
# 显示裁剪后的点云数据
global window_width, window_height
window_width, window_height = 640, 480
pcd = pcd_crop
glutReshapeWindow(window_width, window_height)
def motion(x, y):
global end_x, end_y
end_x, end_y = x, y
glutPostRedisplay()
if __name__ == '__main__':
# 读取点云数据
pcd = o3d.io.read_point_cloud("point_cloud.pcd")
# 初始化 OpenGL 窗口和环境
init()
# 进入 OpenGL 主循环
glutMainLoop()
```
在代码中,我们使用了 `o3d.geometry.AxisAlignedBoundingBox.from_points()` 函数将矩形框转换为 Open3D 中的 AxisAlignedBoundingBox 对象,并使用 `pcd.crop()` 函数对原始点云数据进行截取操作,得到裁剪后的点云数据。裁剪后的点云数据将替代原始点云数据,并在窗口中显示。