Pointpillars三维点云实时检测

2023-05-16

目录

一、项目方案

二、项目准备工作

1.安装并配置好Openpcdet的环境

2.安装好ROS melodic

三、项目工作空间创建及代码配置

四、具体代码修改与讲解

launch/pointpillars.launch的修改

launch/pointpillars.rviz的修改

五、实时检测效果展示

六、项目思考以及未解决的问题

七、Reference


一、项目方案

ROS的通讯机制使得它在机器人和无人驾驶领域应用十分广泛。所以本项目通讯都在ROS里进行。

1.激光雷达或者相机通过ROS发送点云信息

2.获得的点云msg消息通过转换送入pointpillars目标检测框架,检测完毕获得检测框通过ROS消息发送出去。

3.在ROS的rviz里面对这些消息进行显示。

二、项目准备工作

1.安装并配置好Openpcdet的环境

使用OpenPcdet框架里面的pointpillars代码进行,因为这个框架对于三维目标检测算法的封装集成度很高,方便我们进行使用。

2.安装好ROS melodic

本项目是基于ROS进行的,所以要提前安装好,其他的ROS版本也可

三、项目工作空间创建及代码配置

mkdir -p ~/pointpillars_ros/src
cd pointpillars_ros/src

下载这个包,这个包是某个大佬写的,后面有参考链接。

git clone https://github.com/BIT-DYN/pointpillars_ros
cd ..

 进入openpcdet的conda环境,然后安装几个库,jsk-recognition-msg这个库里面的消息主要是存放检测框的。具体可以看这个链接https://blog.csdn.net/leesanity/article/details/123137541

# 进入到搭建好的openpcdet环境
conda activate pcdet
pip install --user rospkg catkin_pkg
pip install pyquaternion

sudo apt-get install ros-melodic-pcl-ros
sudo apt-get install ros-melodic-jsk-recognition-msg
sudo apt-get install ros-melodic-jsk-rviz-plugins
catkin_make

然后再把Openpcdet里面的相关文件移进来,放到src/pointpillars/tools下面

 这里可以改一下demo.py里面配置文件和预训练模型,然后放入数据检查一下openpcdet移植过来还能跑通不。

四、具体代码修改与讲解

先修改ros.py,大家可以先用下面的ros.py代码替换掉原先的。代码如下:

#!/usr/bin/env python3

import rospy

from sensor_msgs.msg import PointCloud2,PointField

import sensor_msgs.point_cloud2 as pc2
from std_msgs.msg import Header
from jsk_recognition_msgs.msg import BoundingBox, BoundingBoxArray

import time
import numpy as np
from pyquaternion import Quaternion

import argparse
import glob
from pathlib import Path

import numpy as np
import torch
import scipy.linalg as linalg

import sys
sys.path.append("/home/wangchen/pointpillars_ros/src/pointpillars_ros")

from pcdet.config import cfg, cfg_from_yaml_file
from pcdet.datasets import DatasetTemplate
from pcdet.models import build_network, load_data_to_gpu
from pcdet.utils import common_utils

class DemoDataset(DatasetTemplate):
    def __init__(self, dataset_cfg, class_names, training=True, root_path=None, logger=None, ext='.bin'):
        """
        Args:
            root_path: 根目录
            dataset_cfg: 数据集配置
            class_names: 类别名称
            training: 训练模式
            logger: 日志
            ext: 扩展名
        """
        super().__init__(
            dataset_cfg=dataset_cfg, class_names=class_names, training=training, root_path=root_path, logger=logger
        )



class Pointpillars_ROS:
    def __init__(self):
        config_path, ckpt_path = self.init_ros()
        self.init_pointpillars(config_path, ckpt_path)


    def init_ros(self):
        """ Initialize ros parameters """
        config_path = rospy.get_param("/config_path", "/home/wangchen/pointpillars_ros/src/pointpillars_ros/tools/cfgs/kitti_models/pointpillar.yaml")
        ckpt_path = rospy.get_param("/ckpt_path", "/home/wangchen/pointpillars_ros/src/pointpillars_ros/tools/pointpillar_7728.pth")
        # # subscriber
        # self.sub_velo = rospy.Subscriber("/kitti/velo/pointcloud", PointCloud2, self.lidar_callback, queue_size=1,
        #                                  buff_size=2 ** 12)
        #
        # # publisher
        # self.sub_velo = rospy.Publisher("/modified", PointCloud2, queue_size=1)
        # self.pub_bbox = rospy.Publisher("/detections", BoundingBoxArray, queue_size=10)
        return config_path, ckpt_path


    def init_pointpillars(self, config_path, ckpt_path):
        """ Initialize second model """
        logger = common_utils.create_logger() # 创建日志
        logger.info('-----------------Quick Demo of Pointpillars-------------------------')
        cfg_from_yaml_file(config_path, cfg)  # 加载配置文件

        self.demo_dataset = DemoDataset(
            dataset_cfg=cfg.DATA_CONFIG, class_names=cfg.CLASS_NAMES, training=False,
            ext='.bin', logger=logger
        )
        self.model = build_network(model_cfg=cfg.MODEL, num_class=len(cfg.CLASS_NAMES), dataset=self.demo_dataset)
        # 加载权重文件
        self.model.load_params_from_file(filename=ckpt_path, logger=logger, to_cpu=True)
        self.model.cuda() # 将网络放到GPU上
        self.model.eval() # 开启评估模式


    def rotate_mat(self, axis, radian):
        rot_matrix = linalg.expm(np.cross(np.eye(3), axis / linalg.norm(axis) * radian))
        return rot_matrix


    def lidar_callback(self, msg):
        """ Captures pointcloud data and feed into second model for inference """
        pcl_msg = pc2.read_points(msg, field_names = ("x", "y", "z", "intensity"), skip_nans=True)
        #这里的field_names可以不要,不要就是把数据全部读取进来。也可以用field_names = ("x", "y", "z")这个只读xyz坐标
        #得到的pcl_msg是一个generator生成器,如果要一次获得全部的点,需要转成list
        np_p = np.array(list(pcl_msg), dtype=np.float32)
        #print(np_p.shape)
        # 旋转轴
        #rand_axis = [0,1,0]
        #旋转角度
        #yaw = 0.1047
        #yaw = 0.0
        #返回旋转矩阵
        #rot_matrix = self.rotate_mat(rand_axis, yaw)
        #np_p_rot = np.dot(rot_matrix, np_p[:,:3].T).T

        # convert to xyzi point cloud
        x = np_p[:, 0].reshape(-1)
        #print(np.max(x),np.min(x))
        y = np_p[:, 1].reshape(-1)
        z = np_p[:, 2].reshape(-1)
        if np_p.shape[1] == 4: # if intensity field exists
            i = np_p[:, 3].reshape(-1)
        else:
            i = np.zeros((np_p.shape[0], 1)).reshape(-1)
        points = np.stack((x, y, z, i)).T
        # 组装数组字典
        input_dict = {
            'frame_id': msg.header.frame_id,
            'points': points
        }
        data_dict = self.demo_dataset.prepare_data(data_dict=input_dict) # 数据预处理
        data_dict = self.demo_dataset.collate_batch([data_dict])
        load_data_to_gpu(data_dict) # 将数据放到GPU上
        pred_dicts, _ = self.model.forward(data_dict) # 模型前向传播
        scores = pred_dicts[0]['pred_scores'].detach().cpu().numpy()
        mask = scores > 0.5
        scores = scores[mask]
        boxes_lidar = pred_dicts[0]['pred_boxes'][mask].detach().cpu().numpy()
        label = pred_dicts[0]['pred_labels'][mask].detach().cpu().numpy()
        num_detections = boxes_lidar.shape[0]

        arr_bbox = BoundingBoxArray()
        for i in range(num_detections):
            bbox = BoundingBox()

            bbox.header.frame_id = msg.header.frame_id
            bbox.header.stamp = rospy.Time.now()
            bbox.pose.position.x = float(boxes_lidar[i][0])
            bbox.pose.position.y = float(boxes_lidar[i][1])
            bbox.pose.position.z = float(boxes_lidar[i][2]) #+ float(boxes_lidar[i][5]) / 2
            bbox.dimensions.x = float(boxes_lidar[i][3])  # width
            bbox.dimensions.y = float(boxes_lidar[i][4])  # length
            bbox.dimensions.z = float(boxes_lidar[i][5])  # height
            q = Quaternion(axis=(0, 0, 1), radians=float(boxes_lidar[i][6]))
            bbox.pose.orientation.x = q.x
            bbox.pose.orientation.y = q.y
            bbox.pose.orientation.z = q.z
            bbox.pose.orientation.w = q.w
            bbox.value = scores[i]
            bbox.label = label[i]

            arr_bbox.boxes.append(bbox)

        arr_bbox.header.frame_id = msg.header.frame_id
        #arr_bbox.header.stamp = rospy.Time.now()

        if len(arr_bbox.boxes) is not 0:
            pub_bbox.publish(arr_bbox)
            self.publish_test(points, msg.header.frame_id)

    def publish_test(self, cloud, frame_id):
        header = Header()
        header.stamp = rospy.Time()
        header.frame_id = frame_id
        fields = [PointField('x', 0, PointField.FLOAT32, 1),
                  PointField('y', 4, PointField.FLOAT32, 1),
                  PointField('z', 8, PointField.FLOAT32, 1),
                  PointField('intensity', 12, PointField.FLOAT32, 1)]  # ,PointField('label', 16, PointField.FLOAT32, 1)
        #creat_cloud不像read,他必须要有fields,而且field定义有两种。一个是上面的,一个是下面的fields=_make_point_field(4)
        msg_segment = pc2.create_cloud(header = header,fields=fields,points = cloud)

        pub_velo.publish(msg_segment)
        #pub_image.publish(image_msg)


def _make_point_field(num_field):
    msg_pf1 = pc2.PointField()
    msg_pf1.name = np.str_('x')
    msg_pf1.offset = np.uint32(0)
    msg_pf1.datatype = np.uint8(7)
    msg_pf1.count = np.uint32(1)

    msg_pf2 = pc2.PointField()
    msg_pf2.name = np.str_('y')
    msg_pf2.offset = np.uint32(4)
    msg_pf2.datatype = np.uint8(7)
    msg_pf2.count = np.uint32(1)

    msg_pf3 = pc2.PointField()
    msg_pf3.name = np.str_('z')
    msg_pf3.offset = np.uint32(8)
    msg_pf3.datatype = np.uint8(7)
    msg_pf3.count = np.uint32(1)

    msg_pf4 = pc2.PointField()
    msg_pf4.name = np.str_('intensity')
    msg_pf4.offset = np.uint32(16)
    msg_pf4.datatype = np.uint8(7)
    msg_pf4.count = np.uint32(1)

    if num_field == 4:
        return [msg_pf1, msg_pf2, msg_pf3, msg_pf4]

    msg_pf5 = pc2.PointField()
    msg_pf5.name = np.str_('label')
    msg_pf5.offset = np.uint32(20)
    msg_pf5.datatype = np.uint8(4)
    msg_pf5.count = np.uint32(1)

    return [msg_pf1, msg_pf2, msg_pf3, msg_pf4, msg_pf5]
if __name__ == '__main__':
    global sec
    sec = Pointpillars_ROS()

    rospy.init_node('pointpillars_ros_node', anonymous=True)

    # subscriber

    sub_velo = rospy.Subscriber("/kitti/velo/pointcloud", PointCloud2, sec.lidar_callback, queue_size=1,
                                    buff_size=2 ** 12)


    # publisher
    pub_velo = rospy.Publisher("/modified", PointCloud2, queue_size=1)
    pub_bbox = rospy.Publisher("/detections", BoundingBoxArray, queue_size=10)

    try:
        rospy.spin()
    except KeyboardInterrupt:
        del sec
        print("Shutting down")

替换完之后,大家要改的是24行,56 ,57行的预训练权重和config文件,改成你自己的路径即可。如果是你自己的雷达或相机219行换成你自己的话题名

launch/pointpillars.launch的修改

 <node pkg="rosbag" type="play" name="player" output="log" args="-l /media/ubuntu/ximing/dataset/ros_kitti/bag/2011_10_03/kitti_2011_10_03_drive_0027_synced.bag" />

把这个里面的ROSBAG路径改一下,改成你自己的就行。

这里附上一个ROSBAG包制作的链接https://blog.csdn.net/FSKEps/article/details/90345566

 这个链接里面需要下载的包在我百度网盘里,链接: https://pan.baidu.com/s/1EtG_Z8jujW77bU9o_ZoduQ提取码: sfiw

launch/pointpillars.rviz的修改

这个里面主要把Topic话题改一下,一个图像,一个点云,那个modified不改

Topic: /kitti/velo/pointcloud

Image Topic: /kitti/camera_color_left/image_raw

这两个话题是kitti的ROSbag包的话题,如果是自己的激光雷达要修改这两个话题。

还有一处如果是自己的雷达或相机也要修改。

Fixed Frame: velo_link,这里如果是自己的也要改。指的RVIZ里面的基准坐标系

五、实时检测效果展示

conda activate pcdet
source ~/pointpillars_ros/devel/setup.bash
roslaunch pointpillars_ros pointpillars.launch

可能会卡顿,打开RVIZ之后等一分钟。

具体动画效果看大佬的bilibili链接https://www.bilibili.com/video/BV1ce4y1D76o/

播放的时候点云换成modified,这时框与点云可以对上。如果不换对不上。

六、项目思考以及未解决的问题

首先是点云和检测框在RVIZ里面显示的问题,/kitti/velo/pointcloud这个是我们订阅的点云话题,送入pointpillars检测之后会耗费一段时间,这时检测出来的检测框和/kitti/velo/pointcloud的时间戳对不上,所以会导致RVIZ里面点云与框不对应。这时我们在检测完框之后,重新定义一个点云,把他的时间戳和检测框的对齐,再发布出来就是我们代码里的modified点云,所以modified点云与框可以对应,但此时图像是和/kitti/velo/pointcloud对应的,所以我的想法是同时也订阅一个图像信息,等检测完,创建一个新的modified图像再发布,让他们时间戳对齐,这样就可以解决了,但事实证明,这样尝试了一下还是对不齐,希望大家有想法的可以积极讨论一下,很期待和大家一起解决这个问题。

第二个问题就是大家用自己的相机或者雷达做实时检测显示,我这里也和一位博主讨论过,把点云图像换成自己相机的,还有RVIZ里面的launch文件的基准坐标系也要改成你自己的。但是在实际场景中检测出来的检测框乱飞。现在还在尝试解决,希望大家可以一起解决这个问题。目前就这么多,也希望大家可以把自己的想法和问题说出来,我们一起讨论,谢谢大家的参与。

关于自己数据实时检测已经实现了,自己数据检测时要注意两点:

1.坐标系一定要转换为openpcdet的统一坐标系。

2.自己雷达采集的intensity一定要置零之后再进行检测,不然检测框会乱飞。

七、Reference

https://blog.csdn.net/jiachang98/article/details/126106126?spm=1001.2014.3001.5501

https://blog.csdn.net/weixin_43807148/article/details/125867953

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pointpillars三维点云实时检测 的相关文章

  • 2D Nav Goal无法使用 或 rviz-gazebo数据交互出问题

    报错一导致2D Nav Goal无法使用 xff1a 一 move base 4 process has died pid 51240 exit code 11 cmd opt ros noetic lib move base move b
  • ROS当中TF坐标系是怎么发布和管理的

    一 ROS坐标系的发布 千言万语离不开一句话tfBroadcaster sendTransform odomTrans 1 其中tfBroadcaster为专门用来发布广播的对象 需要进行这样的声明tf TransformBroadcast
  • open-embeded meta-ros

    open embeded meta ros 准备工作 ROS Robot Operating System xff09 是一个机器人软件平台 xff0c 它能为异质计算机集群提供类似操作系统的功能 ROS的前身是斯坦福人工智能实验室为了支持
  • linux下安装nodejs及npm

    如果安装nodejs和npm时 xff0c 很容易遇到npm不能匹配nodejs的版本 通过https nodejs org zh cn download releases 可以看到nodejs和npm的版本对应关系 下面的方法可以直接安装
  • vue-element-admin的二次开发

    最近也是完成了公司招聘管理系统后台的前端开发 xff0c 项目已经开始测试了近期估计就会交付使用 一直是一个人在做 xff0c 配合两个后端 xff0c 说实话这种从很多不会到一个个独立debug解决问题到最后终于完成项目的感觉真的太有成就
  • 烧写APM板的bootloader

    所需工具材料 xff1a 1 一个AVRusbasp编程器以及相应的烧写软件 xff0c 推荐progisp1 72下载链接https download csdn net download sky7723 12477620 2 AVR的US
  • APM_V2.8.0的改进说明

    APM V2 8 0版基于3DR公司出的V2 5 2版优化设计而来 xff0c 硬件功能跟V2 5 2一样 xff0c 尺寸也一样 xff0c 仍旧可以使用2 52版的外壳 不同的是V2 8 0版针对内部电路设计BUG做了改进 xff0c
  • Ardupliot飞控PID等参数加密屏蔽方法(针对Mission Planner的刷新参数等功能)

    当辛辛苦苦调试OK的参数 xff0c 被别人连上飞地面站后轻松获取 xff0c 是不是有点难受 xff1f 本文针对四旋翼Copter4 0 7和 xff08 4 1 5 xff09 最新版本调试了两个加密方法 4 0 7固件 在对4 0
  • ROS省略source devel/setup.bash的方法

    为了不每次运行程序的时候都source一次devel文件夹里的setup bash xff0c 可以打开主目录 按下Crtl 43 h 显示隐藏文件 xff0c 双击打开bashrc文件 xff0c 在最后加入 source home ca
  • 浅谈prometheus(普罗米修斯) client golang

    浅谈prometheus client golang 含类型精讲 43 接口示例 43 源码节选 Prometheus xff1a prometheus是什么 xff0c 网上已经有很多文章了 xff0c prometheus的部署和启动可
  • Git中submodule的使用

    背景 面对比较复杂的项目 xff0c 我们有可能会将代码根据功能拆解成不同的子模块 主项目对子模块有依赖关系 xff0c 却又并不关心子模块的内部开发流程细节 这种情况下 xff0c 通常不会把所有源码都放在同一个 Git 仓库中 有一种比
  • 测控系统中上位机开发小节

    对测控系统中上位机开发小节 关键字即内容 xff1a 工业控制 xff0c 测量控制 xff0c 上位机 xff0c 下位机 通讯协议 xff0c tcpip rs232 rs485 报警状态 xff0c 控制开关 xff0c 采集数据 x
  • Remmina:一个 Linux 下功能丰富的远程桌面共享工具

    转自 https linux cn article 8493 1 html Remmina 是一款在 Linux 和其他类 Unix 系统下的自由开源 功能丰富 强大的远程桌面客户端 xff0c 它用 GTK 43 3 编写而成 它适用于那
  • 个人简历

    大家好 xff1a 本人系重庆大学2003级硕士研究生 xff0c 将于2006年7月毕业 相关技能 xff1a 1 计算机 xff1a 熟悉计算机软 硬件体系结构 xff0c 了解计算机接口技术 xff1b 熟悉C 43 43 汇编等语言
  • 游戏开发踩的那些坑:abs函数的平台差异

    转载请注明 xff0c 来自 xff1a http blog csdn net skyman 2001 我写了个弹性3D箭头功能 xff0c 指定起点 终点和圆弧的夹角 xff0c 就会渲染出弯曲的3D箭头 xff0c 里面用了abs函数计
  • 实时水墨渲染探究

    转载请注明 xff1a 来自http blog csdn net skyman 2001 xff0c by 吴俊 中国绘画源远流长 xff0c 有着丰富多彩的遗产 独特而鲜明的艺术特点 xff0c 在东方乃至世界都自成体系 xff0c 别具
  • ios platform 型号

    转载自 xff1a http hulefei29 iteye com blog 1701464 xfeff xfeff Platforms iFPGA gt iPhone1 1 gt iPhone 1G M68 iPhone1 2 gt i
  • fopen vs access vs stat

    xfeff xfeff 转载请注明 xff0c 来自 xff1a http blog csdn net skyman 2001 vs2010 win7 function call time fopen 1 149000 ms access

随机推荐

  • OpenGL运行库下载

    OpenGL运行库下载 可能有些同志遇到过这样的情况 xff1a 下载的OpenGL程序由于缺少一个或多个dll文件而不能运行 xff0c 这里是我搜集的常用的OpenGL运行dll库 xff0c 包括 xff1a opengl32 dll
  • OpenGL通过读取Z Buffer深度值将屏幕2D坐标转化为场景3D坐标(含完整源码)

    如需转载请注明出处 xff1a http blog csdn net skyman 2001 主要有2种方法来实现屏幕2D坐标转化为场景3D坐标 xff1a 一种是通过拣选射线 xff0c 我的 APRG Demo 就是这样做的 xff0c
  • gen_fsm中send_event和send_all_state_event的区别

    文档原文 xff1a The difference between send event and send all state event is which callback function is used to handle the e
  • STM32驱动开发(一)--串口原理与开发实践

    STM32驱动开发 xff08 一 xff09 串口原理与开发实践 参考 xff1a 野火嵌入式 STM32库开发实战指南 韦东山 STM32MP157 M4 用户手册 一 简介 在工业现场目前用的最多的对外通信就是串口 xff08 UAR
  • 如何将float转换为string

    可能有好多人 xff0c 包括C语言老手都不知道如何将float数据转换为string xff0c 我就是这样 xff0c 今天查了一下MSDN xff0c 才知道C提供了 gcvt函数实现这个功能 xff0c 收获着实不小 xff0c 为
  • SVN中update to revision与revert to revision的区别

    转载请注明 xff0c 来自 xff1a http blog csdn net skyman 2001 update to revision和revert to revision很像 xff0c 都会融合你本地未提交的修改 它们2个的区别是
  • OpenGL中不用AUX库来加载BMP图片作为纹理

    大家在OpenGL中一般是用aux库的auxDIBImageLoad 函数来加载BMP格式的图片来作为纹理 xff0c 这个确实是比较简单易用 xff0c 但aux库的性能不佳 xff0c 经常会出问题 xff0c 稳定性较差 所以一般最好
  • 程序员会设计后是一种什么样的感觉

    我是一个iOS开发的程序员 xff0c 也是一个自由职业者 平时靠接一些外包和做自己的产品为生 做了这么多年 xff0c 给我的感觉是 xff1a 如果你只会写程序 xff0c 那么做自由职业者的空间要小很多 01 我为什么要学设计 做自己
  • poll函数详解

    1 poll函数概述 select 和 poll 系统调用的本质一样 xff0c poll 的机制与 select 类似 xff0c 与 select 在本质上没有多大差别 xff0c 管理多个描述符也是进行轮询 xff0c 根据描述符的状
  • PID超详细教程——PID原理+串级PID+C代码+在线仿真调参

    目录 前言 仿真调参环境 案例引入 小球位置控制 抛开案例 更专业地理解PID 由虚到实 代码编写 最后一步 PID参数调整 总结 使用PID的步骤 更进一步 串级PID 前言 很多人应该都听说过PID xff0c 它的运算过程简单 xff
  • 滤波器和衰减器的电路设计

    一 滤波器影象参数法的设计 滤波器是一种典型的选频电路 xff0c 在给定的频段内 xff0c 理论上它能让信号无衰减地通过电路 xff0c 这一段称为通带外的其他信号将受到很大的衰减 xff0c 具有很大衰减的频段称为阻带 xff0c 通
  • Odroid XU4学习笔记

    Odroid XU4学习笔记 xff08 一 xff09 20161127 写文档的最初目的是自己在学习过程中踩了很多坑 xff0c 只为记录下 xff0c 避免自己以后或者他人重蹈覆辙 一 相关资源 用户手册 xff1a http mag
  • Mac JetBrains工具 2018破解方法 PhpStorm 2018、 WebStorm 2018、DataGrip2018、PyCharm2018

    1 自行安装PhpStorm WebStorm DataGrip PyCharm 2 下载破解补丁 xff0c 2018版下载地址 链接 xff1a https pan baidu com s 1TZ kXvkgF2t3hKusQl5TDQ
  • 树莓派UPS供电(附图、视频、代码)

    通过XiaoJi UPS做供电 xff0c 通过Arduino做控制 通过XiaoJi UPS来感知车辆是否处于启动状态 xff08 电瓶供电 xff09 xff0c 如果在启动状态转为熄火状态 xff0c 则XiaoJi UPS指定针脚会
  • freeRtos源码解析(二)–任务调度

    freeRtos源码解析 二 任务调度 一 启动任务调度器 启动任务调度器之后 xff0c CPU正式进入任务模式调度各任务 xff08 CPU在中断模式和任务模式之间不断轮转 xff09 freeRtos任务调度依赖于内核的三个中断 xf
  • Ubuntu Windows双系统切换技巧

    平时在宿舍或者在家需要用到实验室的电脑 xff0c 远程的时候切换系统是个麻烦的事情 还要担心实验室断电之后 xff0c 电脑关机了 没人帮忙开机 所以有了此文 1 远程唤醒电脑 如果你的主板支持定时开机 xff0c 那么这个问题就比较简单
  • Ubuntu18.04+ZED SDK安装+ZED Python API+zed ros wrapper安装 手把手详细教程

    1 安装前准备 1 ubuntu显卡驱动要有 xff0c 没有的可以搜索如何安装ubuntu显卡驱动 xff0c 教程很多 xff0c 这里不再详细说明 2 ROS需要提前安装好 xff0c 可以搜索ubuntu如何安装ROS 我这里安装的
  • 五种常见的聚类算法总结

    目录 一 关于聚类的基础描述 1 1 聚类与分类的区别 1 2 聚类的概念 1 3 聚类的步骤 二 几种常见的聚类算法 2 1 K means聚类算法 1 K means算法的流程 xff1a 2 xff09 K means算法的优缺点及算
  • 非科班如何自学深度学习转行

    前言 xff1a 博主已经学废了 xff0c 代码代码不行 xff0c 理论理论不行 xff0c 所以想把走过的路给大家讲讲经验 xff0c 仅供参考 研一前 xff1a 编程基础 xff1a Python为主 xff0c 一般的深度学习代
  • Pointpillars三维点云实时检测

    目录 一 项目方案 二 项目准备工作 1 安装并配置好Openpcdet的环境 2 安装好ROS melodic 三 项目工作空间创建及代码配置 四 具体代码修改与讲解 launch pointpillars launch的修改 launc