Lab-open3d可视化界面自定义关闭时间

Open3d可视化界面自定义关闭时间

参考代码的链接
Open3d之非阻塞可视化
oepn3d python 读取python文件获取指定视角并自动旋转

自定义关闭时间

  • 效果:替代o3d.visualization.draw_geometries([pcd])函数,但可设置窗口保持时间,不需要手动关闭

    def visPcd(pcd): # 需要open3d,time库,默认暂停2秒,暂停时间在函数内设置
        # 创建可视化窗口并显示pcd
        vis = o3d.visualization.Visualizer()
        vis.create_window()
        vis.add_geometry(pcd)
        vis.poll_events()
        vis.update_renderer()
        # 设置窗口存在时间,根据需要自行更改
        time.sleep(2)
        # 关闭窗口
        vis.destroy_window()
    
    • 存在限制:无法对窗口进一步操作(例如调整角度等)

在程序主线程运行的同时,自定义可视化窗口保持时间

  • 开发背景:要求在一个循环里,每次循环都读取一个pcd文件,对其进行处理的同时,展示该pcd文件一定时间

    # 主副线程都可执行 函数整合版
    # 主副线程都可执行
    import threading
    import time
    import inspect
    import ctypes
    import open3d as o3d
    
    def _async_raise(tid, exctype):
        """raises the exception, performs cleanup if needed"""
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble,
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")
    
    
    def stop_thread(thread):
        _async_raise(thread.ident, SystemExit)
    
    def visPcd(pcd): # 需要open3d,time库,默认暂停2秒,暂停时间在函数内设置
        # 创建可视化窗口并显示pcd
        vis = o3d.visualization.Visualizer()
        vis.create_window()
        vis.add_geometry(pcd)
        vis.poll_events()
        vis.update_renderer()
        # 设置窗口存在时间,根据需要自行更改
        time.sleep(2)
        # 关闭窗口
        vis.destroy_window()
    
    class TestThread(threading.Thread):
        def run(self):
            print("副线程开始")
            while True:
                # time.sleep(0.1)
                # print("副线程 进行中")
                visPcd(pcd)
    
    def visOpen3d_Noblockmain(pcd): # 要调用此函数,需先定义TestThread这个class以及visPcd(pcd)/stop_thread(thread)/_async_raise(tid, exctype)这三个函数
        t=TestThread()
        t.start()
    
        '''
            当设置的线程开始和结束的时间差小于visPcd(pcd)函数里的界面保留时间时,界面保留时间即visPcd(pcd)里设置的时间,不受该参数影响,
        推测运行stop_thread(t)时,在TestThread这个类里的run函数里返回一个false来终止循环,
        而上次循环还没结束,则副线程的运行时间由visOpen3d_Noblockmain(pcd)里的界面持续时间决定
        '''
        time.sleep(1)
    
        print("副线程进行中~")
        stop_thread(t)
    
    if __name__ == "__main__":
        pcd = o3d.io.read_point_cloud("D:\STUDY\A4\open3d_downloads\ICP\Civil.pcd")
    
    
        for i in range(10):
            print("主线程进行中~")
            time.sleep(1)
            print("主线程进行中~")
            time.sleep(1)
            visOpen3d_Noblockmain(pcd)
            print("主线程进行中~")
            time.sleep(1)
            print("主线程进行中~")
            time.sleep(1)
            print("主线程进行中~")
            time.sleep(1)
            print("主线程进行中~")
            time.sleep(1)
        # time.sleep(20)  # 等待线程进行2秒时间
    
        print("线程 结束")
    
    
    
    • 限制1:该文件为demo版,其中定义了TestThread类,但在整合最终的函数visOpen3d_Noblockmain(pcd)时,pcd没有被创建为该类的对象(笔者的浅陋理解)。虽然该py文件能单独运行,但整合到项目里需要一定的调整,还请自行研究
    • 限制2:当运行负荷较大时,窗口弹出和保持均会延长一定时间,请合理设置参数
    • 限制3:自动弹出的o3d界面可能不会保持显示在窗口最前,笔者的解决办法是运行程序时先将全部窗口最小化,只露出桌面。这样,在设置好显示时间的前提下,每次读取pcd文件的窗口基本能显示
posted @ 2022-03-19 23:14  梧桐灯下江楚滢  阅读(1223)  评论(0编辑  收藏  举报