目录
6.Kitti数据集测试一下【The KITTI Vision Benchmark Suite】
1.安装Anaconda
比较简单,详细参考【Anaconda超详细安装教程(Windows环境下) - 奋斗终生 - 博客园】
2.安装Visual Studio 2022
略
3.安装CudaToolkit
这里说明一下,为什么需要在宿主机上安装CudaToolkit工具包。
主要是因为在anaconda中我们安装的cudatoolkit包只有cudart,没有用于编译的nvcc部分(后续用于编译OpenPCDet中的文件)。
所以虽然是在anaconda的虚拟环境中运行,还是需要在宿主机上安装一个版本一样的完整CudaToolkit
这里我的配置是:
Cuda版本:11.8
宿主机安装可以参考【win10 64位 环境下安装CUDA 11.8和 cuDNN v8.6.0_cudnn8.6.0-CSDN博客】
确认是否安装正常
nvcc -V
返回如下信息即正常
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:41:10_Pacific_Daylight_Time_2022
Cuda compilation tools, release 11.8, V11.8.89
Build cuda_11.8.r11.8/compiler.31833905_0
还需要配置一下系统环境变量LIBPATH
4.配置Conda虚拟环境
python 版本选择3.8
pytorch版本选择torch-2.0.0+cu118
torchvision版本选择torchvision-0.15.0+cu118
cudatoolkit选择11.8
创建conda环境(Powershell)
conda create -n pcdet python=3.8 cudatoolkit=11.8 -y
conda activate pcdet
安装Pytorch
1.先去这里面找对应版本的whl文件【download.pytorch.org/whl/torchvision/】,下载下来。
2.切换到对应文件目录,挨个安装一下
pip install ./torch-2.0.0+cu118-cp38-cp38-win_amd64.whl
pip install ./torchvision-0.15.0+cu118-cp38-cp38-win_amd64.whl
测试一下能用不
python -c "import torch; print(torch.cuda.is_available())"
True #True就没问题了
5.下载编译OpenPCDet源码
1.下载源码【open-mmlab/OpenPCDet: OpenPCDet Toolbox for LiDAR-based 3D Object Detection.】
2.解压、切换目录、安装必须库(不按照给的reuirement)
cd E:\OpenPCDet-master
pip install spconv-cu118
pip install kornia==0.6.5 av2==0.2.0 llvmlite ninja numba tensorboardX easydict pyyaml scikit-image tqdm opencv-python pyquaternion
3.修改setup.py(不依赖ShareArray,避免错误:fatal error C1083: 无法打开包括文件: “sys/mman.h”: No such file or directory)
setup(
name='pcdet',
version=version,
description='OpenPCDet is a general codebase for 3D object detection from point cloud',
install_requires=[
'numpy',
'llvmlite',
'numba',
'tensorboardX',
'easydict',
'pyyaml',
'scikit-image',
'tqdm',
# 'SharedArray', #这里注释
# 'spconv', # spconv has different names depending on the cuda version
],
4.修改源文件(主要是涉及CUDA中Linux系统和windows系统对于数据类型支持问题,详见OpenPCDet的issue)
pcdet/ops/ingroup_inds/src/ingroup_inds_kernel.cu
(所有long改为为int32_t,所有unsigned long long 改为uint64_t)
#include <assert.h>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <torch/serialize/tensor.h>
#include <torch/types.h>
#include "cuda_fp16.h"
#define CHECK_CALL(call) \
do \
{ \
const cudaError_t error_code = call; \
if (error_code != cudaSuccess) \
{ \
printf("CUDA Error:\n"); \
printf(" File: %s\n", __FILE__); \
printf(" Line: %d\n", __LINE__); \
printf(" Error code: %d\n", error_code); \
printf(" Error text: %s\n", \
cudaGetErrorString(error_code)); \
exit(1); \
} \
} while (0)
#define THREADS_PER_BLOCK 256
#define DIVUP(m, n) ((m) / (n) + ((m) % (n) > 0))
// #define DEBUG
// #define ASSERTION
__global__ void ingroup_inds_kernel(
const int32_t *group_inds,
int32_t *out_inds,
int *ingroup_counter,
int N
) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx >= N) return;
int32_t this_group_id = group_inds[idx];
int cnt = atomicAdd(&ingroup_counter[this_group_id], 1);
out_inds[idx] = cnt;
}
void ingroup_inds_launcher(
const int32_t *group_inds,
int32_t *out_inds,
int N,
int max_group_id
) {
int *ingroup_counter = NULL;
CHECK_CALL(cudaMalloc(&ingroup_counter, (max_group_id + 1) * sizeof(int)));
CHECK_CALL(cudaMemset(ingroup_counter, 0, (max_group_id + 1) * sizeof(int)));
dim3 blocks(DIVUP(N, THREADS_PER_BLOCK));
dim3 threads(THREADS_PER_BLOCK);
ingroup_inds_kernel<<<blocks, threads>>>(
group_inds,
out_inds,
ingroup_counter,
N
);
cudaFree(ingroup_counter);
#ifdef DEBUG
CHECK_CALL(cudaGetLastError());
CHECK_CALL(cudaDeviceSynchronize());
#endif
return;
}
pcdet/ops/ingroup_inds/src/ingroup_inds.cpp
(所有long改为为int32_t,所有unsigned long long 改为uint64_t)【同上】
代码略
pcdet/ops/iou3d_nms/src/iou3d_nms.cpp
(所有long改为为int32_t,所有unsigned long long 改为uint64_t,修改remv_cpu函数)
在 C/C++ 中,静态数组(Stack Array)的大小必须在编译时确定,而 col_blocks 是一个运行时计算的变量(通过 DIVUP 宏定义),因此无法直接用于静态数组的声明。
需要使用 std::vector 替代原生数组,避免手动内存管理
// unsigned long long mask_cpu[boxes_num * col_blocks];
// unsigned long long *mask_cpu = new unsigned long long [boxes_num * col_blocks];
std::vector<uint64_t> mask_cpu(boxes_num * col_blocks);
pcdet/ops/iou3d_nms/src/iou3d_nms_kernel.cu
(修改check_rect_cross函数名,避免与iou3d_nms中重复)
__device__ int check_rect_cross_cuda(const Point &p1, const Point &p2, const Point &q1, const Point &q2){
int ret = min(p1.x,p2.x) <= max(q1.x,q2.x) &&
min(q1.x,q2.x) <= max(p1.x,p2.x) &&
min(p1.y,p2.y) <= max(q1.y,q2.y) &&
min(q1.y,q2.y) <= max(p1.y,p2.y);
return ret;
}
__device__ inline int intersection(const Point &p1, const Point &p0, const Point &q1, const Point &q0, Point &ans){
// fast exclusion
const float EPS = 1E-8f;
if (check_rect_cross_cuda(p0, p1, q0, q1) == 0) return 0;
// check cross standing
float s1 = cross(q0, p1, p0);
float s2 = cross(p1, q1, p0);
float s3 = cross(p0, q1, q0);
float s4 = cross(q1, p1, q0);
if (!(s1 * s2 > 0 && s3 * s4 > 0)) return 0;
// calculate intersection of two lines
float s5 = cross(q1, p1, p0);
if(fabs(s5 - s1) > EPS){
ans.x = (s5 * q0.x - s1 * q1.x) / (s5 - s1);
ans.y = (s5 * q0.y - s1 * q1.y) / (s5 - s1);
}
else{
float a0 = p0.y - p1.y, b0 = p1.x - p0.x, c0 = p0.x * p1.y - p1.x * p0.y;
float a1 = q0.y - q1.y, b1 = q1.x - q0.x, c1 = q0.x * q1.y - q1.x * q0.y;
float D = a0 * b1 - a1 * b0;
ans.x = (b0 * c1 - b1 * c0) / D;
ans.y = (a1 * c0 - a0 * c1) / D;
}
return 1;
}
pcdet\datasets\augmentor\database_sampler.py(注释import SharedArray)
pcdet\datasets\waymo\waymo_dataset.py(注释import SharedArray)
pcdet\models\model_utils\mppnet_utils.py(注释from os import getgrouplist windows里面没这个,所以要注释掉)
5.编译
python .\setup.py develop
成功。
6.Kitti数据集测试一下【The KITTI Vision Benchmark Suite】
1.下载基本依赖
pip install open3d
2.切换目录
cd tools
3.验证
把模型文件和点云数据放到对应目录下,如下
weight目录如下,模型权重github主页下载就行
python demo.py --cfg_file cfgs/kitti_models/pv_rcnn.yaml --ckpt weight/pv_rcnn_8369.pth --data_path 000000.bin
还是建议使用Linux弄,这样搞太麻烦了,而且OpenPCDet已经没维护了,不知道后续会不会解决在windows上如此麻烦的问题