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文件的窗口基本能顯示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM