如何在虚拟环境(虚幻引擎)按照规划路径下拍摄图片并应用于三维重建,以及路径规划
如何在虚拟环境(虚幻引擎)按照规划路径下拍摄图片并应用于三维重建
在三维重建工作中针对各项路径规划算法的使用,如果完全依照现实生活的照片未免太过奢侈和艰难(若用无人机,各项准备工作繁琐,),所以我们改为在虚拟环境下使用我们设定的相机位姿来进行拍照,相对于采用真实图片更加方便,参数更好修改,所以本篇我们介绍如何在虚幻引擎ue4下,通过自己设定的位姿来拍摄照片。
首先提前明确相机位姿的具体数据,这是一个六*度的变量,世界坐标系下做标x,y,z,和三个旋转欧拉角
θ
,
ϕ
,
ψ
\theta,\phi,\psi
θ,ϕ,ψ
那我们设置相机位姿就是要按照队这六个变量完成赋值,那如何在虚幻引擎下完成这样的工作呢,虚幻引擎提供了一个python库 unrealcv,用于对于游戏各项操作(你甚至可以用它来目标检测:https://www.youtube.com/watch?v=iGGNAkaxVyQ&feature=youtu.be),我们首先先安装unrealcv
pip install unrealcv
在github上搜索unrealcv有入门介绍(可能需要神秘力量)
为了测试拍摄,我们先下载一个虚幻引擎的小游戏(在unrealcv的入门指南上有链接)我选择的是RealisticRendering(就是一个w,a,s,d四处移动的观察景色的小游戏)
那么我们如何从这边获取图片呢,
import sys
import cv2
from pylab import *
import h5py
import itertools
import os
import unrealcv
import numpy
import matplotlib
unrealcv.client.connect()
assert unrealcv.client.isconnected()#首先让虚幻引擎连接
出现这个即为连接成功(我在windows下如果单独启动虚幻引擎经常连接失败,知道为什么的大佬希望可以在评论区指导我一下)
那么我们接下来来设置如何获取拍摄照片:
M_si_from_unreal = matrix("0.0 0.01 0.0; 0.0 0.0 0.01; 0.01 0.0 0.0")
M_unreal_from_si = M_si_from_unreal.I
rad_from_deg = pi/180
deg_from_rad = 180/pi
def position_si_from_unreal(position_unreal):
position_unreal=str(position_unreal)
return (M_si_from_unreal*matrix(matrix(position_unreal).A1).T).A1
def orientation_si_from_unreal(pyr_unreal):
return rad_from_deg*pyr_unreal[0,2], rad_from_deg*(pyr_unreal[0,1] + 90), -rad_from_deg*pyr_unreal[0,0] # theta, psi, phi
def position_unreal_from_si(position_si):
return (M_unreal_from_si*matrix(matrix(position_si).A1).T).A1
def pyr_unreal_from_si(theta_si, psi_si, phi_si):
return deg_from_rad*array([-phi_si,psi_si,theta_si]) - array([0,90,0])
def unreal_engine_get_camera_pose(cam_id):
while True:
try:
pos = position_si_from_unreal(matrix(str(unrealcv.client.request("vget /camera/%d/location" % cam_id))))
break
except:
continue
while True:
try:
theta, psi, phi = orientation_si_from_unreal(matrix(str(unrealcv.client.request("vget /camera/%d/rotation" % cam_id))))
break
except:
continue
return pos, theta, psi, phi
def unreal_engine_set_camera_pose(cam_id, pos, theta, psi, phi):
pos_unreal = position_unreal_from_si(pos)
pyr_unreal = pyr_unreal_from_si(theta, psi, phi)
while True:
try:
result = str(unrealcv.client.request("vset /camera/%d/location %f %f %f" % (cam_id,pos_unreal[0],pos_unreal[1],pos_unreal[2])))
break
except:
continue
assert result == "ok"
while True:
try:
result = str(unrealcv.client.request("vset /camera/%d/rotation %f %f %f" % (cam_id,pyr_unreal[0],pyr_unreal[1],pyr_unreal[2])))
break
except:
continue
assert result == "ok"
def unreal_engine_get_camera_rgb_image(cam_id):
while True:
try:
rgb_filename = str(unrealcv.client.request("vget /camera/%d/lit" % cam_id))
break
except:
continue
print(rgb_filename)
rgb_img = imread(rgb_filename)
return rgb_img
在这里仔细观察(这份代码是我从一个项目下改动的,不是官方给的写法),我们在这里有unreal_engine_get_camera_rgb_img函数来通过相机的id号来获取所拍摄的相片,同时我们还有一设定给定相机id位姿的函数,那接下来我们的思想就很简单了,我们每次都对给定id的相机设定它的位姿,然后获取图片并保存下来(在这里我们用的是hdf5格式文件来分开存储相机位置和姿态(这个文件,是我自己为了实现overhead拍摄自己一个个慢慢拍摄并记录的,如果想自己试试这个文件可以在评论区说下),那我们读取hdf5文件就要使用h5py库,
file_name="camera_position.hdf5"
i=0
position=[]
eular=[]
with h5py.File(file_name, "r+") as f:
a_key=list(f.keys())[i]
i+=1
data=list(f[a_key])
position.append(data)
print(position)
file_name="camera_position_eular.hdf5"
i=0
with h5py.File(file_name, "r+") as f2:
b_key=list(f2.keys())[i]
i+=1
data=list(f2[b_key])
eular.append(data)
cam_id=0
picture_name=0
for pose,eular_tangle in zip(position[0],eular[0]):
picture_name+=1
unreal_engine_set_camera_pose(cam_id, pose, eular_tangle[0], eular_tangle[1], eular_tangle[2])
rgb_img = unreal_engine_get_camera_rgb_image(cam_id)
name=str(picture_name)+".png"
imsave(name, rgb_img)
ps:这代码我随意写的,可能有些不规范,这样我们通过读取两个存储着位置和姿态的文件,我们设置每个相机的位姿,在拍摄图片就完成了我们在虚拟环境下给定路径拍摄照片的方法,结果如下:
接下来我们就可以利用这些图片来进行三维重建或者路径规划的工作(博主最近在做三维重建路径规划的工作(纯萌新),如果有大佬或同志会可以评论区或私聊我交流)
本文地址:https://blog.csdn.net/theworld666/article/details/110441579