Files
2026-06-24 09:35:46 +08:00

1243 lines
62 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# coding:utf-8
import os
import glob
import json
from copy import deepcopy
import math
import cv2
import copy
import matplotlib.cm as cm
import numpy as np
from pyquaternion import Quaternion
import random
from multiprocessing import Pool, cpu_count
import traceback
colors = [(0, 255, 0),(255, 0, 0),(0, 0, 255),(240, 32, 160), (128, 128, 128),
(204, 161, 141),(101, 134, 179),(0, 255, 255),(89, 109, 61),(141, 137, 194),(132, 228, 208),
(249, 118, 35),(80, 91, 182),(222, 91, 125),(91, 63, 123),(173, 232, 91),
(255, 164, 26),(44, 56, 142),(74, 148, 81),(179, 42, 50),(250, 226, 21),(191, 81, 160),
(6, 142, 172),(252, 252, 252),(230, 230, 230),(200, 200, 200),(143, 143, 142),(100, 100, 100),(50, 50, 50)]
subcls = {
'kNegative' : 0, # 背景
'kBus' : 1, # 大巴
'kCar' : 2, # 小轿车,suv
'kMiniBus' : 3, # 面包车
'kBucketTruck' : 4, # 斗卡
'kContainerTruck' : 5, # 箱卡
'kTricycle' : 6, # 三轮车
'kTanker' : 7, # 油罐车,晒水车(车身带有圆形,椭圆形,半圆形的罐)
'kCementTankTruck' : 8, # 水泥罐车
'kPickup' : 9, # 皮卡
'kSedimentTruck' : 10, # 渣土车
'kIveco' : 11, # 依维柯
'kSpecialCar' : 12, # 异型车
'kCityAuto' : 13, # 市政车
'kVehicleUnknown' : 14, # 未知车辆
'kWrecker' : 15, # 小型拖车,清障车
'kFlatTransporter' : 16,# 大型平板拖车
'kTractorHead' : 17, # 卡车车头,牵引车车头
'kSpecialFlatTransporter' : 18, # 大型特种拖车(相对于大型平板拖车会多挡板)
'kCarCarrier' : 19, # 轿运车
# 盖布车(车身上的货物全部被布盖着,同时对车辆尾部进行了遮挡)
'kTruckWithTrap' : 20,
'kEngineeringVehicle' : 21, # 工程车
'kSweeper' : 22, # 扫地车
'kRoadServiceCar' : 23, # 道路维修车
'kSanitationTruck' : 24, # 环卫车
'kGarbageTruck' : 25, # 垃圾车
}
def plot_box(x, img, color=None, label=None, line_thickness=None):
# Plots one bounding box on image img
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
T1Q2Dlabel = {'vehicle': 0, 'pedestrian':1, 'bicycle':2, 'rider':3, 'roadblock':4,'cone': 4, 'crashbarrels' :4, 'plasticpile':4, 'bumpingpost':4, 'head':5, 'tsr':6, 'guideboard':7, 'plate':8, 'wheel':9, 'tl_border':10,'tl_wick':11,'tl_num':12}
def detectmap(path):
# labeldict = {0:'vehicle', 1:'pedestrian', 2:'bicycle', 3:'cone', 4:'warning', 5:'head', 6:'tsr', 7:'guideboard', 8:'plate', 9:'wheel', 10:'tl_border',11:'tl_wick',12:'tl_num'}
labeldict = {0:'vehicle', 1:'pedestrian', 2:'bicycle', 3:'rider', 4:'roadblock', 5:'head', 6:'tsr', 7:'guideboard', 8:'plate', 9:'wheel', 10:'tl_border',11:'tl_wick',12:'tl_num'}
textlists = open(path,'r').readlines()
label_maps = {}
for text in textlists:
data = text.strip('\n').split(' ')
filename = data[0]
box = [float(data[2]), float(data[3]), float(data[4]),float(data[5])]
# label = labeldict.get(int(data[1]))
label = str(data[1])
# ignore = int(data[6])
ignore = 1
if filename not in label_maps:
label_maps[filename] = []
label_maps[filename].append((label,box,ignore))
return label_maps
def get_rot_mat_and_trans(calib_dict):
su = np.sin(calib_dict['roll'] * np.pi / 180)
cu = np.cos(calib_dict['roll'] * np.pi / 180)
sv = np.sin(calib_dict['pitch'] * np.pi / 180)
cv = np.cos(calib_dict['pitch'] * np.pi / 180)
sw = np.sin(calib_dict['yaw'] * np.pi / 180)
cw = np.cos(calib_dict['yaw'] * np.pi / 180)
rot = np.array([[cv * cw, su * sv * cw - cu * sw, su * sw + cu * sv * cw],
[cv * sw, cu * cw + su * sv * sw, cu * sv * sw - su * cw],
[-sv, su * cv, cu * cv]])
rot = np.transpose(rot)
rot_yxz = np.array([[0, -1, 0], [0, 0, -1], [1, 0, 0]])
rot_ego2cam = np.matmul(rot_yxz, rot)
# rot_cam2ego = np.transpose(rot_ego2cam) # equals np.linalg.inv
pos = np.array(calib_dict['pos'])
trans_ego2cam = -1 * np.matmul(rot_ego2cam, pos)
ego_to_cam = np.zeros((4, 4))
ego_to_cam[:3, :3] = rot_ego2cam
ego_to_cam[:3, 3] = trans_ego2cam
ego_to_cam[3, 3] = 1
# cam_to_ego = np.linalg.inv(ego_to_cam)
return ego_to_cam
def Vehicle2OrigImg(pts3d, ego2cam, distort_param, K, origW, origH):
pts3d_cam = np.dot(ego2cam[:3, :3],[pts3d[0],pts3d[1],pts3d[2]]) + ego2cam[:3, 3]
# pts2d_cam = cam_img_kb(pts3d_cam[0],pts3d_cam[1],pts3d_cam[2],K,distort_param)
if len(distort_param)==5:
pts2d_cam = xyz_xy(pts3d_cam[0] /pts3d_cam[2], pts3d_cam[1] / pts3d_cam[2], distort_param, K)
else:
pts2d_cam = cam_img_kb(pts3d_cam[0],pts3d_cam[1],pts3d_cam[2],K,distort_param)
pts2d_cam = pts2d_cam[0:2]
pts2d_cam[0] = np.clip(pts2d_cam[0],0,origW-1)
pts2d_cam[1] = np.clip(pts2d_cam[1],0,origH-1)
return pts2d_cam, pts3d_cam
def deal_cutoff(cor,bbox_cam3d,cen2d,cen2d_di,alpha,lidar_to_cam,K,distortion_param,K_new,image_w,image_h,ydis_dict):
cor = np.array(cor)
# a = cor[:,0] * K_new[0][0]
# b = -cor[:,2]*K_new[0][2]
# c = cor[:,2]*(image_w-1-K_new[0][2])
x_left = cor[:,0]>=-cor[:,2]*K_new[0][2]/K_new[0][0] # (8,)
x_right = cor[:,0]<=cor[:,2]*(image_w-1-K_new[0][2])/K_new[0][0]
if (x_left==True).sum()==(x_right==True).sum() and (x_right==True).sum()<8:
if bbox_cam3d[0]<=-bbox_cam3d[2]*(image_w-1-K_new[0][2])/K_new[0][0]: ####右边界线
is_left = True
# assert bbox_cam3d[0] < -bbox_cam3d[2]*K_new[0][2]/K_new[0][0]
else:
is_left = False
# assert bbox_cam3d[0]>-bbox_cam3d[2]*(image_w-1-K_new[0][2])/K_new[0][0]
else:
is_left = (x_left==True).sum()<(x_right==True).sum() # 左边界被切
have_in = ((x_left & x_right)[[0,1,4,5]]==True).sum()
pts2ds_c,_ = cam2pixel(np.array([bbox_cam3d[0], bbox_cam3d[1], bbox_cam3d[2]]), K_new)
condition_c = np.logical_and((pts2ds_c[1] <= image_h-1) & (pts2ds_c[1] >= 0),(pts2ds_c[0] <= image_w-1) & (pts2ds_c[0] >= 0))
cutoff = 0
if have_in ==2 and condition_c == False:
cutoff = 1
y_dis = max(0,min(image_h-1,round(K_new[1][2]+K_new[1][1]*(bbox_cam3d[1]/bbox_cam3d[2]))))
if is_left:
x_dis = ydis_dict[0][y_dis]
else:
x_dis = ydis_dict[1][y_dis]
z_new = (bbox_cam3d[2]*K_new[0][0]+bbox_cam3d[0]*K_new[0][0]*np.tan(bbox_cam3d[-1]))/((x_dis-K_new[0][2])*np.tan(bbox_cam3d[-1])+K_new[0][0])
x_new = z_new*(x_dis-K_new[0][2])/K_new[0][0]
# cen2d = xyz_xy(x_new/z_new,bbox_cam3d[1]/z_new,distortion_param,K)
cen2d = cam_img_kb(x_new,bbox_cam3d[1],z_new,K,distortion_param)
x_nc,y_nc = float(cen2d[0]),float(cen2d[1])
if x_nc<0 or x_nc>image_w-1 or y_nc<0 or y_nc>image_h-1:
x_nc,y_nc = max(0,min(image_w-1,x_nc)),max(0,min(image_h-1,y_nc))
img_corners = np.array([x_nc,y_nc]).reshape((-1, 2))
x_new,y_new = img_cam_kb(img_corners,K,distortion_param)
x_new,y_new = x_new*z_new,y_new*z_new
if y_new!=bbox_cam3d[1]:
bbox_cam3d[4] = bbox_cam3d[4]-(y_new-bbox_cam3d[1])*2
bbox_cam3d[1] = y_new
is_l = np.logical_or((x_left & x_right)[[0,1]].all(),(x_left & x_right)[[4,5]].all())
see_radio = [1,1]
if is_l:
l = (bbox_cam3d[3]/2 - np.sqrt(np.sum(np.square(np.array([x_new,bbox_cam3d[1],z_new],dtype=np.float32) - np.array(bbox_cam3d[0:3],dtype=np.float32)))))*2
assert l<bbox_cam3d[3]
new_box = [x_new,bbox_cam3d[1],z_new,l,bbox_cam3d[4],bbox_cam3d[5],bbox_cam3d[6]]
see_radio = [l/bbox_cam3d[3],1]
else: ###
w = (bbox_cam3d[5]/2 - np.sqrt(np.sum(np.square(np.array([x_new,bbox_cam3d[1],z_new],dtype=np.float32) - np.array(bbox_cam3d[0:3],dtype=np.float32)))))*2
assert w<bbox_cam3d[5]
new_box = [x_new,bbox_cam3d[1],z_new,bbox_cam3d[3],bbox_cam3d[4],w,bbox_cam3d[6]]
see_radio = [1,w/bbox_cam3d[4]]
if min(see_radio) > 0.1:
# cen2d = xyz_xy(new_box[0]/new_box[2],new_box[1]/new_box[2],distortion_param, K) # 中心点x,y,z;底部中心点(x,y+l/2,z) 1933.3505753743707, 593.9974302913548
# cen2d_di = xyz_xy(new_box[0]/new_box[2],(new_box[1]+0.5*new_box[4])/new_box[2],distortion_param,K)
cen2d = cam_img_kb(new_box[0],new_box[1],new_box[2],K,distortion_param) # 中心点x,y,z;底部中心点(x,y+l/2,z) 1933.3505753743707, 593.9974302913548
cen2d_di = cam_img_kb(new_box[0],(new_box[1]+0.5*new_box[4]),new_box[2],K,distortion_param)
# assert new_box[2]>0
alpha = -np.arctan2(new_box[0],new_box[2])+new_box[-1] # -torch.atan2(torch.tensor(loc[0]), torch.tensor(loc[2]))+torch.tensor(rot[0])
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
bbox_cam3d = new_box
return bbox_cam3d, cen2d,cen2d_di, alpha, cutoff
def rotation_3d_in_axis(points, angles, axis=0):
####需要特别注意旋转的轴和旋转矩阵正逆问题 以下为逆时针旋转矩阵
rot_sin = np.sin(angles)
rot_cos = np.cos(angles)
ones = np.ones_like(rot_cos)
zeros = np.zeros_like(rot_cos)
if axis == 1: ####Y
rot_mat = np.stack([
np.stack([rot_cos, zeros, -rot_sin]),
np.stack([zeros, ones, zeros]),
np.stack([rot_sin, zeros, rot_cos])
])
elif axis == 2: #####Z
rot_mat = np.stack([
np.stack([rot_cos, rot_sin, zeros]),
np.stack([-rot_sin, rot_cos, zeros]),
np.stack([zeros, zeros, ones])
])
elif axis == 0: #####X
rot_mat = np.stack([
np.stack([ones, zeros, zeros]),
np.stack([zeros, rot_cos, rot_sin]),
np.stack([zeros, -rot_sin, rot_cos])
])
else:
raise ValueError(f'axis should in range [0, 1, 2], got {axis}')
return np.dot(points, rot_mat)
def create_corner(object = [0,0,0,0,0,0,0], type= 'cam',dtype=np.float32):
dims = np.array([object[3],object[4],object[5]]) ###lwh # torch.Size([1, 3])
corners_norm =np.stack(np.unravel_index(np.arange(8), [2] * 3), axis=1)
corners_norm = corners_norm[[0, 1, 3, 2, 4, 5, 7, 6]]
# use relative origin [0.5, 1, 0.5]
corners_norm = corners_norm -[0.5, 0.5, 0.5]
corners = dims.reshape([-1, 3]) * corners_norm.reshape([8, 3])
# rotate around y axisa
corners = rotation_3d_in_axis(corners, object[6], axis=2) ######
corners += np.array(object[:3]).reshape(1, 3)
return corners
def cam_corners_front_rear(pred3d, facetype,pitch = 0):
dims = pred3d[3:6]
corners_norm = np.stack(np.unravel_index(np.arange(8), [2] * 3), axis=1)
corners_norm = corners_norm[[0, 1, 3, 2, 4, 5, 7, 6]]
# use relative origin [0.5, 1, 0.5]
if facetype == 'tail':
# front
corners_norm = corners_norm - [0, 0.5, 0.5]
elif facetype == 'front':
# tail
corners_norm = corners_norm - [1, 0.5, 0.5]
elif facetype == 'right':
# left
corners_norm = corners_norm - [0.5, 0.5, 0]
elif facetype == 'left':
# right
corners_norm = corners_norm - [0.5, 0.5, 1]
elif facetype == 'whole':
# center
corners_norm = corners_norm - [0.5, 0.5, 0.5]
else:
raise AssertionError('Non valid face type')
corners = dims.reshape([1, 3]) * corners_norm.reshape([8, 3])
# rotate around y axis
corners = rotation_3d_in_axis(corners, pred3d[6], axis=1)
####
corners = rotation_3d_in_axis(corners, pitch * np.pi / 180.0, axis=0)
####
corners += pred3d[:3].reshape(1, 3)
return corners
def ious_function(boxes1, boxes2, iom = False):
# boxes1-(4,),mx4
boxes1 = np.array(boxes1)
boxes2 = np.array(boxes2)
boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * (boxes1[..., 3] - boxes1[..., 1])
boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1])
left_up = np.maximum(boxes1[..., :2], boxes2[..., :2])
right_down = np.minimum(boxes1[..., 2:], boxes2[..., 2:])
inter_section = np.maximum(right_down - left_up, 0.0)
inter_area = inter_section[..., 0] * inter_section[..., 1]
if iom:
union_area = boxes1_area
else:
union_area = boxes1_area + boxes2_area - inter_area
ious = np.maximum(1.0 * inter_area / union_area, np.finfo(np.float32).eps)
return ious
def get_point_xyz(xyz1,xyz2,num=1): # num=1为黑色
(x1,y1,z1),(x2,y2,z2) = xyz1,xyz2
dis = np.array([abs(x1-x2),abs(y1-y2),abs(z1-z2)])
dis_idx = dis.argmax()
res = []
if dis_idx==0:
for x in np.concatenate((np.arange(x1,x2,0.01) ,np.arange(x1,x2,-0.01))):
res.append([x,(x-x1)*(y2-y1)/(x2-x1)+y1,(x-x1)*(z2-z1)/(x2-x1)+z1,num])
elif dis_idx==1:
for y in np.concatenate((np.arange(y1,y2,0.01) ,np.arange(y1,y2,-0.01))):
res.append([(y-y1)*(x2-x1)/(y2-y1)+x1,y,(y-y1)*(z2-z1)/(y2-y1)+z1,num])
else:
for z in np.concatenate((np.arange(z1,z2,0.01) ,np.arange(z1,z2,-0.01))):
res.append([(z-z1)*(x2-x1)/(z2-z1)+x1,(z-z1)*(y2-y1)/(z2-z1)+y1,z,num])
return res
def cam_img_kb(x,y,z,cam_intrinsic,distort_param):
# objp=np.array([x/z,y/z,1]).reshape(1,-1,3)
# rvec = np.array([[[0., 0., 0.]]])
# tvec = np.array([[[0., 0., 0.]]])
# image_coord, _ = cv2.fisheye.projectPoints(objp, rvec, tvec,cam_intrinsic, distort_param)
# image_coord = image_coord.reshape(-1)
# return image_coord
camxyz = np.array([x/z, y/z]).reshape(-1,2)
a = camxyz[...,0]
b = camxyz[...,1]
r = np.sqrt(a * a + b * b)
theta = np.arctan(r)
k1 = distort_param[0]
k2 = distort_param[1]
k3 = distort_param[2]
k4 = distort_param[3]
thetaD = theta * (1 + k1 * theta**2 + k2 * theta**4 + k3 * theta**6 + k4 * theta**8)
xp = thetaD / r * a
yp = thetaD / r * b
fx = cam_intrinsic[0,0]
fy = cam_intrinsic[1,1]
cx = cam_intrinsic[0,2]
cy = cam_intrinsic[1,2]
imgx = (fx * xp + cx)
imgy = (fy * yp + cy)
# mask_2d = (imgx>=0)&(imgx<3840)&(imgy>=0)&(imgy<2160)
pix_point = np.round(np.concatenate((imgx.reshape((-1,1)),imgy.reshape((-1,1))),axis=-1))
# pix_point = pix_point[mask_2d].astype(np.int32)
pix_point = pix_point.astype(np.int32)
return pix_point.reshape(-1)
def img_cam_kb(img_corners,cam_intrinsic,distort_param): # nx2
ones_col = np.ones((img_corners.shape[0], 1), dtype=np.float32)
img_corners = np.concatenate((img_corners.astype(np.float32),ones_col),axis=-1) # n,3
k1 = distort_param[0]
k2 = distort_param[1]
k3 = distort_param[2]
k4 = distort_param[3]
points = np.dot(np.linalg.inv(cam_intrinsic),img_corners.T).T # (2073600, 3)
xp = points[:,0] # n
yp = points[:,1] # n
thetaD = np.sqrt(xp*xp+yp*yp)
cam_theta,femask = [],[]
theta = thetaD
for i in range(10):
ftheta = theta * (1 + k1 * theta**2 + k2 * theta**4 + k3 * theta**6 + k4 * theta**8) - thetaD
ftheta_dao = 1 + 3 * k1 * theta**2 + 5 * k2 * theta**4 + 7 * k3 * theta**6 + 9 * k4 * theta**8
theta = theta - ftheta/ftheta_dao
if abs(ftheta)<0.0000001:
break
# print(ftheta)
r = np.tan(theta)
###################################
normx = xp * r / thetaD # 4,H,W
normy = yp * r / thetaD
ones_col = np.ones((normy.shape[0], 1), dtype=np.float32)
x3dy3d = np.concatenate((normx.reshape((-1,1)),normy.reshape((-1,1)),ones_col),axis=-1)
return x3dy3d[0,0], x3dy3d[0,1]
# def img_cam_kb(img_corners,cam_intrinsic,distort_param): # nx2
# ones_col = np.ones((img_corners.shape[0], 1), dtype=np.float32)
# img_corners = np.concatenate((img_corners.astype(np.float32),ones_col),axis=-1) # n,3
# k1 = distort_param[0]
# k2 = distort_param[1]
# k3 = distort_param[2]
# k4 = distort_param[3]
# points = np.dot(np.linalg.inv(cam_intrinsic),img_corners.T).T # (2073600, 3)
# xp = points[:,0] # n
# yp = points[:,1] # n
# thetaD = np.sqrt(xp*xp+yp*yp)
# cam_theta,femask = [],[]
# # for d in tqdm(thetaD):
# for d in thetaD:
# coeff = np.array([-d,1,0,k1,0,k2,0,k3,0,k4],dtype=np.float64) # k4*x**9+k3*x**7+k2*x**5+k1*x**3+x-d=0
# success,roots = cv2.solvePoly(coeff)
# roots = roots.squeeze(1)
# roots = np.array([root[0] for root in roots if abs(root[1]) < 1e-10]) # 找到唯一实数根解
# assert len(roots)==1,'come with many theta'
# if roots[0]>=0 and roots[0] <=np.pi/2:
# femask.append(True)
# else:
# femask.append(False)
# cam_theta.append(roots[0])
# r = np.tan(cam_theta)
# mask3d = np.array(femask)
# ###################################
# normx = xp * r / thetaD # 4,H,W
# normy = yp * r / thetaD
# ones_col = np.ones((normy.shape[0], 1), dtype=np.float32)
# x3dy3d = np.concatenate((normx.reshape((-1,1)),normy.reshape((-1,1)),ones_col),axis=-1)
# x3dy3d = x3dy3d[mask3d]
# return x3dy3d[0,0], x3dy3d[0,1]
def cam2RectifyImg(x,y, distort_param, K):
# R = np.array([[0, -1, 0],[-1, 0, 0],[0, 0, 1]])
# pts3d_cam = np.dot(lidar_to_cam[:3, :3],[pts3d[0],pts3d[1],pts3d[2]]) + lidar_to_cam[:3, 3]
# pts3d_cam = lidar_to_cam[:3, :3] @ (pts3d.T) + lidar_to_cam[:3, 3].reshape(3, 1) # 1x3
pts2d_cam = K @ np.array([x,y,1])
pts2d_cam[2] = np.clip(pts2d_cam[2],1,500)
pts2d_cam = (pts2d_cam[:2] / pts2d_cam[2]).T
pts2d_cam = pts2d_cam[0:2]
image_h, image_w = 1080,1920
pts2d_cam[0] = np.clip(pts2d_cam[0],0,image_w-1)
pts2d_cam[1] = np.clip(pts2d_cam[1],0,image_h-1)
return pts2d_cam
def xyz_xy(x,y,distort_param,K):
r = np.sqrt(x * x + y * y)
r_2 = r * r
r_4 = r_2 * r_2
r_6 = r_4 * r_2
m_distort_coeffs = distort_param
coeffs = np.zeros(12,dtype=np.float32)
for i in range(min(m_distort_coeffs.shape[0],12)):
coeffs[i] = m_distort_coeffs[i]
radial_ratio = (1 + coeffs[0] * r_2 + coeffs[1] * r_4 + coeffs[4] * r_6) / (1 + coeffs[5] * r_2 + coeffs[6] * r_4 + coeffs[7] * r_6)
res_x = x * radial_ratio + 2 * coeffs[2] * x * y + coeffs[3] * (r_2 + 2 * pow(x, 2)) + coeffs[8] * r_2 + coeffs[9] * r_4
res_y = y * radial_ratio + 2 * coeffs[2] * (r_2 + 2 * pow(y, 2)) + coeffs[3] * x * y + coeffs[10] * r_2 + coeffs[11] * r_4
image_coord = np.dot(K,np.array([res_x,res_y,1])).T
return image_coord[:2]
def xy_xyz(x,y,m_distort_coeffs,k):
x = (x - k[0][2])/k[0][0]
y = (y - k[1][2])/k[1][1]
coeffs = np.zeros(12,dtype=np.float32)
for i in range(min(m_distort_coeffs.shape[0],12)):
coeffs[i] = m_distort_coeffs[i]
iter_num = 5
x0,y0 = x,y
for i in range(iter_num):
r = np.sqrt(x * x + y * y)
r_2 = r * r
r_4 = r_2 * r_2
r_6 = r_4 * r_2
inv_radial_ratio = (1 + coeffs[5] * r_2 + coeffs[6] * r_4 + coeffs[7] * r_6) / (1 + coeffs[0] * r_2 + coeffs[1] * r_4 + coeffs[4] * r_6)
delta_x = 2 * coeffs[2] * x * y + coeffs[3] * (r_2 + 2 * pow(x, 2)) + coeffs[8] * r_2 + coeffs[9] * r_4
delta_y = 2 * coeffs[2] * (r_2 + 2 * pow(y, 2)) + coeffs[3] * x * y + coeffs[10] * r_2 + coeffs[11] * r_4
x = (x0 - delta_x) * inv_radial_ratio
y = (y0 - delta_y) * inv_radial_ratio
# x = x*k[0][0]+k[0][2]
# y = y*k[1][1]+k[1][2]
return x,y
def get_cutoff_corners(cam3d_corners,pts2ds,cam_intrinsic,distortion_param,cam_rectify,imgW,imgH):
xyz_list = []
cut_pts2d = np.zeros_like(pts2ds)
cam3d_corners_update = np.zeros_like(cam3d_corners)
for (i,j) in [(0, 1), (1, 2), (2, 3), (3, 0),(0,4), (1,5), (2,6),(3,7)]:
res = get_point_xyz(cam3d_corners[i],cam3d_corners[j],0)
xyz_list.extend(res)
if (i,j) in [(0,4), (1,5), (2,6),(3,7)]:
point = np.array(res)
pointx_in = np.logical_and(point[:,0]>=-point[:,2]*cam_rectify[0][2]/cam_rectify[0][0],point[:,0]<=point[:,2]*(imgW-1-cam_rectify[0][2])/cam_rectify[0][0])
pointy_in = np.logical_and(point[:,1]>=-point[:,2]*cam_rectify[1][2]/cam_rectify[1][1],point[:,1]<=point[:,2]*(imgH-1-cam_rectify[1][2])/cam_rectify[1][1])
pointxy_in = np.logical_and(pointx_in,pointy_in)
t_point = point[pointxy_in]
if t_point.shape[0] == 0:
if len(distortion_param)==5:
origimg0 = xyz_xy(point[0,0] /point[0,2], point[0,1] / point[0,2], distortion_param, cam_intrinsic)
else:
origimg0 = cam_img_kb(point[0,0] , point[0,1] , point[0,2],cam_intrinsic,distortion_param)
cut_pts2d[i] = origimg0[:2]
cut_pts2d[j] = origimg0[:2]
continue
if len(distortion_param)==5:
point_origimg0 = xyz_xy(t_point[0,0] /t_point[0,2], t_point[0,1] / t_point[0,2], distortion_param, cam_intrinsic)
point_origimg1 = xyz_xy(t_point[-1,0] /t_point[-1,2], t_point[-1,1] / t_point[-1,2], distortion_param, cam_intrinsic)
else:
point_origimg0 = cam_img_kb(t_point[0,0] , t_point[0,1] , t_point[0,2],cam_intrinsic,distortion_param)
point_origimg1 = cam_img_kb(t_point[-1,0] , t_point[-1,1] , t_point[-1,2],cam_intrinsic,distortion_param)
cut_pts2d[i] = point_origimg0[:2]
cut_pts2d[j] = point_origimg1[:2]
cam3d_corners_update[i] = t_point[0,:3]
cam3d_corners_update[j] = t_point[-1,:3]
return cut_pts2d ,cam3d_corners_update
def cam2pixel(pts3d_cam, K):
pts2d_cam = K @ pts3d_cam
Z = pts2d_cam[2]
pts2d_cam = (pts2d_cam[:2] / Z).T
return pts2d_cam, Z
def nms_area(boxes,lables,area_thresh=0.9):
if len(boxes) < 2:
discard = []
return discard
# for i in range(boxes.shape[0]):
# if boxes[i][0] < 40 or boxes[i][3] > 3840 - 40:
# discard = []
# return discard
rect_boxes = np.array(boxes)
x1 = rect_boxes[:,0]
y1 = rect_boxes[:,1]
x2 = rect_boxes[:,2]
y2 = rect_boxes[:,3]
areas = (y2-y1+1)*(x2-x1+1)
discard = []
index = areas.argsort()[::-1] ##降序
for idx in index[1:]:
x11=np.maximum(x1[index[0]],x1[idx])
y11=np.maximum(y1[index[0]],y1[idx])
x22=np.minimum(x2[index[0]],x2[idx])
y22=np.minimum(y2[index[0]],y2[idx])
w=np.maximum(0,x22-x11+1)
h=np.maximum(0,y22-y11+1)
overlaps = w*h
iou=overlaps /areas[idx]
if iou > area_thresh:
if lables[index[0]] == lables[idx]:
discard.append(idx)
elif lables[index[0]] in ['Pedestrian','Rider'] and lables[idx] in ['Pedestrian','Rider']:
discard.append(idx)
elif lables[index[0]] in ['Bicycle','Rider'] and lables[idx] in ['Bicycle','Rider']:
discard.append(idx)
return discard
def Lidar2OrigImg(pts3d, lidar_to_cam, distort_param, K, origW, origH):
pts3d_cam = np.dot(lidar_to_cam[:3, :3],[pts3d[0],pts3d[1],pts3d[2]]) + lidar_to_cam[:3, 3]
# pts2d_cam = cam_img_kb(pts3d_cam[0],pts3d_cam[1],pts3d_cam[2],K,distort_param)
if len(distort_param)==5:
pts2d_cam = xyz_xy(pts3d_cam[0] /pts3d_cam[2], pts3d_cam[1] / pts3d_cam[2], distort_param, K)
else:
pts2d_cam = cam_img_kb(pts3d_cam[0],pts3d_cam[1],pts3d_cam[2],K,distort_param)
pts2d_cam = pts2d_cam[0:2]
pts2d_cam[0] = np.clip(pts2d_cam[0],0,origW-1)
pts2d_cam[1] = np.clip(pts2d_cam[1],0,origH-1)
return pts2d_cam, pts3d_cam
def Lidar2RectifyImg(pts3d, lidar_to_cam, K,origW, origH):
# R = np.array([[0, -1, 0],[-1, 0, 0],[0, 0, 1]])
pts3d_cam = np.dot(lidar_to_cam[:3, :3],[pts3d[0],pts3d[1],pts3d[2]]) + lidar_to_cam[:3, 3]
# pts3d_cam = lidar_to_cam[:3, :3] @ (pts3d.T) + lidar_to_cam[:3, 3].reshape(3, 1) # 1x3
pts2d_cam = K @ pts3d_cam
pts2d_cam[2] = np.clip(pts2d_cam[2],1,500)
pts2d_cam = (pts2d_cam[:2] / pts2d_cam[2]).T
pts2d_cam = pts2d_cam[0:2]
image_h, image_w = origH,origW
pts2d_cam[0] = np.clip(pts2d_cam[0],0,image_w-1)
pts2d_cam[1] = np.clip(pts2d_cam[1],0,image_h-1)
return pts2d_cam, pts3d_cam
def Calculate_vector_angle(vector_a ,vector_b):
dot_product = np.dot(vector_a, vector_b)
# 计算两个向量的范数(大小)
norm_a = np.linalg.norm(vector_a)
norm_b = np.linalg.norm(vector_b)
# 计算夹角的余弦值
cos_angle = dot_product / (norm_a * norm_b)
# 使用 arccos 计算角度,得到的结果是弧度
angle_radians = np.arccos(cos_angle)
# 将弧度转换为度
angle_degrees = np.degrees(angle_radians)
return angle_degrees
def angle2score(angle):
angle = (angle - 90)/90
angle = min(max(0,angle),1)
angle = np.sqrt(angle)
return angle
def drawPointBox(img, imgW, imgH, rect_corners, colors, thickness=1):
line_indices = ((4, 5), (5, 6), (6, 7), (7, 4), # 尾部
(0,4), (1,5), (2,6),(3,7),
(0, 1), (1, 2), (2, 3), (3, 0), (0, 2), (1, 3)) # 头部(1, 3),
border_x = imgW ####
border_y = imgH #####
for i in range(len(rect_corners)):
if int(rect_corners[i][0]) < 0 or int(rect_corners[i][0]) > border_x or int(rect_corners[i][1]) < 0 or int(rect_corners[i][1]) > border_y:
continue
# cv2.circle(img,(int(rect_corners[i][0]),int(rect_corners[i][1])),5,(255,0,0),2,cv2.LINE_8,0)
# cv2.putText(img, str(i), (int(rect_corners[i][0]+5),int(rect_corners[i][1] - 5)), 1, 1, (0, 0, 255), lineType=cv2.LINE_AA)
corners = rect_corners.astype(np.int32)
for start, end in line_indices:
try:
if (start,end) in [(0, 1), (1, 2), (2, 3), (3, 0),(0, 2), (1, 3)] and corners.shape[0]==8:
if int(corners[start, 0]) < 5 or int(corners[start, 0]) > (border_x - 5) or int(corners[start, 1]) < 5 or int(corners[start, 1]) > (border_y - 5):
continue
if int(corners[end, 0]) < 5 or int(corners[end, 0]) > (border_x - 5) or int(corners[end, 1]) < 5 or int(corners[end, 1]) > (border_y - 5):
continue
cv2.line(img, (corners[start, 0], corners[start, 1]),(corners[end, 0], corners[end, 1]), colors[1], thickness*2,cv2.LINE_AA)
else:
cv2.line(img, (corners[start, 0], corners[start, 1]),(corners[end, 0], corners[end, 1]), colors[0], thickness,cv2.LINE_AA)
except:
pass
return img
def showFace3Dbox(img,label_temp_all, cam_intrinsic, distortion_param, cam_rectify,origW,origH,pitch):
for co in label_temp_all:
label_det_cls,cx,cy,w,h =co[0], float(co[1])*origW,float(co[2])*origH,float(co[3])*origW,float(co[4])*origH
box2d= [cx-0.5*w,cy-0.5*h,cx+0.5*w,cy+0.5*h]
plot_box(box2d, img, label=str('%s'%label_det_cls), color=colors[label_det_cls], line_thickness=1)
# box2d_1=[[box2d[0],box2d[1]],[box2d[2],box2d[3]]]
# box2d_Rectify = cv2.undistortPoints(np.array(box2d_1).reshape(2,1,2), cam_intrinsic, distortion_param, None, cam_rectify).reshape((4,))
# plot_box(box2d_Rectify, img, label=str('%s'%label_det_cls), color=colors[label_det_cls], line_thickness=1)
pts2ds = []
if len(co)>6:
x3d_ori,y3d_ori,z3d_ori,l3d,h3d,w3d,rotation_y = float(co[5]),float(co[6]),float(co[7]),float(co[8]),float(co[9]),float(co[10]),float(co[11])
color = (0,0,0) if rotation_y <= 0 else (0,255,255)
corners = cam_corners_front_rear(np.array([x3d_ori,y3d_ori,z3d_ori,l3d,h3d,w3d,rotation_y]),'whole',pitch)
pts2ds = []
for i in range(corners.shape[0]):
x,y,z = corners[i]
if len(distortion_param)==5:
image_coord = xyz_xy(x/z,y/z,distortion_param,cam_intrinsic)
# image_coord = cam2RectifyImg(x/z,y/z,distortion_param,cam_rectify)
else:
image_coord = cam_img_kb(x,y,z,cam_intrinsic,distortion_param)
pts2ds.append([image_coord[0],image_coord[1]])
#####deal cutoff####
x_left = corners[:,0]>=-corners[:,2]*cam_rectify[0][2]/cam_rectify[0][0] # (8,)
x_right = corners[:,0]<=corners[:,2]*(origW-1-cam_rectify[0][2])/cam_rectify[0][0]
have_in = ((x_left & x_right)[[0,1,4,5]]==True).sum()
# po2ds = None
if have_in >= 1 and have_in < 4:
cut_pts2d,cam3d_corners_update= get_cutoff_corners(corners,pts2ds,cam_intrinsic,distortion_param,cam_rectify,origW,origH)
# cut_pts2d,cut_rect,cut_rectify_box3d, po2ds= get_cutoff_corners(corners,pts2ds_new,cam_intrinsic,distortion_param,cam_rectify,imgW,imgH)
if cut_pts2d is not None:
pts2ds = cut_pts2d
sqe = [6,7,4,5,2,3,0,1]
pts2ds = np.array(pts2ds)[sqe]
img = drawPointBox(img, origW, origH,np.array(pts2ds), colors=[(0, 0, 255), color], thickness=1)
if len(co)==50:
anchortype_index = ['front','tail','left','right']
value_3d_4face = co[18:50]
for jj in range(len(value_3d_4face)):
value_3d_4face[jj] = float(value_3d_4face[jj])
value_3d_4face = np.reshape(value_3d_4face,(4,-1))
for anchortype in range(len(value_3d_4face)):
x3d,y3d,z3d,alpha,xc,yc,score,is_good = value_3d_4face[anchortype]
xc,yc = max(0,min(origW-1,float(xc)*origW)),max(0,min(origH-1,float(yc)*origH))
if len(distortion_param)==5:
x3d_new ,y3d_new = xy_xyz(xc,yc,distortion_param,cam_intrinsic)
# x3d_new ,y3d_new = cam2RectifyImg(x/z,y/z,distortion_param,cam_rectify)
else:
x3d_new ,y3d_new = img_cam_kb(np.array([xc,yc]).reshape((-1, 2)),cam_intrinsic,distortion_param)
infer_x3d = x3d_new * z3d
infer_y3d = y3d_new * z3d
rotation_y = alpha + np.arctan2(infer_x3d, z3d)
if is_good == -1:
continue
if rotation_y<0:
color = (0,0,0)
else:
color = (0,255,255)
corners = cam_corners_front_rear(np.array([infer_x3d,infer_y3d,z3d, l3d,h3d,w3d, rotation_y]),anchortype_index[anchortype],pitch)
pts2ds_new = []
for i in range(corners.shape[0]):
x,y,z = corners[i]
if len(distortion_param)==5:
image_coord = xyz_xy(x/z,y/z,distortion_param,cam_intrinsic)
# image_coord = cam2RectifyImg(x/z,y/z,distortion_param,cam_rectify)
else:
image_coord = cam_img_kb(x,y,z,cam_intrinsic,distortion_param)
pts2ds_new.append([image_coord[0],image_coord[1]])
#####deal cutoff####
x_left = corners[:,0]>=-corners[:,2]*cam_rectify[0][2]/cam_rectify[0][0] # (8,)
x_right = corners[:,0]<=corners[:,2]*(origW-1-cam_rectify[0][2])/cam_rectify[0][0]
have_in = ((x_left & x_right)[[0,1,4,5]]==True).sum()
# po2ds = None
if have_in >= 1 and have_in < 4:
cut_pts2d,cam3d_corners_update= get_cutoff_corners(corners,pts2ds_new,cam_intrinsic,distortion_param,cam_rectify,origW,origH)
if cut_pts2d is not None:
pts2ds_new = cut_pts2d
sqe = [6,7,4,5,2,3,0,1]
pts2ds = np.array(pts2ds_new)[sqe]
img = drawPointBox(img, origW, origH,np.array(pts2ds), colors=[(0, 0, 255),color], thickness=1)
if len(distortion_param)==5:
[xc,yc] = xyz_xy(infer_x3d/z3d,infer_y3d/z3d,distortion_param,cam_intrinsic)
# [xc,yc] = cam2RectifyImg(infer_x3d/z3d,infer_y3d/z3d,distortion_param,cam_rectify)
else:
[xc,yc] = cam_img_kb(infer_x3d,infer_y3d,z3d,cam_intrinsic,distortion_param)
img = cv2.circle(img, (int(xc),int(yc)), 4, colors[int(anchortype)],-1)
return img
def mono3dlabel_trans2train(calib_path,anno):
# det_cls_map = { 'kVehicle':0,
# 'kPed':1,
# 'kBike':2,
# 'kCyclist':3,
# 'kCone':4,
# 'kRoadBarrier':4,
# 'kPedHead':5,
# 'kSmallTrafficSign': 6,
# 'kWarningTriangle' :6,
# 'kBigTrafficSign':7,
# 'kVehiclePlate' :8,
# 'kVehicleWheel':9,
# 'kTrafficLight':10,
# 'kTrafficLightBulb' :11,
# 'kTrafficLightDigit':12
# }
# det_cls_map = {
# "vehicle": 0,
# "head": 5,
# "plate": 8,
# "pedestrian": 1,
# "wheel": 9,
# "guideboard": 7,
# "bicycle": 2,
# "rider": 3,
# "roadpile": 4,
# "tsr": 6,
# "rickshaw": 0,
# }
det_cls_map ={
"vehicle": 0,
"head": 5,
"bicycle": 2,
"wheel": 9,
"plate": 8,
"rider": 3,
"pedestrian": 1,
"tsr": 6,
"guideboard": 7,
"roadpile": 4,
"waterbarrier": 4,
"tl_border": 10,
"tl_wick": 11,
"sphericalstone": 4,
"rickshaw": 0,
"roadblock": 4,
"cone": 4,
"crashbarrel": 4,
"tl_num": 12,
"carton": -1,
}
# det_cls_map = { 'vehicle':0,
# 'pedestrian':1,
# 'bicycle':2,
# 'rider':3,
# 'roadpile':4, 'warningtriangle':4, 'cone':4, 'crashbarrel':4,'waterbarrier':4, 'sphericalstone':4,'roadblock':4,
# 'head':5,
# 'tsr': 6,
# 'guideboard':7,
# 'plate' :8,
# 'wheel':9,
# 'tl_border':10,
# 'tl_wick' :11,
# 'tl_num':12,
# 'trailer':0,
# 'rickshaw':0,
# 'tinycar':0,
# 'carton':-1,'tire':-1,'barriergate':-1
# }
# det_cls_map = [
# "car", "tinycar", "bus", "van", "truck",
# "tanker", "large_truck", "construction_vehicle",
# "special_vehicle", "unknown", 'pedestrian', 'bicycle', "bicyclist",
# "motorcycle", "motorcyclist", "tricycle", "tricyclist",
# 'traffic_light_bbox', 'traffic_light_bulb',
# 'traffic_sign', 'animal', 'movable_object',
# 'warning_triangle', 'traffic_cone', 'water_barrier', 'crash_barrel',
# 'movable_barrier', 'bollard', 'sphere_bollard', 'cube_bollard',
# 'cylinder_bollard', 'construction_barrier', 'other_barrier',
# 'road_barrier_unknown', "wheel", "plate", "face"
# ]
if os.path.exists(anno):
text_basename = os.path.basename(anno)
print(text_basename)
text_split = text_basename.strip('_').split('_')
# try:
# calib_name = calib_path + '/' + 'calib.json'
# calib_params = json.load(open(calib_name, "r"))
# except:
# calib_name = calib_path + '/' + 'calib_pandar128_to_cam.json'
# calib_params = json.load(open(calib_name, "r"))
# cam_name = 'camera4'
# calib_param = calib_params[cam_name]
# lidar_to_cam = np.array(calib_param["Extrinsic"])
# cam_intrinsic = np.array(calib_param["Intrinsic"])
# distortion_param = np.array(calib_param["Distortion"])
# if 'D4Q' in text_basename and cam_name == 'camera4':
# origH,origW = 2160,3840
# cam_rectify = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(cam_intrinsic,distortion_param,[origW,origH],np.eye(3),balance=1) ####
# elif 'G1M2' in text_basename and cam_name == 'camera4':
# origH,origW = 1080,1920
# cam_rectify, _ = cv2.getOptimalNewCameraMatrix(cam_intrinsic,distortion_param, (origW,origH), 1, (origW,origH))
# elif 'G1M3' in text_basename and cam_name == 'camera4':
# origH,origW = 1080,1920
# cam_rectify = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(cam_intrinsic,distortion_param,[origW,origH],np.eye(3),balance=1)
# elif 'D4Q' in text_basename and cam_name == 'camera2':
# origH,origW = 1280,1920
# cam_rectify, _ = cv2.getOptimalNewCameraMatrix(cam_intrinsic,distortion_param, (origW,origH), 1, (origW,origH))
# else:
# print('error cam')
cam_name = 'camera4'
calib_param_vehicle = json.load(open(calib_path + '/' + '/L2_calib/camera4.json','r'))
ego_to_cam = get_rot_mat_and_trans(calib_param_vehicle)
cam_intrinsic = np.array([calib_param_vehicle['focal_u'], 0, calib_param_vehicle['cu'], 0, calib_param_vehicle['focal_v'], calib_param_vehicle['cv'], 0, 0, 1], dtype=np.float64).reshape(3, 3)
distortion_param = np.array(calib_param_vehicle['distort_coeffs'])
if 'G1M2' in text_basename and cam_name == 'camera4':
origH,origW = 1080,1920
cam_rectify, _ = cv2.getOptimalNewCameraMatrix(cam_intrinsic,distortion_param, (origW,origH), 1, (origW,origH))
elif 'G1M3' in text_basename and cam_name == 'camera4':
origH,origW = 1080,1920
cam_rectify = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(cam_intrinsic,distortion_param,[origW,origH],np.eye(3),balance=1)
objs = json.load(open(anno))['asso_list']
label_temp_all = []
for obj in objs:
label_temp = []
label_2d = obj['camera_mea']
confidence = label_2d['confidence']
try:
label_radar = obj['radar_mea']
except:
label_radar=None
label_lidar = obj['lidar_mea']
label_det_cls = det_cls_map[label_2d['cls']]
if label_det_cls == -1:
continue
# sublabel = subcls.get(label_2d['subcls']) ###'kTricycle' : 6 # 三轮车
box2d = [label_2d['det_pt_x'],label_2d['det_pt_y'],label_2d['det_pt_width'],label_2d['det_pt_height']]
box2d = [box2d[0] , box2d[1] , box2d[0] + box2d[2], box2d[1] + box2d[3]]
label_temp=[label_det_cls,min((box2d[0]+box2d[2])/(2*origW),1), min((box2d[1]+box2d[3])/(2*origH),1),min((box2d[2]-box2d[0])/origW,1), min((box2d[3]-box2d[1])/origH,1)]
# if label_radar is not None:
# radar_conf = label_radar['asso_conf']
# if radar_conf < 0.5:
# continue
# radar_x3d ,radar_y3d, radar_z3d= label_radar['x'],label_radar['y'],label_radar['z'] ###rear plane
# radarpoint = [radar_x3d ,radar_y3d, radar_z3d]
# radarpts2d , radarpts3d = Lidar2OrigImg(radarpoint,lidar_to_cam,distortion_param,cam_intrinsic, origW, origH)
# cv2.circle(img,(int(radarpts2d[0]),int(radarpts2d[1])),5,(255,0,0),2,cv2.LINE_8,0)
# cv2.putText(img, str('%.2f'%radarpts3d[2]), (int(radarpts2d[0]) + 5,int(radarpts2d[1]) - 5), 1, 1, (0, 0, 255))
if (label_lidar is not None) and label_det_cls<=3:
obj_lidar = [float(label_lidar[1]),float(label_lidar[2]),float(label_lidar[3]),float(label_lidar[4]),float(label_lidar[5]),float(label_lidar[6]),float(label_lidar[7])]
l3d,w3d,h3d = obj_lidar[3],obj_lidar[4],obj_lidar[5]
singleLW = int(float(label_lidar[11]))
yaw_lidar = obj_lidar[6]
Rz = np.array([
[np.cos(yaw_lidar), -np.sin(yaw_lidar), 0],
[np.sin(yaw_lidar), np.cos(yaw_lidar), 0],
[ 0, 0, 1.0],
]) #############lidar Z轴对应 cam Y轴 顺时针
RotateZ =np.dot(ego_to_cam[:3, :3],Rz) ##lidar yaw 累加旋转矩阵
orientation = Quaternion(matrix=RotateZ)
rotation_y = -orientation.yaw_pitch_roll[0] # convert the rot to our cam coordinate
campts2d , campts3d = Vehicle2OrigImg(np.array([obj_lidar[0],obj_lidar[1],obj_lidar[2]]), ego_to_cam, distortion_param, cam_intrinsic, origW, origH)
campts2d_di, campts3d_di = Vehicle2OrigImg(np.array([obj_lidar[0],obj_lidar[1],obj_lidar[2] - 0.5 * h3d]),ego_to_cam, distortion_param, cam_intrinsic, origW, origH)
# campts2d , campts3d = Lidar2OrigImg(np.array([obj_lidar[0],obj_lidar[1],obj_lidar[2]]), lidar_to_cam, distortion_param, cam_intrinsic, origW, origH)
# campts2d_di, campts3d_di = Lidar2OrigImg(np.array([obj_lidar[0],obj_lidar[1],obj_lidar[2] - 0.5 * h3d]),lidar_to_cam, distortion_param, cam_intrinsic, origW, origH)
box3d_cam = [campts3d[0], campts3d[1], campts3d[2],l3d,h3d,w3d,rotation_y]
alpha = -np.arctan2(campts3d[0],campts3d[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
x3d_ori,y3d_ori,z3d_ori,l3d,h3d,w3d,rotation_y,alpha,singleLW = campts3d[0], campts3d[1], campts3d[2],l3d,h3d,w3d,rotation_y,alpha,singleLW
label_temp = label_temp + [x3d_ori,y3d_ori,z3d_ori,l3d,h3d,w3d,rotation_y,campts2d[0]/origW,campts2d[1]/origH,campts2d_di[0]/origW,campts2d_di[1]/origH,alpha]
# cy = (box2d[1]+box2d[3])/2.0
# if len(distortion_param)==5:
# image_coord = xyz_xy(x3d_ori/z3d_ori , y3d_ori/z3d_ori, distortion_param,cam_intrinsic)
# x3d_new ,y3d_new = xy_xyz(image_coord[0],cy,distortion_param,cam_intrinsic)
# else:
# image_coord = cam_img_kb(x3d_ori,y3d_ori,z3d_ori,cam_intrinsic,distortion_param)
# x3d_new ,y3d_new = img_cam_kb(np.array([image_coord[0],cy]).reshape((-1, 2)),cam_intrinsic,distortion_param)
# infer_y3d = y3d_new * z3d_ori
# box3d_cam[1] = infer_y3d
corners = cam_corners_front_rear(np.array(box3d_cam),'whole', pitch=0)
if label_det_cls !=0:
label_temp = label_temp + [-1] + [confidence]
else:
xyz3d_0 = np.mean(corners[4:8,:],axis=0) ### Front_point
xyz3d_1 = np.mean(corners[0:4,:],axis=0) ### Back_point
xyz3d_2 = np.mean((corners[1,:],corners[2,:],corners[5,:],corners[6,:]),axis=0) ### Left_point
xyz3d_3 = np.mean((corners[0,:],corners[4,:],corners[3,:],corners[7,:]),axis=0) ### Right_point
xyz3d_4face = [xyz3d_0,xyz3d_1,xyz3d_2,xyz3d_3]
value_3d_4face = []
x_left = corners[:,0]>=-corners[:,2]*cam_rectify[0][2]/cam_rectify[0][0] # (8,)
x_right = corners[:,0]<=corners[:,2]*(origW-1-cam_rectify[0][2])/cam_rectify[0][0]
x_down = corners[:,1]<=corners[:,2]*(origH-1-cam_rectify[1][2])/cam_rectify[1][1]
have_in = ((x_left & x_right)[[0,1,4,5]]==True).sum()
#####################
x_front_1 = corners[4:8,0]>=-corners[4:8,2]*cam_rectify[0][2]/cam_rectify[0][0]
x_front_2 = corners[4:8,0]<=corners[4:8,2]*(origW-1-cam_rectify[0][2])/cam_rectify[0][0]
have_in_front = ((x_front_1 & x_front_2)[[0,1,2,3]]==True).sum()
y_front = corners[4:8,1]<=corners[4:8,2]*(origH-5-cam_rectify[1][2])/cam_rectify[1][1]
y_front_center = xyz3d_0[1]<=xyz3d_0[2]*(origH-5-cam_rectify[1][2])/cam_rectify[1][1]
x_tail_1 = corners[0:4,0]>=-corners[0:4,2]*cam_rectify[0][2]/cam_rectify[0][0]
x_tail_2 = corners[0:4,0]<=corners[0:4,2]*(origW-1-cam_rectify[0][2])/cam_rectify[0][0]
y_tail = corners[0:4,1]<=corners[0:4,2]*(origH-5-cam_rectify[1][2])/cam_rectify[1][1]
y_tail_center = xyz3d_1[1]<=xyz3d_1[2]*(origH-5-cam_rectify[1][2])/cam_rectify[1][1]
have_in_tail = ((x_tail_1 & x_tail_2)[[0,1,2,3]]==True).sum()
#####################
anchorpoint = [x3d_ori, y3d_ori, z3d_ori]
if have_in >= 1 and have_in < 4: ######切车
if y_front_center.sum() == 1 or y_tail_center.sum() == 1:
if have_in_tail < 4 and have_in_front==4:
anchorpoint = xyz3d_0
alpha = -np.arctan2(anchorpoint[0],anchorpoint[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
score = 1
if len(distortion_param)==5:
[xc,yc] = xyz_xy(anchorpoint[0]/anchorpoint[2],anchorpoint[1]/anchorpoint[2],distortion_param,cam_intrinsic)
else:
[xc,yc] = cam_img_kb(anchorpoint[0],anchorpoint[1],anchorpoint[2],cam_intrinsic,distortion_param)
xc,yc = xc/origW,yc/origH
value_3d_face = [anchorpoint[0],anchorpoint[1],anchorpoint[2],alpha,xc,yc,score,1]
value_3d_4face.append(value_3d_face)
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
elif have_in_tail == 4 and have_in_front<4:
anchorpoint = xyz3d_1
alpha = -np.arctan2(anchorpoint[0],anchorpoint[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
score = 1
if len(distortion_param)==5:
[xc,yc] = xyz_xy(anchorpoint[0]/anchorpoint[2],anchorpoint[1]/anchorpoint[2],distortion_param,cam_intrinsic)
else:
[xc,yc] = cam_img_kb(anchorpoint[0],anchorpoint[1],anchorpoint[2],cam_intrinsic,distortion_param)
xc,yc = xc/origW,yc/origH
value_3d_face = [anchorpoint[0],anchorpoint[1],anchorpoint[2],alpha,xc,yc,score,1]
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append(value_3d_face)
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
else:
if 'G1M2' in text_basename and (x_down.sum() < 8 and rotation_y < 0 and y_tail.sum() < 4 and y_front_center.sum() == 1): ####G1M2车尾底边被截断###
anchorpoint = xyz3d_0
alpha = -np.arctan2(anchorpoint[0],anchorpoint[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
score = 1
if len(distortion_param)==5:
[xc,yc] = xyz_xy(anchorpoint[0]/anchorpoint[2],anchorpoint[1]/anchorpoint[2],distortion_param,cam_intrinsic)
else:
[xc,yc] = cam_img_kb(anchorpoint[0],anchorpoint[1],anchorpoint[2],cam_intrinsic,distortion_param)
xc,yc = xc/origW,yc/origH
value_3d_face = [anchorpoint[0],anchorpoint[1],anchorpoint[2],alpha,xc,yc,score,1]
value_3d_4face.append(value_3d_face)
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
elif 'G1M2' in text_basename and (x_down.sum() < 8 and rotation_y > 0 and y_front.sum() == 4 and y_tail_center.sum() == 1): ####G1M2车头底边被截断###
anchorpoint = xyz3d_1
alpha = -np.arctan2(anchorpoint[0],anchorpoint[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
score = 1
if len(distortion_param)==5:
[xc,yc] = xyz_xy(anchorpoint[0]/anchorpoint[2],anchorpoint[1]/anchorpoint[2],distortion_param,cam_intrinsic)
else:
[xc,yc] = cam_img_kb(anchorpoint[0],anchorpoint[1],anchorpoint[2],cam_intrinsic,distortion_param)
xc,yc = xc/origW,yc/origH
value_3d_face = [anchorpoint[0],anchorpoint[1],anchorpoint[2],alpha,xc,yc,score,1]
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append(value_3d_face)
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
value_3d_4face.append([-1,-1,-1,-1,-1,-1,0,-1])
elif (rotation_y < 0 and y_front_center.sum() == 0) or (rotation_y > 0 and y_tail_center.sum() == 0):
value_3d_4face = []
else:
for xyz3d in xyz3d_4face:
angle = Calculate_vector_angle(np.array([xyz3d[0] - x3d_ori, xyz3d[2] - z3d_ori]), np.array([xyz3d[0], xyz3d[2]]))
score = angle2score(angle)
alpha = -np.arctan2(xyz3d[0],xyz3d[2]) + rotation_y
if alpha<-np.pi:
alpha+=2*np.pi
if alpha>np.pi:
alpha-=2*np.pi
if len(distortion_param)==5:
[xc,yc] = xyz_xy(xyz3d[0]/xyz3d[2],xyz3d[1]/xyz3d[2],distortion_param,cam_intrinsic)
else:
[xc,yc] = cam_img_kb(xyz3d[0],xyz3d[1],xyz3d[2],cam_intrinsic,distortion_param)
xc,yc = xc/origW,yc/origH
value_3d_face = [xyz3d[0],xyz3d[1],xyz3d[2],alpha,xc,yc,score,1]
value_3d_4face.append(value_3d_face)
value_3d_4face = np.array(value_3d_4face)
if singleLW == 0: #####L W Believable
value_3d_4face = value_3d_4face
elif singleLW == 1: #####L Believable
value_3d_4face[0:2,7] = -1
elif singleLW == 2: #####W Believable
value_3d_4face[2:4,7] = -1
label_temp.append(singleLW)
side_diff = np.min((abs(0-box2d[0]),abs(origW-box2d[2])))
value_3d_4face = np.array(value_3d_4face)
################################
if 'G1M2' in text_basename or 'D4Q' in text_basename:
side_diff_threshold = 12
elif 'G1M3' in text_basename:
side_diff_threshold = 70
if len(value_3d_4face)!=0:
if have_in >= 1 and have_in < 4:
# if np.sum(value_3d_4face[:,-1])==-2 and np.sum(value_3d_4face[:,-2]) == 1:
if side_diff>side_diff_threshold and abs(rotation_y) >= 0.785 and abs(rotation_y)<= 2.355: ##45
label_temp = label_temp[0:6]
label_temp[5]=-1
# print(annotations)
elif not(np.sum(value_3d_4face[:,-1])==-2 and np.sum(value_3d_4face[:,-2]) == 1) :
if side_diff<side_diff_threshold:
label_temp = label_temp[0:6]
label_temp[5]=-1
else:
label_temp = label_temp[0:6]
label_temp[5]=-1
if len(label_temp)>6:
for value_3d_face in value_3d_4face:
for value_3d in value_3d_face:
label_temp.append(value_3d)
label_temp.append(confidence)
else:
label_temp.append(-1)
label_temp.append(confidence)
label_temp_all.append(label_temp)
return label_temp_all
# if Labelshow:
# outpath = '/data1/xdzhu/Data/Mono3D_G1M2/mono3d_show_for_changepoint_0221_0311/'
# if not os.path.exists(outpath):
# os.makedirs(outpath)
# img = cv2.imread(anno.replace('annotations','images')[0:-5] + '.jpg' )
# img = showFace3Dbox(img,label_temp_all, cam_intrinsic, distortion_param, cam_rectify,origW,origH,pitch)
# ###
# # map_1, map_2 = cv2.initUndistortRectifyMap(cam_intrinsic, distortion_param, np.eye(3), cam_rectify, [1920,1080],cv2.CV_32FC1)
# # undistorted_image = cv2.remap(img, map_1, map_2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
# # undistorted_image = showFace3Dbox(undistorted_image,label_temp_all, cam_intrinsic, distortion_param, cam_rectify,origW,origH)
# ###
# cv2.imwrite(outpath + '/' + os.path.basename(anno)[0:-5] + '.jpg',img)
def analysis_depth(depth_path):
depth_data = np.load(depth_path)
return depth_data['arr_0']
def process_annotation_file(anno_file):
"""
处理单个JSON标注文件转换为TXT标签格式
参数:
anno_file: 单个JSON标注文件的完整路径
返回:
tuple: (anno_file, success: bool, message: str)
"""
try:
# 拆分路径和文件名,替代字符串切片,更健壮
anno_dir, anno_name = os.path.split(anno_file)
# 构建labels目录路径替换annotations为labels
label_dir = anno_dir.replace('annotations_20260320', 'labels_20260320')
# 确保目录存在不存在则创建exist_ok=True避免重复创建报错
os.makedirs(label_dir, exist_ok=True)
# (可选)图片存在性校验,如需启用可取消注释
# img_path = anno_file.replace('annotations', 'images/camera4')[:-5] + '.png'
# if not os.path.exists(img_path):
# return (anno_file, True, "跳过:对应图片不存在")
# 构建标定文件路径
calib_dir = anno_dir.replace('annotations_20260320', 'calib')
# 调用转换函数生成标签列表
label_lists = mono3dlabel_trans2train(calib_dir, anno_file)
# 拼接标签字符串
label_str = ''
for ll in label_lists:
# 优化字符串拼接用join更高效
ll_str = ' '.join([str(item) for item in ll[:-1]]) + ' ' + str(ll[-1]) + '\n'
label_str += ll_str
# 构建输出TXT文件路径
txt_filename = anno_name[:-5] + '.txt' # 去掉.json后缀加.txt
txt_filepath = os.path.join(label_dir, txt_filename)
# 写入标签文件使用with语句自动关闭文件避免手动close遗漏
with open(txt_filepath, 'w+', encoding='utf-8') as fw:
fw.write(label_str)
return (anno_file, True, "处理成功")
except Exception as e:
# 捕获所有异常,记录详细错误信息
error_detail = f"{str(e)}\n{traceback.format_exc()}"
return (anno_file, False, f"处理失败:{error_detail}")
def main():
"""
主函数:初始化进程池,分发处理任务
"""
# 1. 获取所有待处理的JSON文件并排序
JSON_ROOT_PATH = '/data1/dongying/Mono3d/G1M3/Testdata_0129/'
json_pattern = os.path.join(JSON_ROOT_PATH, '019b4e2c-f464-7aea-af9f-e61135bb3eed', 'annotations_20260320', '*.json')
annotations = glob.glob(json_pattern)
annotations.sort()
# 2. 基础校验
total_files = len(annotations)
if total_files == 0:
print("⚠️ 未找到任何JSON标注文件程序退出")
return
print(f"📌 共发现 {total_files} 个JSON标注文件待处理")
# 3. 设置进程数IO密集型任务设为CPU核心数的2-4倍避免进程数过多导致调度开销
# num_processes = min(cpu_count() * 2, total_files)
num_processes = 1
print(f"🚀 启动 {num_processes} 个进程并行处理...")
# 4. 启动进程池处理任务
with Pool(processes=num_processes) as pool:
# 使用imap_unordered实时获取处理结果便于监控进度
results = []
for idx, result in enumerate(pool.imap_unordered(process_annotation_file, annotations), 1):
file_path, success, msg = result
# 打印进度和状态
status = "" if success else ""
print(f"进度: {idx}/{total_files} | {status} {os.path.basename(file_path)} - {msg}")
results.append(result)
# 5. 统计最终结果
success_count = sum(1 for r in results if r[1])
fail_count = total_files - success_count
print("\n" + "="*60)
print(f"📊 处理完成 | 成功:{success_count} | 失败:{fail_count}")
# 6. 打印失败文件列表(便于排查)
if fail_count > 0:
failed_files = [r[0] for r in results if not r[1]]
print(f"❌ 失败文件列表:{failed_files}")
if __name__ == "__main__":
# 多进程必须在该判断内执行避免Windows系统递归创建进程
# 需确保mono3dlabel_trans2train函数可被子进程导入/访问
main()
# if __name__ == '__main__':
# ##calib path ####
# jsonpath = '/mnt/smb/xdzhu_data/Mono3d/Mono3d_4face_2m_g1m3/discard_erro/G1M3_FDL2232/'
# annotations = glob.glob(jsonpath + '20251201/*/annotations/*.json')
# annotations.sort()
# for anno in annotations:
# # context = anno.split('/')
# # tag = context[-3]
# path,annoname = os.path.split(anno)
# labelpath = path.replace('annotations','labels')
# calib_path = path.replace('annotations','calib')
# calib_path = calib_path.replace('discard_erro','driving_png_20260202')
# if not os.path.exists(labelpath):
# os.mkdir(labelpath)
# imgpath = anno.replace('annotations','images')[0:-5] + '.png'
# if not os.path.exists(imgpath):
# continue
# jsonname = os.path.basename(anno)
# labellists = mono3dlabel_trans2train(calib_path,anno)
# # strs = ''
# # for ll in labellists:
# # for i in range(len(ll) - 1):
# # strs += str(ll[i]) + ' '
# # strs += str(ll[-1]) + '\n'
# # fw = open(labelpath + '/' + jsonname[:-5] + '.txt','w+')
# # fw.write(strs)
# # fw.close()
# if __name__ == '__main__': ####GT
# ##calib path ####
# jsonpath = '/mnt/smb/xdzhu_data/Mono3d/Mono3d_4face_2m_g1m3/driving_png_20260207/G1M3_FDL2232/20251210/019b092a-4bb3-7e06-af6b-99b53dd0a18c/'
# labelpath = '/mnt/smb/xdzhu_data/Mono3d/Mono3d_4face_2m_g1m3/driving_png_20260207/G1M3_FDL2232/20251210/019b092a-4bb3-7e06-af6b-99b53dd0a18c/'
# annotations = glob.glob(jsonpath + '/annotations/*.json')
# annotations.sort()
# for anno in annotations:
# path,annoname = os.path.split(anno)
# labelpath = path.replace('annotations','labels')
# if not os.path.exists(labelpath):
# os.mkdir(labelpath)
# # imgpath = anno.replace('annotations','images/camera4')[0:-5] + '.png'
# # if not os.path.exists(imgpath):
# # continue
# calib_path = path.replace('annotations','calib')
# jsonname = os.path.basename(anno)
# labellists = mono3dlabel_trans2train(calib_path,anno)
# strs = ''
# for ll in labellists:
# for i in range(len(ll) - 1):
# strs += str(ll[i]) + ' '
# strs += str(ll[-1]) + '\n'
# fw = open(labelpath + '/' + jsonname[:-5] + '.txt','w+')
# fw.write(strs)
# fw.close()
#############################show#######################################
# jsonpath = '/data1/xdzhu/Data/Mono3D_G1M2/Train_Data/'
# showpath = '/data1/xdzhu/Data/Mono3D_G1M2_test/'
# annotations = glob.glob(jsonpath + '20250222/annotations/*.json')
# annotations.sort()
# for anno in annotations:
# if 'G1M2_AU4010_20250222_seq_33_camera4_001954_405946' not in anno :
# continue
# print(anno)
# mono3dlabel_trans2train(anno,showpath)