设备:NVIDIA Jetson Xavier NX,定制载板
版本:L4T 32.6.1,JetPack 4.6,ubuntu 18.04 LTS,ros melodic,cuda 10.2
(务必确认系统版本和 JetPack 版本对应,不然大概率出问题,详见JetPack Archive | NVIDIA Developer)
darknet_ros 移植 yolo_v4 教程:Yolo v4系列学习(四)Yolo v4移植ROS_木顶思上的博客-CSDN博客
安装好 darknet_ros 和 yolo_v4 后,可以运行和识别,但是加载网络时有显示 train=1 ,而直接在设备上运行 darknet 和 yolo_v4 时则显示 train=0 。同时发现 darknet_ros 运行帧率不及直接运行 darknet ,可能是此处 train=1 造成了一定影响。
另外 darknet_ros 会重复识别同一张图片,解决方案:Darknet_ros FPS过高,对同一帧图像重复处理占用资源的问题_走走走走走走你的博客-CSDN博客
catkin_ws/src/darknet_ros/darknet/src/parser.c 第1357行
return parse_network_cfg_custom(filename, 0, 0);
改为
return parse_network_cfg_custom(filename, 1, 0);
从 catkin_ws/src/darknet_ros/darknet_ros/src 文件夹入手,在YoloObjectDetector.cpp文件中可以找到调用yolo的函数:
void YoloObjectDetector::yolo()
从该函数中,可以看到调用了几个主要的函数:
fetchInThread
detectInThread
displayInThread
publishInThread
寻找目标用到的是
YoloObjectDetector::detectInThread
转到该函数定义,可以看到存储 yolo 网络的变量 net_ ,转到该变量赋值处,位于 setupNetwork 函数内
net_ = load_network(cfgfile, weightfile, 0);
转到 load_network 函数定义,来到 parser.c 文件,在该文件的1396行可以看到
printf("mini_batch = %d, batch = %d, time_steps = %d, train = %d \n", net.batch, net.batch * net.subdivisions, net.time_steps, params.train);
这里就是最初的打印出 train=1 的地方。可以看到此处变量名为 params.train 。查找发现文件中共有19处该变量,其中 parse_network_cfg_custom 函数中出现了
if (batch > 0) params.train = 0; // allocates memory for Inference only
else {params.train = 1;} // allocates memory for Inference & Training
刚刚的 load_network 函数中则有
*net = parse_network_cfg(cfg);
从 parse_network_cfg 的定义可以看到该函数和 parse_network_cfg_custom 的关系(1355行)
network parse_network_cfg(char *filename)
{
return parse_network_cfg_custom(filename, 0, 0);
}
parse_network_cfg_custom 的第二个参数恰恰是 batch ,也就意味着此处直接将 batch = 0 传入了 parse_network_cfg_custom ,进而在上边的判断里给 params.train 赋值 1 。到这里一切就豁然开朗了,解决方法也很简单,将这里的第二个参数改为 1 即可。
network parse_network_cfg(char *filename)
{
return parse_network_cfg_custom(filename, 1, 0);
}
再次测试,发现此时已经正常显示 train = 0 。