最近正在做点云分割相关的课题,数据集采集有点麻烦,想通过Pybullet先制作一批仿真合成数据集出来。虽然思路挺清晰,由RGB-D图像生成点云,但是中间有很多地方会卡住,所以写篇blog记录一下。
图像拍摄
图像的拍摄挺简单的,直接用Pybullet现成的函数就可以获取RGB图像和深度图像,就是先要对物体还有相机的位置朝向等做个设置。
import pybullet as p
import pybullet_data
import numpy as np
import cv2
import PIL.Image as Image
import open3d as o3d
# 连接引擎
_ = p.connect(p.GUI)
# 不展示GUI的套件
p.configureDebugVisualizer(p.COV_ENABLE_GUI, 1)
# 添加资源路径
p.setAdditionalSearchPath(pybullet_data.getDataPath())
planeUid = p.loadURDF("plane.urdf", useMaximalCoordinates=True) # 加载一个地面
trayUid = p.loadURDF("tray/traybox.urdf", basePosition=[0, 0, 0]) # 加载一个箱子,设置初始位置为(0,0,0)
p.setGravity(0,0,-10)
width = 1080 # 图像宽度
height = 720 # 图像高度
fov = 50 # 相机视角
aspect = width / height # 宽高比
near = 0.01 # 最近拍摄距离
far = 20 # 最远拍摄距离
cameraPos = [0,0,1] # 相机位置
targetPos = [0,0,0] # 目标位置,与相机位置之间的向量构成相机朝向
cameraupPos = [1,0,0] # 相机顶端朝向
viewMatrix = p.computeViewMatrix(
cameraEyePosition=cameraPos,
cameraTargetPosition=targetPos,
cameraUpVector=cameraupPos,
physicsClientId=0
) # 计算视角矩阵
projection_matrix = p.computeProjectionMatrixFOV(fov, aspect, near, far) # 计算投影矩阵
w, h, rgb, depth, seg = p.getCameraImage(width, height, viewMatrix, projection_matrix, renderer=p.ER_BULLET_HARDWARE_OPENGL)
# 由此便可以得到RGB图像、深度图像、分割标签图像
图像存储
接下来就是将图像存储下来了,这里有挺多坑的。
彩色图像
彩色图像的存储还是比较简单的,我这里直接用OpenCV存,就是需要将RGB通道转换一下,OpenCV存储时的通道顺序有点不一样。
rgbImg = cv2.cvtColor(images[2], cv2.COLOR_BGR2RGB)
cv2.imwrite('image/rgb.jpg',rgbImg)
深度图像
坑1:深度图像一般的存储单位都是毫米,而Pybullet里的单位是米,所以需要做个换算。
坑2:需要对深度图像的深度值做一个透视变换,原理参考下文:《【3D数学】——透视变换与相机偏手性》,主要就是如下公式(符号意义看链接中的文章): m 3 + m 4 z = z ′ ⇒ z = m 4 z ′ − m 3 m_3+\frac{m_4}{z}=z'\Rightarrow z= \frac{m_4}{z'-m_3} m3+zm4=z′⇒z=z′−m3m4

最低0.47元/天 解锁文章
190

被折叠的 条评论
为什么被折叠?



