Commit e6f31465 authored by oscar's avatar oscar

提交代码修改

parent 21abad1e
......@@ -483,10 +483,10 @@ if __name__ == '__main__':
total_ind = 0
for child_ind,child_dir in enumerate(children_dir):
pcd_list = glob.glob(os.path.join(root_path,child_dir)+'\\pcd\\*.pcd')
pcd_list = glob.glob(os.path.join(root_path,child_dir)+'\\pcd\\*.pcd') #获取子目录下的所有pcd文件列表,其中每个元素都有完整的路径和文件名
#读标注的json文件
anno = {}
anno = {} #保存标记的信息列表,每个元素key是文件名,value是所有标记的信息列表
jsn_file = os.path.join(os.path.join(root_path,child_dir), child_dir + ".json")
with open(jsn_file, 'r',encoding='utf-8',errors='ignore') as fp:
jsn = json.load(fp)
......
import os
import open3d as o3d
import json
import glob
import numpy as np
import math
import random
import shutil as sh
import copy
from scipy.spatial.transform import Rotation as R
import cv2
def compute_pitch(A,B,C):
origin_direction = [0,0,1]
nor = [A,B,C]
angle = np.arccos(np.dot(origin_direction,nor) / np.linalg.norm(nor))
print(angle,angle* 180/ np.pi)
return angle
#绕z轴旋转:欧拉角到旋转矩阵
def rotz(t):
"""Rotation about the z-axis."""
c = np.cos(t)
s = np.sin(t)
return np.array([[c, -s, 0],
[s, c, 0],
[0, 0, 1]])
def compute_rot(A,B,C):
origin_direction = np.array([0,0,1])
nor = np.array([A,B,C])
mod = np.linalg.norm(nor)
nor = nor / mod
angle = np.arccos(np.dot(nor,origin_direction))
print(angle,angle* 180/ np.pi)
p_rot = np.cross(nor,origin_direction)
p_rot = p_rot / np.linalg.norm(p_rot)
sin_ang = np.sin(angle)
cos_ang = np.cos(angle)
rotMat = np.zeros([4,4])
rotMat[0,0] = cos_ang + p_rot[0] * p_rot[0] * (1 - cos_ang)
rotMat[0,1] = p_rot[0] * p_rot[1] * ( 1 - cos_ang - p_rot[2] * sin_ang)
rotMat[0,2] = p_rot[1] * sin_ang + p_rot[0] * p_rot[2] * (1-cos_ang)
rotMat[1,0] = p_rot[2] * sin_ang + p_rot[0] * p_rot[1] * (1 - cos_ang)
rotMat[1,1] = cos_ang + p_rot[1] * p_rot[1] * (1 - cos_ang)
rotMat[1,2] = -p_rot[0] * sin_ang + p_rot[1] * p_rot[2] * ( 1 - cos_ang)
rotMat[2,0] = -p_rot[1] * sin_ang + p_rot[0] * p_rot[2] * (1 - cos_ang)
rotMat[2,1] = p_rot[0] * sin_ang + p_rot[1] * p_rot[2] * ( 1 - cos_ang)
rotMat[2,2] = cos_ang + p_rot[2] * p_rot[2] * (1 - cos_ang)
rotMat[3,3] = 1
return angle,rotMat
rotMat = {}
def gen_rotMat():
global rotMat
#生成N7_1这段数据的全局转换矩阵
A,B,C,D = 5.10151553e-04,1.30740918e-03,1.89664435e-01,9.81847968e-01
#A,B,C,D = -9.39865821e-04, 1.04783823e-03, 1.85715376e-01, 9.82602574e-01
ang,hori_rotMat = compute_rot(A,B,C)
print(ang,hori_rotMat)
#ext_theta = 0.5 * np.pi
ext_theta = 90 / 180.0 * np.pi
kitti_Rot = np.zeros([4,4])
kitti_Rot[:3,:3] = rotz(ext_theta)
kitti_Rot[2,3] = -1
kitti_Rot[3,3] = 1
print(kitti_Rot)
tmp = np.dot(kitti_Rot,hori_rotMat)
rotMat['N7_1'] = tmp
print(tmp)
inverse_tmp = np.linalg.inv(tmp)
print(inverse_tmp)
N2_1_mat = np.array([[0.05045908306549516, -0.997741728436212, 0.04433197799906369, 0.0],
[0.9959209468126726, 0.05359234819149573, 0.07259013648610471, 0.0], [-0.0748020630460102,
0.04048831377621809, 0.9963761076077744, 0.2859260540868016], [0.0, 0.0, 0.0,
1.0]])
rotMat['N2_1'] = N2_1_mat
N2_2_mat = np.array([[0.07510626206747571, -0.9946697513726462, 0.07064796601834904, 0.0],
[0.9968676257061473, 0.07313389683723709, -0.03010597868179836, 0.0], [0.024778745271707994,
0.07268781767035316, 0.997046887034447, -0.7000000000000002], [0.0, 0.0, 0.0,
1.0]])
rotMat['N2_2'] = N2_2_mat
N2_3_mat = np.array([[0.07568437565247627, -0.9968308870840116, -0.02449607800031248,
0.0], [0.9971317454228593, 0.07565174868629727, 0.002257252902847979, 0.0],
[-0.0003969282768393359, -0.024596655789107878, 0.9996973776958381, 0.9000000000000004],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N2_3'] = N2_3_mat
N2_4_mat = np.array([[0.07516802438907474, -0.996779910756179, 0.0279209172905782, 0.0],
[0.9961881280280445, 0.07630731297561882, 0.042265914901034, 0.0], [-0.044260385057339445,
0.024637441006419476, 0.9987161833149752, 0.09999999999999964], [0.0, 0.0, 0.0,
1.0]])
rotMat['N2_4'] = N2_4_mat
N3_1_mat = np.array([[0.10282893175566048, -0.9927983688656276, 0.06146226136206685, 0.0],
[0.9946815801416514, 0.10226437626202323, -0.01226994191701453, 0.0], [0.0058961784994428,
0.06239708427073043, 0.9980339868729993, 0.7844127162859094], [0.0, 0.0, 0.0,
1.0]])
rotMat['N3_1'] = N3_1_mat
N3_2_mat = np.array([[0.9995180204153945, 0.028485544660163925, -0.012341013341895022,
10.0], [-0.02812481342444661, 0.9991986491976914, 0.02847901528053492, 0.0],
[0.013142364122603362, -0.02811820027887063, 0.9995182064766736, 0.7000000000000002],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N3_2'] = N3_2_mat
N4_1_mat = np.array([[-0.444341735964156, -0.8947739313681952, 0.044045810518876544, 0.0],
[0.8953720752482885, -0.4419458502434798, 0.054705688169885476, 0.0], [-0.029483360492542885,
0.06374540921880009, 0.9975305781065533, -0.09999999999999964], [0.0, 0.0, 0.0,
1.0]])
rotMat['N4_1'] = N4_1_mat
N4_2_mat = np.array([[0.9988523295913587, 0.04671359708300838, -0.010576555085760117,
10.0], [-0.04648606911938285, 0.9987018755893003, 0.020823281975752502, 0.0],
[0.011535555805583356, -0.02030772124045653, 0.9997272265024476, 0.7999999999999998],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N4_2'] = N4_2_mat
N5_1_mat = np.array([[-0.08986377281989212, -0.9954705408424266, 0.031030704946254054,
0.0], [0.9958706079834863, -0.09021596031025624, -0.010139657780214443, 0.0],
[0.012893195460257717, 0.029991379097749554, 0.9994669993004465, 0.5747271756415682],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N5_1'] = N5_1_mat
N5_2_mat = np.array([[-0.09764111729780293, -0.9944741458664936, 0.038566636046517395,
0.0], [0.9945996324606676, -0.09887670911792698, -0.03154310547669095, 0.0],
[0.035182144930937416, 0.03527845797532399, 0.9987580523234553, 1.2727123965813156],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N5_2'] = N5_2_mat
N5_3_mat = np.array([[0.11376454710271973, -0.9928370794231558, 0.03649878826770976, 0.0],
[0.9918680257870178, 0.11560991762950971, 0.05321810187391049, 0.0], [-0.05705652674214411,
0.030147647805359817, 0.9979156638152981, -0.404451678835378], [0.0, 0.0, 0.0,
1.0]])
rotMat['N5_3'] = N5_3_mat
N6_1_mat = np.array([[0.9994973004805413, -0.03086596626934255, 0.007241440351907325,
10.0], [0.03082860898771179, 0.9995110809882194, 0.0052149640117460745, 0.0],
[-0.007398864777328993, -0.004989098918726587, 0.9999601820532585, 0.9000000000000004],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N6_1'] = N6_1_mat
N6_2_mat = np.array([[0.9988722862129534, -0.04214125427326351, -0.021869396973478106,
10.0], [0.0409985649537926, 0.99789214163878, -0.05030299521200135, 0.0], [
0.023943130694148426, 0.04934965393845363, 0.9984945358632253, 0.9000000000000004],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N6_2'] = N6_2_mat
N6_3_mat = np.array([[-0.04889424680162646, -0.9987854830493128, -0.006075481845301646,
0.0], [0.9987878973799329, -0.048858057728727665, -0.005968772264798985, 0.0],
[0.00566468684698101, -0.00635995636205657, 0.9999637304812602, -0.6553131698852468],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N6_3'] = N6_3_mat
N8_1_mat = np.array([[0.06742395876958965, -0.9977243948218384, 0.00020435565303055666,
0.0], [0.9976344970690704, 0.06741513105551401, -0.013439135482274529, 0.0],
[0.013394776652850061, 0.001109991965790168, 0.9999096698583608, 0.7999999999999998],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N8_1'] = N8_1_mat
N9_1_mat = np.array([[-0.19809481806349166, -0.9794499176397107, 0.03789857374567175,
0.0], [0.9799804151970427, -0.19712000934332657, 0.02796583177233762, 0.0],
[-0.01992056441529652, 0.04267974639159458, 0.998890189340813, 0.9980420980703562],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N9_1'] = N9_1_mat
N9_2_mat = np.array([[-0.03297378854159967, -0.9961526066188378, 0.08119552694397052,
0.0], [0.9993813319576447, -0.03186786767058145, 0.014879258875841538, 0.0],
[-0.01223448420563244, 0.0816359194020958, 0.9965871231656551, -0.11066447945547608],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N9_2'] = N9_2_mat
N10_1_mat = np.array([[-0.10138137931389381, -0.9920819078535333, 0.07413031794148582,
0.0], [0.9946640529021992, -0.10251230933181928, -0.011603805394292926, 0.0],
[0.019111195477614955, 0.07255835269044347, 0.9971810505932539, -0.09999999999999964],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N10_1'] = N10_1_mat
N10_2_mat = np.array([[0.051858864388487746, -0.9973430294431006, 0.05116189798663601,
0.0], [0.9980146776291314, 0.049924120800806875, -0.0383964243008054, 0.0],
[0.03574019335646457, 0.05305152008684534, 0.9979519902256409, 1.259040914953271],
[0.0, 0.0, 0.0, 1.0]])
rotMat['N10_2'] = N10_2_mat
gen_rotMat()
#根据quart和计算出的原始坐标系的corners_3d来
#计算转换到新虚拟坐标系下的heading和heading平面
def my_compute_heading_plane(quart,corners_3d):
rot = R.from_quat(quart)
euler = rot.as_euler('zxy', degrees=False) #航向角
#点的方向按照逆时针顺序给出,保证算出的法向量垂直于平面向外
six_planes = [[corners_3d[1],corners_3d[5],corners_3d[6],corners_3d[2]],\
[corners_3d[0],corners_3d[4],corners_3d[5],corners_3d[1]],\
[corners_3d[3],corners_3d[7],corners_3d[4],corners_3d[0]],\
[corners_3d[2],corners_3d[6],corners_3d[7],corners_3d[3]],\
[corners_3d[0],corners_3d[1],corners_3d[2],corners_3d[3]],\
[corners_3d[7],corners_3d[6],corners_3d[5],corners_3d[4]] ]
normals = []
for it in six_planes:
it = np.array(it)
nor = np.cross(it[1] - it[2],it[0] - it[1])
normals.append(nor)
origin_direction = [1,0,0]
ret_ind = -1
for ind,nor in enumerate(normals):
direction = np.arccos(np.dot(origin_direction,nor) / np.linalg.norm(nor))
if abs(direction - abs(euler[0])) < 0.5:
ret_ind = ind
#print('debug:',direction,ind)
break
try:
assert(ret_ind == 0)
except:
print("wrong annotation")
return False, [], []
#new_heading = origin_lidar_heading_to_new_virtual(euler[0])
new_heading = euler[0]
new_heading_plane = copy.deepcopy(six_planes[ret_ind])
'''
nhp_len = len(new_heading_plane)
for ii in range(nhp_len):
#TODO cur lidar -> virtual kitti lidar
new_heading_plane[ii][0] = new_heading_plane[ii][0] - 15.0
new_heading_plane[ii][1] = new_heading_plane[ii][1] - 7.0
'''
return True,new_heading, new_heading_plane
#根据标注的3d框的center、quart、size计算3d bbox的8个顶点
#此处计算的是原始lidar坐标系下的坐标
def my_compute_box_3d(center, quart, size):
# P' = T * R * S * p
#其中p为box3d局部坐标,P'为变换后的世界坐标,假设初始box3d局部坐标系与lidar世界坐标系重合
#标准的box边长为1,正方体
x_corners = [-1,1,1,-1,-1,1,1,-1]
y_corners = [1,1,-1,-1,1,1,-1,-1]
z_corners = [1,1,1,1,-1,-1,-1,-1]
tmp = np.vstack([x_corners, y_corners, z_corners]) / 2
corners_3d = np.ones([4,8])
corners_3d[:3,:] = tmp
S = np.diag([size[0],size[1],size[2],1])
rot = R.from_quat(quart)
TR = rot.as_matrix()
Trans = np.zeros([4,4])
Trans[:3,:3] = TR
Trans[0,3] = center[0]
Trans[1,3] = center[1]
Trans[2,3] = center[2]
tmp4x4 = np.dot(S,corners_3d)
world_corners_3d = np.dot(Trans,tmp4x4)
return np.transpose(world_corners_3d[:3,:])
#读入原始lidar坐标系的标注信息
#将原始lidar坐标系转化为标准kitti坐标系
#转换方式:
# 所有corners_3d、center坐标按照“ln(x) = -l(y);ln(y) = l(x);ln(z) = l(z)”来转换
# 新的虚拟new_heading = np.pi + heading if -np.pi < heading < 0;
# 新的虚拟new_heading = heading - np.pi if 0 < heading < np.pi;
########
#保持不变的信息:
# category、size
def read_all_3d_bboxes(box3d,rotMat):
bboxes = []
for item in box3d:
center = [item['box3D']['translation']['x'],item['box3D']['translation']['y'],item['box3D']['translation']['z']]
center = np.array(center, np.float32)
center = np.transpose(np.dot(rotMat[:3,:3],np.transpose(center))) + rotMat[:3,3]
quart = [item['box3D']['rotation']['x'],item['box3D']['rotation']['y'],item['box3D']['rotation']['z'],item['box3D']['rotation']['w']]
origin_rot = R.from_quat(quart)
origin_rot_mat = origin_rot.as_matrix()
new_rot_mat = np.dot(rotMat[:3,:3],origin_rot_mat)
tmp = R.from_matrix(new_rot_mat)
quart = tmp.as_quat()
size = [item['box3D']['size']['x'],item['box3D']['size']['y'],item['box3D']['size']['z']]
size = np.array(size, np.float32)
if size[0] < 0.4 or size[1] < 0.4 or size[2] < 0.4:
continue
#计算原始lidar坐标系中的corners_3d
corners_3d = my_compute_box_3d(center, quart, size)
category = item['category']
assert_flag, heading, heading_plane = my_compute_heading_plane(quart,corners_3d)
if assert_flag == False:
return False, []
#以上为原始lidar坐标系的数据,下面要把bbox转成虚拟lidar坐标系的数据
#TODO cur lidar -> virtual kitti lidar
#new x = old x - 15 new y = old y - 7
#corners_3d[:,0] = corners_3d[:,0] - 15.0
#corners_3d[:,1] = corners_3d[:,1] - 7.0
#TODO cur lidar -> virtual kitti lidar
#center[0] = center[0] - 15.0
#center[1] = center[1] - 7.0
#特别注意,下面的heading和heading_plane是虚拟lidar坐标系下的heading
bboxes.append([category, corners_3d, heading, heading_plane, center, quart, size])
return True, bboxes
#按照文本来解析pcd点云文件
#解析过程中将原始lidar坐标系转换为新虚拟lidar坐标系
#转换方式:
# ln(x) = -l(y);ln(y) = l(x);ln(z) = l(z)
# intensity = intensity / 255.0
def parse_pandarmind_pcd(pandar_pcd_path,rotMat):
'''
pandar_fp = open(pandar_pcd_path,'r')
origin_data = []
pc = []
for line in pandar_fp.readlines()[11:]:
#TODO cur lidar -> virtual kitti lidar
x = float(line.split(' ')[1]) * -1 + 5 #将原点移到铁丝网后5米,这样可以把剔除掉的对象拉回来
y = float(line.split(' ')[0]) * 1 + 22 #将原点右移22米
z = float(line.split(' ')[2])
intensity = int(line.split(' ')[3])
origin_data.append([x,y,z,intensity/255.0])
pc.append([x,y,z])
origin_data = np.array(origin_data,dtype=np.float32)
pc = np.array(pc,dtype=np.float32)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(pc)
return origin_data, pcd
'''
pcd = o3d.io.read_point_cloud(pandar_pcd_path)
converted_pcd = copy.deepcopy(pcd)
xyz = np.array(pcd.points)
# convert points to horizontal plane
xyz_h = copy.deepcopy(xyz)
xyz_h = np.transpose(np.dot(rotMat[:3,:3], np.transpose(xyz_h))) + rotMat[:3,3]
xyzi = np.zeros([xyz_h.shape[0],4])
xyzi[:,:3] = xyz_h[:,:]
converted_pcd.points = o3d.utility.Vector3dVector(xyzi[:,:3])
'''
xyzi[:,0] = xyz[:,0] - 15
xyzi[:,1] = xyz[:,1] - 7
xyzi[:,2] = xyz[:,2]
pcd.points = o3d.utility.Vector3dVector(xyzi[:,:3])
'''
return xyzi,pcd,converted_pcd
#根据corners_3d来生成open3d渲染要用的12条边
def gen_o3d_3dbboxes(corners_):
bbox_lines = [[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7], [7, 4], [0, 4], [1, 5], [2, 6], [3, 7]]
colors = [[1, 0, 0] for _ in range(len(bbox_lines))] #red
bbox = o3d.geometry.LineSet()
bbox.lines = o3d.utility.Vector2iVector(bbox_lines)
bbox.colors = o3d.utility.Vector3dVector(colors)
bbox.points = o3d.utility.Vector3dVector(corners_)
return bbox
def custom_draw_geometry_with_key_callback(pcd, file_path):
def save_pcd(vis):
#io.write_point_cloud(file_path, pcd, write_ascii=True)
#print(file_path)
return False
key_to_callback = {}
key_to_callback[ord("S")] = save_pcd
o3d.visualization.draw_geometries_with_key_callbacks(pcd, key_to_callback)
if __name__ == '__main__':
jsn_file = "./data_aug_samples/N10_1.json"
root_path = "D:/work/git_workspace/jfxmap_python/script/data_aug_samples/"
child_dir = "N10_1"
#读标注的json文件
anno = {}
jsn_file = os.path.join(root_path, child_dir + ".json")
print(jsn_file)
vis = True
with open(jsn_file, 'r',encoding='utf-8',errors='ignore') as fp:
jsn = json.load(fp)
print(jsn)
\ No newline at end of file
annos = jsn["annotations"]
for an in annos:
fileuri = "10-1_pcds/" + an['fileuri'].split("/")[-1]
fileuri_path = os.path.join(root_path,fileuri)
# print(fileuri_path)
if os.path.isfile(fileuri_path):
print(fileuri_path," ",fileuri)
anno[fileuri_path] = an['labels_box3D']
for file_path,boxx in anno.items():
# print(file_path)
# print(boxx)
bbox_flag,bboxes = read_all_3d_bboxes(boxx, np.identity(4))
if bbox_flag == False or len(bboxes) < 1:
continue
# print(bbox_flag)
# print(bboxes)
# 地面转成水平面,地面点的z值几乎差不多
xyzi,pcd,converted_pcd = parse_pandarmind_pcd(file_path, rotMat[child_dir])
print(xyzi)
print(pcd)
print(converted_pcd)
merge_geos = [pcd]
for bbox in bboxes:
#渲染bbox
merge_geos += [gen_o3d_3dbboxes(bbox[1])]
heading_point = (bbox[3][0] + bbox[3][2]) / 2
heading_pcd = o3d.geometry.PointCloud()
heading_pcd.points = o3d.utility.Vector3dVector(np.array([heading_point]))
colors = [[0, 1, 0]]
heading_pcd.colors = o3d.utility.Vector3dVector(colors)
#渲染车辆形式方向的点
merge_geos += [heading_pcd]
if vis:
axis_pcd = o3d.geometry.TriangleMesh.create_coordinate_frame(size=5, origin=[0, 0, 0])
merge_geos += [axis_pcd]
#pcd.paint_uniform_color([1.00, 0, 0])
custom_draw_geometry_with_key_callback(merge_geos, file_path)
# pcd_list = glob.glob("D:/work/git_workspace/jfxmap_python/script/data_aug_samples/10-1_pcds/*.pcd")
# print(pcd_list)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment