3D目标检测——代码理解——Second代码:数据处理kitti_dataset.py的理解
3D目标检测—代码理解—Second代码:数据处理kitti_dataset.py的理解
Second代码的github地址:Second代码的github地址
Second文章的链接:Second文章的链接
目前是刚研究3D点云数据的处理,将自己的理解分享出来,如果有理解有误的地方,还请大家多多批评指正。
- dataset.py的部分:
import pathlib
import pickle
import time
from functools import partialimport numpy as npfrom second.core import box_np_ops
from second.core import preprocess as prep
from second.data import kitti_common as kittiREGISTERED_DATASET_CLASSES = {}def register_dataset(cls, name=None):global REGISTERED_DATASET_CLASSESif name is None:name = cls.__name__assert name not in REGISTERED_DATASET_CLASSES, f"exist class: {REGISTERED_DATASET_CLASSES}"REGISTERED_DATASET_CLASSES[name] = clsreturn clsdef get_dataset_class(name):global REGISTERED_DATASET_CLASSESassert name in REGISTERED_DATASET_CLASSES, f"available class: {REGISTERED_DATASET_CLASSES}"return REGISTERED_DATASET_CLASSES[name]class Dataset(object):"""An abstract class representing a pytorch-like Dataset.All other datasets should subclass it. All subclasses should override``__len__``, that provides the size of the dataset, and ``__getitem__``,supporting integer indexing in range from 0 to len(self) exclusive.这是一个基类,其他的数据集的类要继承该类所有子类都应覆盖提供数据集大小的__len__和支持从0到len(self)范围内的整数索引的__getitem__。"""NumPointFeatures = -1def __getitem__(self, index):"""This function is used for preprocess.you need to create a input dict in this function for network inference.format: {anchors 框的信息voxels 体素的信息num_points 点云的数量coordinates 坐标的信息if training: 如果训练:labels 标签的信息reg_targets[optional]anchors_mask, slow in SECOND v1.5, don't use this.[optional]metadata, in kitti, image index is saved in metadata}该函数为输入数据做准备,input,输入的数据应该是一个字典,包含:"""raise NotImplementedErrordef __len__(self):raise NotImplementedErrordef get_sensor_data(self, query):"""Dataset must provide a unified function to get data.将数据集的格式进行统一Args:query: int or dict. this param must support int for training.if dict, should have this format (no example yet): {sensor_name: {sensor_meta}}if int, will return all sensor data. (TODO: how to deal with unsynchronized data?)Returns:sensor_data: dict. 返回的是传感器的数据,数据的类型是字典if query is int (return all), return a dict with all sensors: {sensor_name: sensor_data...metadata: ... (for kitti, contains image_idx)}如果传感器是雷达if sensor is lidar (all lidar point cloud must be concatenated to one array): e.g. If your dataset have two lidar sensor, you need to return a single dict:{"lidar": {"points": ......}}sensor_data: {points: [N, 3+][optional]annotations: {"boxes": [N, 7] locs, dims, yaw, in lidar coord system. must testedin provided visualization tools such as second.utils.simplevisor web tool."names": array of string.}}如果传感器是相机if sensor is camera (not used yet):sensor_data: {data: image string (array is too large)[optional]annotations: {"boxes": [N, 4] 2d bbox"names": array of string.}}metadata: {# dataset-specific information.# for kitti, must have image_idx for label file generation.image_idx: ...}[optional]calib # only used for kitti"""raise NotImplementedErrordef evaluation(self, dt_annos, output_dir):"""Dataset must provide a evaluation function to evaluate model."""raise NotImplementedError
- kitti_dataset.py的部分:
from pathlib import Path
import pickle
import time
from functools import partialimport numpy as npfrom second.core import box_np_ops
from second.core import preprocess as prep
from second.data import kitti_common as kitti
from second.utils.eval import get_coco_eval_result, get_official_eval_result
from second.data.dataset import Dataset, register_dataset
from second.utils.progress_bar import progress_bar_iter as prog_bar@register_dataset
class KittiDataset(Dataset):NumPointFeatures = 4def __init__(self,root_path,info_path,class_names=None,prep_func=None,num_point_features=None):#如果保存文件的路径是空,直接报错assert info_path is not None# 把文件的内容读取出来,存在infos里面,再赋值给_kitti_infoswith open(info_path, 'rb') as f:infos = pickle.load(f)self._root_path = Path(root_path)self._kitti_infos = infosprint("remain number of infos:", len(self._kitti_infos))self._class_names = class_namesself._prep_func = prep_funcdef __len__(self):return len(self._kitti_infos)# 该函数作用:将预测得到的信息 转化为 kitti的格式def convert_detection_to_kitti_annos(self, detection):class_names = self._class_names# 把预测:detection中每一帧的内容的det["metadata"]["image_idx"] 提取成一个列表det_image_idxes = [det["metadata"]["image_idx"] for det in detection]# 把真实:info中每一帧的内容的info["metadata"]["image_idx"] 提取成一个列表gt_image_idxes = [info["image"]["image_idx"] for info in self._kitti_infos]annos = []# 对于每一帧数据进行操作for i in range(len(detection)):det_idx = det_image_idxes[i]#det中存放的是这一帧数据的预测值det = detection[i]# info中存放的是这一帧数据中的真实值info = self._kitti_infos[i]# 取出这一帧数据里面的 相机参数calib = info["calib"]rect = calib["R0_rect"]Trv2c = calib["Tr_velo_to_cam"]P2 = calib["P2"]#将预测得到的参数取出,detach()函数是返回一个新的tensor,# 从当前计算图中分离下来的,但是仍指向原变量的存放位置,final_box_preds = det["box3d_lidar"].detach().cpu().numpy()label_preds = det["label_preds"].detach().cpu().numpy()scores = det["scores"].detach().cpu().numpy()if final_box_preds.shape[0] != 0:# 对数据进行 数据运算final_box_preds[:, 2] -= final_box_preds[:, 5] / 2# 将box 从雷达坐标系 转化为相机坐标系box3d_camera = box_np_ops.box_lidar_to_camera(final_box_preds, rect, Trv2c)# 获取在相机坐标系下的 位置、尺寸和转角locs = box3d_camera[:, :3]dims = box3d_camera[:, 3:6]angles = box3d_camera[:, 6]# 设置相机box的范围camera_box_origin = [0.5, 1.0, 0.5]box_corners = box_np_ops.center_to_corner_box3d(locs, dims, angles, camera_box_origin, axis=1)box_corners_in_image = box_np_ops.project_to_image(box_corners, P2)# box_corners_in_image: [N, 8, 2]minxy = np.min(box_corners_in_image, axis=1)maxxy = np.max(box_corners_in_image, axis=1)# 以上的操作是通过预测的结果,获取二维框的四个坐标信息bbox# Bbox中存放的是这一帧中所有物体的预测Bbox的信息值bbox = np.concatenate([minxy, maxxy], axis=1)# 获取一个空字典,用来存放一帧的数据anno = kitti.get_start_result_anno()num_example = 0box3d_lidar = final_box_preds # 将这一帧中 预测框的3D信息赋值给box3d_lidar# 对于这一帧中 每一个物体的3D预测框,# 最后得到这一帧中 kitti数据格式下的信息,包含所有物体for j in range(box3d_lidar.shape[0]):# 将真实的image形状进行赋值image_shape = info["image"]["image_shape"]#判断预测和真实的Bbox的信息,不符合的进行跳过if bbox[j, 0] > image_shape[1] or bbox[j, 1] > image_shape[0]:continueif bbox[j, 2] < 0 or bbox[j, 3] < 0:continue# 通过比较和计算后,为Bbox赋值bbox[j, 2:] = np.minimum(bbox[j, 2:], image_shape[::-1])bbox[j, :2] = np.maximum(bbox[j, :2], [0, 0])# 将计算得到的信息都添加到 空字典中anno["bbox"].append(bbox[j])# convert center format to kitti format# box3d_lidar[j, 2] -= box3d_lidar[j, 5] / 2anno["alpha"].append( -np.arctan2(-box3d_lidar[j, 1], box3d_lidar[j, 0]) + box3d_camera[j, 6])anno["dimensions"].append(box3d_camera[j, 3:6])anno["location"].append(box3d_camera[j, :3])anno["rotation_y"].append(box3d_camera[j, 6])anno["name"].append(class_names[int(label_preds[j])])anno["truncated"].append(0.0)anno["occluded"].append(0)anno["score"].append(scores[j])num_example += 1# 如果 该帧中预测的物体个数不为0,则将预测的信息添加到annos中# ,否则,添加一个空的信息if num_example != 0:anno = {n: np.stack(v) for n, v in anno.items()}annos.append(anno)else:annos.append(kitti.empty_result_anno())num_example = annos[-1]["name"].shape[0]annos[-1]["metadata"] = det["metadata"]return annos# 评价函数evaluation,需要将格式统一def evaluation(self, detections, output_dir):"""detectionWhen you want to eval your own dataset, you MUST set correctthe z axis and box z center.If you want to eval by my KITTI eval function, you must provide the correct format annotations.ground_truth_annotations format:{bbox: [N, 4], if you fill fake data, MUST HAVE >25 HEIGHT!!!!!!alpha: [N], you can use -10 to ignore it.occluded: [N], you can use zero.truncated: [N], you can use zero.name: [N]location: [N, 3] center of 3d box.dimensions: [N, 3] dim of 3d box.rotation_y: [N] angle.}all fields must be filled, but some fields can fill zero."""# 如果一帧数据中没有annos,直接返回空,实际上都有if "annos" not in self._kitti_infos[0]:return None# 获取真实集中的annos的数据信息gt_annos = [info["annos"] for info in self._kitti_infos]# 根据预测得到的结果,获取转化为kitti格式后的预测annos的数据信息dt_annos = self.convert_detection_to_kitti_annos(detections)# firstly convert standard detection to kitti-format dt annosz_axis = 1 # KITTI camera format use y as regular "z" axis.z_center = 1.0 # KITTI camera box's center is [0.5, 1, 0.5]# for regular raw lidar data, z_axis = 2, z_center = 0.5.# 下面是通过两种方式进行验证 evalresult_official_dict = get_official_eval_result(gt_annos,dt_annos,self._class_names,z_axis=z_axis,z_center=z_center)result_coco = get_coco_eval_result(gt_annos,dt_annos,self._class_names,z_axis=z_axis,z_center=z_center)# 返回一个大字典,里面包含两个小字典: results和detailreturn {"results": {"official": result_official_dict["result"],"coco": result_coco["result"],},"detail": {"eval.kitti": {"official": result_official_dict["detail"],"coco": result_coco["detail"]}},}# 根据帧的序列,获取该帧的所有信息,并做进一步处理,传给exampledef __getitem__(self, idx):# 根据序列,获取了该帧数据中的全部信息input_dict = self.get_sensor_data(idx)# ??????? 什么意思??大概是将用于输入的数据进行赋值example = self._prep_func(input_dict=input_dict)# 将该键中的值设为空,然后再根据条件进行填充example["metadata"] = {}if "image_idx" in input_dict["metadata"]:example["metadata"] = input_dict["metadata"]if "anchors_mask" in example:example["anchors_mask"] = example["anchors_mask"].astype(np.uint8)return example# 根据序列号,将数据转化为要求的input格式def get_sensor_data(self, query):read_image = Falseidx = queryif isinstance(query, dict):# 如果query 是字典类型read_image = "cam" in query # 如果cam是该字典中的键,则返回true,意思是数据集中包含图像assert "lidar" in query # 如果没有雷达数据lidar,则直接报错idx = query["lidar"]["idx"] # 将数据中的索引号进行赋值,即具体的某一帧的索引值# 获取这一帧的数据信息 infoinfo = self._kitti_infos[idx] # 定义一个字典,且该字典包含一些属性信息 res = {"lidar": {"type": "lidar","points": None,},"metadata": {"image_idx": info["image"]["image_idx"],"image_shape": info["image"]["image_shape"],},"calib": None,"cam": {}}pc_info = info["point_cloud"] # 将点云数据赋值出来velo_path = Path(pc_info['velodyne_path']) #获取存有该雷达数据的文件的路径# 如果不是绝对路径,则修改为绝对路径(以/开头的路径)if not velo_path.is_absolute():velo_path = Path(self._root_path) / pc_info['velodyne_path']# 获取雷达信息的另一个文件(_reduced)路径velo_reduced_path = velo_path.parent.parent / (velo_path.parent.stem + '_reduced') / velo_path.name# 如果该文件存在,则雷达路径velo_path为velo_reduced_path的路径if velo_reduced_path.exists():velo_path = velo_reduced_path#通过雷达的文件路径读取信息,并且获得点云数据points = np.fromfile(str(velo_path), dtype=np.float32,count=-1).reshape([-1, self.NumPointFeatures])# 将点云数据 赋值到 字典中去res["lidar"]["points"] = points# 获取这一帧中的image信息,以及相应的文件的路径image_info = info["image"]image_path = image_info['image_path']# 如果读取图像,先获取文件的路径,再读取文件到image_strif read_image:image_path = self._root_path / image_pathwith open(str(image_path), 'rb') as f:image_str = f.read()res["cam"] = {"type": "camera","data": image_str,"datatype": image_path.suffix[1:], # 获取文件路径名的后缀,得到的结果如:png,jpg之类的}# 获取这一帧中相机参数标定的相关数据,并添加到res的字典里面calib = info["calib"]calib_dict = {'rect': calib['R0_rect'],'Trv2c': calib['Tr_velo_to_cam'],'P2': calib['P2'],}res["calib"] = calib_dict# 如果info里包含annos:if 'annos' in info:# 获取annos的信息annos = info['annos']# we need other objects to avoid collision when sample# 去掉其中 dontcare的信息annos = kitti.remove_dontcare(annos)# 获取 位置、尺寸、转向角、类别名字的信息locs = annos["location"]dims = annos["dimensions"]rots = annos["rotation_y"]gt_names = annos["name"]# rots = np.concatenate([np.zeros([locs.shape[0], 2], dtype=np.float32), rots], axis=1)# 将信息转换成 (N,7)的数据格式gt_boxes = np.concatenate([locs, dims, rots[..., np.newaxis]],axis=1).astype(np.float32)calib = info["calib"] # 获取相机标定的一些参数# 将相机坐标系下的gt_boxes转换成雷达坐标系下的参数gt_boxes,得到的结果还是(N,7)gt_boxes = box_np_ops.box_camera_to_lidar(gt_boxes, calib["R0_rect"], calib["Tr_velo_to_cam"])# 再对数据做进一步的转化,但该函数没有返回值,所以为啥还要这一步呢???????# only center format is allowed. so we need to convert# kitti [0.5, 0.5, 0] center to [0.5, 0.5, 0.5]box_np_ops.change_box3d_center_(gt_boxes, [0.5, 0.5, 0],[0.5, 0.5, 0.5])# 再添加信息到res中,并返回该值,该值中包含了一帧数据中的全部信息res["lidar"]["annotations"] = {'boxes': gt_boxes,'names': gt_names,}res["cam"]["annotations"] = {'boxes': annos["bbox"],'names': gt_names,}return res# convert kitti info v1 to v2 if possible.
def convert_to_kitti_info_version2(info):"""convert kitti info v1 to v2 if possible."""if "image" not in info or "calib" not in info or "point_cloud" not in info:info["image"] = {'image_shape': info["img_shape"],'image_idx': info['image_idx'],'image_path': info['img_path'],}info["calib"] = {"R0_rect": info['calib/R0_rect'],"Tr_velo_to_cam": info['calib/Tr_velo_to_cam'],"P2": info['calib/P2'],}info["point_cloud"] = {"velodyne_path": info['velodyne_path'],}# 将kitti中的一帧的anno信息写成文件保存
def kitti_anno_to_label_file(annos, folder):folder = Path(folder) # 获取文件的路径# 对于每一帧的信息:for anno in annos:image_idx = anno["metadata"]["image_idx"] # 获取image_idxlabel_lines = []for j in range(anno["bbox"].shape[0]): # 对于该帧数据中的每一个物体object:# 获取相应的标签信息,并存入label_dict字典中label_dict = {'name': anno["name"][j],'alpha': anno["alpha"][j],'bbox': anno["bbox"][j],'location': anno["location"][j],'dimensions': anno["dimensions"][j],'rotation_y': anno["rotation_y"][j],'score': anno["score"][j],}# 再对该标签信息做进一步的处理,将结果添加到列表label_lines中去label_line = kitti.kitti_result_line(label_dict)label_lines.append(label_line)# 将这一帧的所有物体的标签信息写入到文件中,并进行相应的命名label_file = folder / f"{kitti.get_image_index_str(image_idx)}.txt"label_str = '\n'.join(label_lines)with open(label_file, 'w') as f:f.write(label_str)# 根据文件路径读取 文件里的内容,
# 返回结果是一个列表,每个元素是当前帧的一个物体
def _read_imageset_file(path):with open(path, 'r') as f:lines = f.readlines()return [int(line) for line in lines]def _calculate_num_points_in_gt(data_path,infos,relative_path,remove_outside=True,num_features=4):# 对于每一帧数据里的信息for info in infos:pc_info = info["point_cloud"] # 获取点云信息image_info = info["image"] #获取图像信息calib = info["calib"] # 获取相机标定参数if relative_path: # 如果相对路径存在,则变为绝对路径,否则取保存在字典中的路径值v_path = str(Path(data_path) / pc_info["velodyne_path"])else: v_path = pc_info["velodyne_path"]# 从文件中读取点云数据,并按照格式排成(M,4)points_v = np.fromfile( v_path, dtype=np.float32, count=-1).reshape([-1, num_features])rect = calib['R0_rect']Trv2c = calib['Tr_velo_to_cam']P2 = calib['P2']if remove_outside:# 判断如果去掉框外面的点,调用函数来实现,去掉外面的点能加快速度points_v = box_np_ops.remove_outside_points(points_v, rect, Trv2c, P2, image_info["image_shape"])# 获取这一帧中所有物体的信息annos = info['annos']# 得到去掉dontcare的物体的总个数,并取出位置等信息,并将信息组成(N,7)num_obj = len([n for n in annos['name'] if n != 'DontCare'])# annos = kitti.filter_kitti_anno(annos, ['DontCare'])dims = annos['dimensions'][:num_obj]loc = annos['location'][:num_obj]rots = annos['rotation_y'][:num_obj]gt_boxes_camera = np.concatenate([loc, dims, rots[..., np.newaxis]],axis=1)# 将数据从相机转为雷达坐标系gt_boxes_lidar = box_np_ops.box_camera_to_lidar(gt_boxes_camera, rect, Trv2c)# 获取点是否在框内的索引,(0,0,0,0,-1,0,,-1,-1)indices = box_np_ops.points_in_rbbox(points_v[:, :3], gt_boxes_lidar)num_points_in_gt = indices.sum(0) # 得到在框内的点的个数num_ignored = len(annos['dimensions']) - num_obj # 得到的是无效物体的个数,即dontcarenum_points_in_gt = np.concatenate([num_points_in_gt, -np.ones([num_ignored])])# 将得到框中点的个数,存放在字典中annos["num_points_in_gt"] = num_points_in_gt.astype(np.int32)# 生成数据集信息文件的函数
def create_kitti_info_file(data_path, save_path=None, relative_path=True):imageset_folder = Path(__file__).resolve().parent / "ImageSets"train_img_ids = _read_imageset_file(str(imageset_folder / "train.txt"))val_img_ids = _read_imageset_file(str(imageset_folder / "val.txt"))test_img_ids = _read_imageset_file(str(imageset_folder / "test.txt"))print("Generate info. this may take several minutes.")# 设置保存 路径if save_path is None:save_path = Path(data_path)else:save_path = Path(save_path)# 获取训练集的信息,并将信息保存在文件中kitti_infos_train = kitti.get_kitti_image_info(data_path,training=True,velodyne=True,calib=True,image_ids=train_img_ids,relative_path=relative_path)_calculate_num_points_in_gt(data_path, kitti_infos_train, relative_path)filename = save_path / 'kitti_infos_train.pkl'print(f"Kitti info train file is saved to {filename}")with open(filename, 'wb') as f:pickle.dump(kitti_infos_train, f)# 获取验证集的信息,并将数据保存在文件中kitti_infos_val = kitti.get_kitti_image_info(data_path,training=True,velodyne=True,calib=True,image_ids=val_img_ids,relative_path=relative_path)_calculate_num_points_in_gt(data_path, kitti_infos_val, relative_path)filename = save_path / 'kitti_infos_val.pkl'print(f"Kitti info val file is saved to {filename}")with open(filename, 'wb') as f:pickle.dump(kitti_infos_val, f)# 将train和val的信息保存在同一个文件中filename = save_path / 'kitti_infos_trainval.pkl'print(f"Kitti info trainval file is saved to {filename}")with open(filename, 'wb') as f:pickle.dump(kitti_infos_train + kitti_infos_val, f)# 将test的数据进行保存kitti_infos_test = kitti.get_kitti_image_info(data_path,training=False,label_info=False,velodyne=True,calib=True,image_ids=test_img_ids,relative_path=relative_path)filename = save_path / 'kitti_infos_test.pkl'print(f"Kitti info test file is saved to {filename}")with open(filename, 'wb') as f:pickle.dump(kitti_infos_test, f)def _create_reduced_point_cloud(data_path,info_path,save_path=None,back=False):# 打开文件,获取数据集的信息with open(info_path, 'rb') as f:kitti_infos = pickle.load(f)# 对于每一帧数据for info in prog_bar(kitti_infos):# 获取相应的参数和信息pc_info = info["point_cloud"]image_info = info["image"]calib = info["calib"]# 获取激光雷达的数据的路径,并读取文件获取点云数据v_path = pc_info['velodyne_path']v_path = Path(data_path) / v_pathpoints_v = np.fromfile( str(v_path), dtype=np.float32, count=-1).reshape([-1, 4])rect = calib['R0_rect']P2 = calib['P2']Trv2c = calib['Tr_velo_to_cam']# first remove z < 0 points# keep = points_v[:, -1] > 0# points_v = points_v[keep]# then remove outside.if back:points_v[:, 0] = -points_v[:, 0]# 去掉框外面的点云数据points_v = box_np_ops.remove_outside_points(points_v, rect, Trv2c, P2,image_info["image_shape"])# 设置保存的路径if save_path is None:save_filename = v_path.parent.parent / (v_path.parent.stem + "_reduced") / v_path.name# save_filename = str(v_path) + '_reduced'if back:save_filename += "_back"else:save_filename = str(Path(save_path) / v_path.name)if back:save_filename += "_back"# 将点云数据写入到要保存的路径中with open(save_filename, 'w') as f:points_v.tofile(f)#该函数的作用是去掉数据集中train、val、test 中多余的点云信息
# 主要调用了_create_reduced_point_cloud的函数
def create_reduced_point_cloud(data_path,train_info_path=None,val_info_path=None,test_info_path=None,save_path=None,with_back=False):# 获取文件的路径if train_info_path is None:train_info_path = Path(data_path) / 'kitti_infos_train.pkl'if val_info_path is None:val_info_path = Path(data_path) / 'kitti_infos_val.pkl'if test_info_path is None:test_info_path = Path(data_path) / 'kitti_infos_test.pkl'# 调用函数,实现去掉多余的数据,并进行保存_create_reduced_point_cloud(data_path, train_info_path, save_path)_create_reduced_point_cloud(data_path, val_info_path, save_path)_create_reduced_point_cloud(data_path, test_info_path, save_path)# 如果返回,则将back参数设置为Trueif with_back:_create_reduced_point_cloud(data_path, train_info_path, save_path, back=True)_create_reduced_point_cloud(data_path, val_info_path, save_path, back=True)_create_reduced_point_cloud(data_path, test_info_path, save_path, back=True)if __name__ == "__main__":fire.Fire()
3D目标检测——代码理解——Second代码:数据处理kitti_dataset.py的理解相关推荐
- 3D目标检测 | PointPillars论文和代码解析
作者丨周威@知乎 来源丨https://zhuanlan.zhihu.com/p/357626425 编辑丨3D视觉工坊 1 前言 本文要解析的模型叫做PointPillars,是2019年出自工业界 ...
- 点云3D目标检测之——尝试SFD代码跑通(超详细!!)
前言 到目前为止还没跑通,但是bug实在太多了,我的每一步都有错,如果不记录下来又会有遗漏,(肯定已经遗漏了很多),在这里把能想起来的都记录一下以便不时之需.另外,本人深度学习小白,一上来跑这么难的代 ...
- 【利用MMdetection3D框架进行单目3D目标检测(smoke算法】
利用MMdetection3D框架进行3D目标检测(smoke算法) 1.mmdetection3d 2.mmdetection3d安装 2.1 依赖 3.进行单目3D目标检测 1.mmdetecti ...
- 【单目3D目标检测】SMOKE论文解析与代码复现
文章目录 yacs Introduction Usage SMOKE Preface Abstract Contributions Pipeline Backbone Head Branch Orie ...
- 最新发布!SMOKE 单目3D目标检测,代码开源!
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者| 黎国溥 编辑| 3D视觉开发者社区 SMOKE是一个one-stage的单目视觉障碍物检测模型 ...
- cvpr2019 目标检测算法_CVPR2019 | 0327日更新12篇论文及代码汇总(多目标跟踪、3D目标检测、分割等)...
加入极市专业CV交流群,与6000+来自腾讯,华为,百度,北大,清华,中科院等名企名校视觉开发者互动交流!更有机会与李开复老师等大牛群内互动! 同时提供每月大咖直播分享.真实项目需求对接.干货资讯汇总 ...
- 首个实时单目3D目标检测算法:RTM3D,代码将开源
o 点击我爱计算机视觉标星,更快获取CVML新技术 基于单目图像的3D目标检测是在输入RGB图像的情况下估计目标的3D包围框,在自动驾驶领域非常有用. 今天来自中科院沈阳自动化所等单位的学者公布论文提 ...
- 【单目3D目标检测】MonoDLE论文精读与代码解析
文章目录 Preface Abstract Contributions Diagnostic Experiments Pipeline Revisiting Center Detection Trai ...
- 【单目3D目标检测】MonoFlex论文精读与代码解析
文章目录 Preface Abstract Contributions Pipeline Problem Definition Decoupled Representations of Objects ...
最新文章
- 响应式布局框架 Pure-CSS 5.0 示例中文版-下
- PAT乙级 1038 统计同成绩学生 C++)
- CSS中的特殊的选择器
- JAVA进阶教学之(Object类中的equals方法)
- 程序员职业6个阶段,你处于哪个?
- 解决Agent admitted failure to sign using the kye with ssh
- 学会提问pdf_原来只要1分钟,Word、PPT、PDF文件就能随意互相转换,快学学
- HeadFirstJava 12 图形用户接口
- Nexus3搭建maven私服(一、Windows系统)
- web请求报出 “超过了最大请求长度”
- 系统封装教程(Win10案例)
- 【ESG】Aggregate Confusion: The Divergence of ESG Ratings
- 关系型数据库设计——银行业务管理系统
- 人工智能 | ShowMeAI资讯日报 #2022.06.25
- 工业强国之路任重道远,制造业乘“疾风”突出重围
- 虎牙直播分类图片爬虫
- 失落的帝国:盛大业务大收缩
- QList、QVector、QMap、QHash安全删除(指定删除、遍历删除、快速删除)
- 考研复试英语自我介绍计算机,计算机复试英语自我介绍
- 怎样自动以管理员身份运行bat文件?
热门文章
- ubuntu18.04安装caffe-cpu版
- Hexo 靜態博客使用指南
- ssh 远程报错 Permission denied, please try again.(密码输入正确也无法登录)
- ZOJ 3987 Numbers 2017CCPC秦皇岛站G题 大整数 二进制 贪心
- android 程序崩溃处理,Android应用崩溃的应急处理
- 广义表的头尾链表存储表示(第五章 P115 算法5.5,5.6,5.8)
- java将office文档,word,ppt,pdf文档转换成swf文件在线预览
- 美国国土安全部部长约翰逊就Dyn网络攻击事件发表声明
- iOS开发-自定义相机(仿微信)拍照、视频录制
- arcgis 9.3/10.2.2/10.5版本下载