Open3d可視化界面自定義關閉時間
自定義關閉時間
-
效果:替代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文件的窗口基本能顯示
