Blensor是一款開源的點雲仿真軟件,是國外的研究人員在三維動畫軟件Blender基礎上進行開發的,整個安裝包很小,只有80M左右,能夠模擬Lidar(Velodyne 32/64線等)、TOF相機、Kinect等,而且可以根據自己的需求調整傳感器參數,也可以加入噪聲模擬實際點雲,總之是一款很優秀的點雲仿真軟件,但是目前國內對這款軟件的介紹寥寥無幾,幾乎找不到相關的學習資料,所以在初步學習這款軟件后,決定寫一下簡單的教程,幫助需要的伙伴快速入手(目前本人也在學習中,對其中的部分功能都還不熟悉,因此下面的教程只適用於對Blender軟件零基礎、只需快速上手拿到仿真點雲數據的伙伴,歡迎大家一起交流)
一、軟件下載
首先訪問官網:https://www.blensor.org/ ,點擊download下載即可(需要翻牆),官網提供的有Windows、Linux、Mac三個版本的,Windows下的下載后解壓直接打開即可,無需安裝
安裝好后打開是下面的界面
二、跑通官方demo
安裝好以后,我們先嘗試跑通官方demo,對這個點雲的數據采集過程有個直觀感受。
(1)官方demo下載(https://www.blensor.org/add_sensors.html)
(2)打開table_tutorial_color.blend文件,里面主要包含了兩類:一台TOF相機和含有桌子杯子等的模型場景。
首先右鍵點擊相機,保證相機處於使用狀態中(相機實三角形為黃色,且出現坐標軸)
然后再點擊single scan按鈕進行點雲數據采集。
至此,數據采集過程完成。上述只是簡單的走了一遍流程,在實際應用過程中,需要用python編寫腳本程序自動采集(不嫌麻煩的也可以手動采集),下面就以我個人的使用需求進行詳細介紹。
三、實際使用
新建場景后,刪除自帶的模型和相機,導入自己的模型,Blensor支持包括.3ds、.ply、.obj、.stl等主流三維模型格式,導入后點擊左下角的view/properties可以修改模型的尺寸、位置、姿態等,如下圖所示。
然后加入相機,如下圖。在右側下方可以選擇相機的類型,包括velodyne 32線、velodyne 64線、TOF、Kinect等,后面的參數也都可以直接進行調整以滿足自己的需求。
在調整好所有參數之后,下面介紹如何用python進行數據收集。(其實上述基本所有的操作都可以用python實現,比如衛星模型比例、位置這些,看個人習慣了)
點擊左下角按鈕,會出現很多功能,這里我們介紹兩個,Text Editor和Python Console
(1)Text Editor主要是用來編寫腳本程序,當然目前支持的也就是Python,里面可以設置顯示行數和代碼高亮等,雖然比不上VS Code、PyCharm等編輯器好用,但是也算很良心了,畢竟幾十兆的軟件……另外提醒一下,這個是Python3.0的語法。一般我們的程序就是寫在這里,寫完后點擊“Run Script”就能運行了,這里不支持斷點調試,同時因為會用到Blensor自己的庫函數,所以外用編輯器也不太行,這個是個硬傷,但是好在這個軟件有個控制台,簡單的語法錯誤導致編譯失敗的可以用這個解決,如果是內在邏輯錯誤,就慢慢檢查代碼吧,good luck……(這個自帶的系統控制台叫“Toggle System Console”,在界面左上方“Window”下拉菜單里面)
(2)Python Console其實很多人應該不陌生,就是個最基本的程序控制台,通過該控制台能輸入一些基本的指令看到相關屬性數據啥的。具體可以在“Outliner”和“Properties”中查看,包括點雲數據、類型等。
重點:Blensor中所有的指令數據都給了非常具體的函數接口,這一點是我個人覺得最贊的,省去了大量閱讀開發文檔的時間,每個想要調用的數據或者按鈕,直接鼠標放在相應的位置即可。
另外關於數據導出的問題:
Blensor官方說法是可以提供pcd的點雲格式數據,但是!這個格式不知道為啥,完全不對,數據幀頭和數據包是兩個文件,而且數據包的文件有問題,沒法直接讀取,可能是我個人的理解偏差,總之官方給的數據我沒法用。
沒有pcd格式點雲數據就得自己想辦法,好在官方還有原始數據可供讀取,因此可以采用一幀一幀的數據訪問,然后保存下來使用。
具體方法:在每一次掃描后,清除上一幀的掃描結果(不然直接讀取數據會包含之前的,導致出錯),通過這個函數進行數據訪問:bpy.data.meshes[“ ”].vertices.co[]
此外,關於清除上一幀的點雲數據問題,在Single scan按鈕后面,有一個Delete scans,這個按鈕只是清除3D 視圖中的掃描痕跡,完全不會清除掃描數據,因此我們需要用bpy.data.objects.remove()函數,這樣清除后的數據再進行掃描,就能拿到當前幀下的掃描結果。
下面附一下我自己的代碼,可以幫助大家進一步理解
(其中999 999 999僅僅是我自己定義的數據分割標志,方便后續處理,相應的場景文件已傳至百度雲:https://pan.baidu.com/s/1xkYxF42yUfw_4T_QJJnUOQ 提取碼:h4ir)
import bpy import math from numpy import arange from bpy import data as D from bpy import context as C from mathutils import * from math import * import blensor """set the parameters of tof """ scanner = bpy.data.objects["Camera"]; scanner.location = (0,-6,0); scanner.rotation_euler= (90/180*pi,0,0/180*pi); scanner.scan_type = "tof"; """clear all scanning datas """ for item in bpy.data.objects: if item.type == 'MESH' and item.name.startswith('Scan'): bpy.data.objects.remove(item) """set the position and attitude of satellite""" satellite=bpy.data.objects["Satellite"]; satellite.rotation_euler=(0,0,0); satellite.location=(0,0,0); """clear the scanning in view windows and start newly scan""" bpy.ops.blensor.delete_scans(); bpy.ops.blensor.scan(); f=open("C:/Users/Justice/Desktop/TOF spacecraft position&attitude estimation by Blensor/data.txt","w") for z_angle in arange(0,360,5): #clear all scanning datas for item in bpy.data.objects: if item.type == 'MESH' and item.name.startswith('Scan'): bpy.data.objects.remove(item) satellite.rotation_euler=(20,0,z_angle/180*pi); bpy.ops.blensor.delete_scans(); bpy.ops.blensor.scan(); for item in bpy.data.objects: if item.type == 'MESH' and item.name.startswith('Scan'): #s_angle="data%" %(z_angle/2+1)) f.write("999\t999\t999\n") for sp in item.data.vertices: #print('X=%+#5.3f\tY=%+#5.3f\tZ=%+#5.3f' % (sp.co[0], sp.co[1],sp.co[2])); str='%#5.3f\t%#5.3f\t%#5.3f \n' % (sp.co[0], sp.co[1],sp.co[2]); f.write(str);