0%

@TOC

下载

官网下载

直接在ILSVRC2012官网进行下载,需要注册账号登陆。
训练集
训练集下载地址:http://www.image-net.org/challenges/LSVRC/2012/dd31405981ef5f776aa17412e1f0c112/ILSVRC2012_img_train.tar
验证集
验证集下载地址:http://www.image-net.org/challenges/LSVRC/2012/dd31405981ef5f776aa17412e1f0c112/ILSVRC2012_img_val.tar

迅雷下载

训练集
训练集种子:http://academictorrents.com/download/a306397ccf9c2ead27155983c254227c0fd938e2.torrent
验证集
验证集种子:http://academictorrents.com/download/5d6d0df7ed81efd49ca99ea4737e0ae5e3a5f2e5.torren

使用aria2加速下载

1
aria2c -x 16 -s 16 'http://academictorrents.com/download/5d6d0df7ed81efd49ca99ea4737e0ae5e3a5f2e5.torren' 'http://academictorrents.com/download/a306397ccf9c2ead27155983c254227c0fd938e2.torrent'

数据集校验

1
2
3
md5sum ILSVRC2012_img_val.tar ILSVRC2012_img_train.tar
29b22e2961454d5413ddabcf34fc5622 ILSVRC2012_img_val.tar
1d675b47d978889d74fa0da5fadfb00e ILSVRC2012_img_train.tar

训练

解压训练集

将ILSVRC2012_img_train.tar解压,1000个类别的*.tar包。

1
2
mkdir train
tar -xvf ILSVRC2012_img_train.tar -C train

然后可以使用下面这段python代码,将训练集的1000个.tar包解压缩,并删除源.tar包。

1
2
3
4
5
6
7
8
9
10
11
12
13
import glob
import os

filelist = glob.glob('./train/*.tar')

for f in filelist:
os.system("mkdir ./train/" + f.split('.')[0])

for f in filelist:
os.system("tar -xvf " + f + " -C ./train/" + f.split('.')[0])

for f in filelist:
os.system("rm ./train/" + f)

解压验证集

将ILSVRC2012_img_val.tar解压,得到没有种类标签的图片。

1
2
mkdir val
tar -xvf ILSVRC2012_img_val.tar -C val

然后使用valprep.sh文件,将验证集整理为和训练集相同的格式,按照种类标签划分文件夹。

1
2
3
cd val
aria2c -x 16 -s 16 ‘https://raw.githubusercontent.com/soumith/imagenetloader.torch/master/valprep.sh’
sh valprep.sh

问题描述:用MacBook Pro笔记本电脑,确定连接了网络,其他应用上网也没问题,就是浏览器打开网页的速度特别慢。换各种浏览器safari,firefox,chorme等打开网页都很慢。
解决方案:不是电脑硬件的问题,不是网络连接的问题,那应该就是网络配置的问题了。
系统偏好设置-网络

打开系统偏好设置,点击网络,在上方的“位置”,选择“编辑位置”,编辑一个“家”。立马解决问题。

参考
mac打开网页速度特别慢?

@[TOC](YOLOv3显示类别但是不显示bounding box)
这两天在跑YOLOv3的源代码,试着用自己的数据集训练并测试。之前测试了好几个数据集都没问题,今天遇到一个数据集,测试结果只显示类别,但是不显示bounding box。而且奇怪的是,并不是所有结果都这样,只是有的类别有,有的类别没有。
在原作者GitHub的issues里面找到了答案。
原来,bounding box的线条宽度,依赖于输入图片的高度。当输入图片的尺寸太小,bounding box的线条太细,就没法显示了。这个时候需要手动修改src文件夹下image.c/draw_detections函数,将width调大。记得修改文件后,make。

参考
no boxes is shown in predictions.jpg #1247

@TOC
最近参加2020年(第13届)中国大学生计算机设计大赛,选择了人工智能挑战赛的赛题二,基于 CT 影像的结直肠息肉检测。
赛题要求是,设计算法,判断图像中是否存在息肉,并实现息肉的准确检测,利用矩形方框将所检测出的息肉包含在检测框内。
乍一看,是一道标准的目标检测题,再看看官方给出的数据集标注,是YOLO格式的,那就直接用YOLOv3进行训练。最后再根据题目的需求,增加了一些功能。
我们这个版本,是在c语言的YOLOv3框架上进行修改的;网上还有很多基于pytorch、tensorflow构建的YOLOv3,以后有时间也写一下。

YOLOv3训练自己的数据集

标记数据

如果是训练自己的数据集,即还未对数据集进行标注,那么推荐使用LabelImg工具进行标注,可以得到适用于PascalVOC(xml)或者YOLO(txt)格式的标注。
因为官方给出的数据集已经是YOLO格式的标注,我们可以直接用。当然,考虑到后面某个功能使用了PascalVOC格式的标注,这里给出一个从YOLO(txt)格式转换成PascalVOC(xml)格式的代码txt2xml.py
此时,原始图像放在JPEGImages目录下,YOLO(txt)格式标注放在labels目录下,PascalVOC(xml)格式标注放在Annotations目录下。

制作 yolo 需要的txt文件

这一步需要制作四个文件:train.txt、val.txt、object_train.txt、object_val.txt。
train.txt、val.txt这两个文件保存了用于训练、验证图片的名字,每行一个名字(不带后缀.jpg)。这里参考了一个别人的代码img2train.py
object_train.txt、object_val.txt这两个文件保存了用于训练、验证图片的绝对路径,每行一个路径。这里参考了一个别人的代码voc_label.py。这个代码不仅可以划分文件,还可以将PascalVOC(xml)格式标注转换成YOLO(txt)格式标注。

制作 yolo 需要的配置文件

这一步需要制作三个文件:ct.names、ct.data、ct.cfg(ct是自己定义的,因为我用的是ct数据集,所以有此定义)。
ct.names包含数据集中的种类,每行一个。注意,这个顺序代表了之后预测时的种类顺序。
ct.data包含以下几个内容

classes= 1 # 类别数
train = data/object_train.txt # obj_train.txt 路径
valid = data/object_val.txt # obj_val.txt 路径
names = data/ct.names # ct.names 路径
backup = backup/ # 建一个 backup 文件夹用于存放 weights 结果

注意,这里放的是object_train.txt和object_val.txt,是写有绝对路径的txt文本。
ct.cfg包含的是与YOLOv3训练或测试相关的配置,有几个地方需要注意

1.注意文档开头training和testing的切换;
2.直接搜索‘classes’,修改三处对应位置:
[convolutional]
filters = 3*(classes + 5) #修改filters数量
[yolo]
classes=5 #修改类别数;
3.修改max_batches = 2000 * classes

训练

首先,下载预训练权重。

1
wget https://pjreddie.com/media/files/darknet53.conv.74

然后,执行训练命令。

1
./darknet detector train ./cfg/ct.data ./cfg/ct.cfg darknet53.conv.74

增加功能

在图像上添加置信度

YOLOv3单张图像检测的结果,默认设定只包含目标类别。我们可以通过修改src/image.c文件draw_detections()函数,添加目标置信度。修改片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
for(i = 0; i < num; ++i)
{
char labelstr[4096] = {0};
char s1[]={" "};// 为了name与置信度之间加空格
int class = -1;
char possible[5];// 存放检测的置信值
for(j = 0; j < classes; ++j)
{
sprintf(possible,"%.2f",dets[i].prob[j]);//置信值截取小数点后两位赋给possible
if (dets[i].prob[j] > thresh)
{
if (class < 0)
{
strcat(labelstr, names[j]);
strcat(labelstr, s1); //加空格
strcat(labelstr, possible);//标签中加入置信值
class = j;
}
else
{
strcat(labelstr, ", ");
strcat(labelstr, names[j]);
strcat(labelstr, s1);//加空格
strcat(labelstr, possible);//标签中加入置信值
}
printf("%s: %.0f%%\n", names[j], dets[i].prob[j]*100);
}
}
}

单张图像检测命令

1
./darknet detector test ./cfg/ct.data ./cfg/ct_test.cfg ct_final.weights test.jpg

批量检测图像

首先,修改example/detector.c文件,在开头添加一个获取图片名字的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char *GetFilename(char *p)
{
static char name[50]={""};
char *q = strrchr(p,'/') + 1;
int i = 0;
while(q[i] != '\0')
{
if(q[i] == '.') break;
i++;
}
strncpy(name,q,i);// i是图片名的长度
name[i] = '\0';
return name;

}

在这里,为了对不同长度的文件名能够兼容处理,设置name数组长度为50,可以根据需要修改。
然后,替换examples/detector.c 中的test_detector函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen)
{
list *options = read_data_cfg(datacfg);
char *name_list = option_find_str(options, "names", "data/names.list");
char **names = get_labels(name_list);

image **alphabet = load_alphabet();
network *net = load_network(cfgfile, weightfile, 0);
set_batch_network(net, 1);
srand(2222222);
double time;
char buff[256];
char *input = buff;
float nms=.45;
int i=0;
while(1){
if(filename){
strncpy(input, filename, 256);
image im = load_image_color(input,0,0);
image sized = letterbox_image(im, net->w, net->h);
layer l = net->layers[net->n-1];


float *X = sized.data;
time=what_time_is_it_now();
network_predict(net, X);
printf("%s: Predicted in %f seconds.\n", input, what_time_is_it_now()-time);
int nboxes = 0;
detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
free_detections(dets, nboxes);
if(outfile)
{
save_image(im, outfile);
}
else{
save_image(im, "predictions");
#ifdef OPENCV
cvNamedWindow("predictions", CV_WINDOW_NORMAL);
if(fullscreen){
cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}
show_image(im, "predictions",0);
cvWaitKey(0);
cvDestroyAllWindows();
#endif
}
free_image(im);
free_image(sized);
if (filename) break;
}
else {
printf("Enter Image Path: ");
fflush(stdout);
input = fgets(input, 256, stdin);
if(!input) return;
strtok(input, "\n");

list *plist = get_paths(input);
char **paths = (char **)list_to_array(plist);
printf("Start Testing!\n");
int m = plist->size;
if(access("/home/lzm/data/test_folder/darknet/car_person/out",0)==-1)//"/homelzm/......"修改成自己要保存图片的的路径
{
if (mkdir("/home/lzm/data/test_folder/darknet/car_person/out",0777))//"/homelzm/......"修改成自己要保存图片的的路径
{
printf("creat folder failed!!!");
}
}
for(i = 0; i < m; ++i){
char *path = paths[i];
image im = load_image_color(path,0,0);
image sized = letterbox_image(im, net->w, net->h);
//image sized = resize_image(im, net->w, net->h);
//image sized2 = resize_max(im, net->w);
//image sized = crop_image(sized2, -((net->w - sized2.w)/2), -((net->h - sized2.h)/2), net->w, net->h);
//resize_network(net, sized.w, sized.h);
layer l = net->layers[net->n-1];


float *X = sized.data;
time=what_time_is_it_now();
network_predict(net, X);
printf("Try Very Hard:");
printf("%s: Predicted in %f seconds.\n", path, what_time_is_it_now()-time);
int nboxes = 0;
detection *dets = get_network_boxes(net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes);
//printf("%d\n", nboxes);
//if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);
if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
free_detections(dets, nboxes);
if(outfile){
save_image(im, outfile);
}
else{

char b[2048];
sprintf(b,"/home/lzm/data/test_folder/darknet/car_person/out/%s",GetFilename(path));//"/homelzm/......"修改成自己要保存图片的的路径

save_image(im, b);
printf("OJBK!\n",GetFilename(path));
#ifdef OPENCV
cvNamedWindow("predictions", CV_WINDOW_NORMAL);
if(fullscreen){
cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}
show_image(im, "predictions",0);
cvWaitKey(0);
cvDestroyAllWindows();
#endif
}

free_image(im);
free_image(sized);
if (filename) break;
}
}
}
}

最后,在命令行输入make,更新文件。
批量检测命令,输入的路径为那些图片路径的txt。

1
./darknet detector test ./cfg/ct.data ./cfg/ct_test.cfg ct_final.weights

保存批量检测结果为txt文件

YOLOv3有自带的命令进行这个操作。

1
./darknet detector valid ./cfg/ct.data ./cfg/ct_test.cfg ct_final.weights results

计算recall

修改examples/detector.c的validate_detector_recall函数。
首先,将validate_detector_recall函数定义和调用修改如下:

void validate_detector_recall(char *datacfg, char *cfgfile, char *weightfile)
validate_detector_recall(datacfg, cfg, weights);

然后,将如下内容:

list *plist = get_paths(“data/coco_val_5k.list”);
char **paths = (char **)list_to_array(plist);

修改成

list *options = read_data_cfg(datacfg);
char *valid_images = option_find_str(options, “valid”, “data/train.list”);
list *plist = get_paths(valid_images);
char **paths = (char **)list_to_array(plist);

最后,记得make。
使用YOLOv3的命令调用方式。

1
./darknet detector recall ./cfg/ct.data ./cfg/ct_test.cfg ct_final.weights

计算mAP

需要用到PascalVOC(xml)格式的注释,可以用文章开始提到的代码txt2xml.py进行转换。
可以先借助py-faster-rcnn下的voc_eval.py计算出单个类别的AP,然后求平均得到mAP。
新建一个all_map.py文件用于计算mAP,这边提供了别的博主的一个例子。
如果需要重复计算mAP,需要删除生成的annots.pkl。

参考
YOLOv3:训练自己的数据(附优化与问题总结)
How to train YOLOv3 model
YOLO-V3实战(darknet)

@TOC

1
scp -P 端口号 本地文件 服务器用户名@服务器ip:目标文件夹

然后,输入”yes”,回车。
最后,输入密码,回车。

@[TOC](Jetson Nano & TX2配置教程)
更新于2021年4月10日。本文介绍了Jetson Nano 和 Jetson TX2两种设备的配置教程,前一部分以Jetson Nano为例,后半部分以Jetson TX2为例。这两种设备的配置教程,大体上是相近的。

Jetson Nano 激活

首先,拿到一张64GB/128GB(12GB的卡不够用)的micro-SD card,并进行格式化。SD卡的格式化工具,直接从官网下载即可,使用时选择“快速格式化”。

然后,从Nvidia官网下载你需要的jetson nano镜像。

注意确定安装的jetpack版本,这关系到其自带的cuda版本。简单来说,jetpack4.4以上,只能安装pytorch1.6以上PyTorch for Jetson - version 1.8.0 now available。而且在pytorch1.6环境下保存的模型,没办法在更低版本的pytorch中打开。

旧版本可以从官网JetPack Archive寻找。
最后,根据Nvidia官网教程完成镜像的烧录,大概需要半个小时的时间。

Jetson TX2 烧录

这里给出两个链接,一个是官网链接使用SDK Manager安装Jetson软件,另一个是知乎上的链接Jetson TX2 入门教程(镜像烧写)

更新系统国内源

在使用系统之前,我们先将系统更换为国内安装源。
首先,备份source.list。

1
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

然后,修改source.list。推荐用gedit,十分方便。如果没有安装的话,需要先安装一下。

1
2
sudo apt-get install gedit
sudo gedit /etc/apt/sources.list

接着,替换list中的内容。

1
2
3
4
5
6
7
8
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main multiverse restricted universe
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main multiverse restricted universe

最后,更新软件。update和upgrade的区别可以参考linux命令系列 sudo apt-get update和upgrade的区别
这一步可能需要花一段时间。

1
2
sudo apt-get update 
sudo apt-get upgrade

安装系统工具jtop

Jetson Nano中有个工具jtop, 可以查看CPU和GPU资源,还可以显示系统的jetpack版本,十分好用。
首先,安装pip3.

1
sudo apt-get install python3-pip

同样的,我们也可以将pip修改为国内源。
第一种方式,长期修改。我以阿里源为例,其他国内源只需要修改链接即可。

1
pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/

然后,使用pip安装jetson-stats。
第二种方式,一次性修改。我以清华源为例,其他国内源只需要修改链接即可。

1
sudo pip3 install jetson-stats -i https://pypi.tuna.tsinghua.edu.cn/simple

安装好之后,我们来看一下效果如何。

1
sudo jtop

从源代码编译opencv

刷机后的Nano已经预装了opencv,但是预装版本不支持CUDA,所以我们还要在Jetson Nano上手动安装OpenCV。

方法一
安装已编译的opencv,简单方便,但是这个版本过低,且不能指定其他版本。

1
sudo apt-get install opencv-python

方法二
从源代码安装,但是使用别人写好的脚本,如buildOpenCVXaviernano_build_opencv。但是报错之后,可能不知道自己为什么错了,因为脚本不是你自己写的。

方法三
自己从源代码编译安装,有很多坑要踩啊。
不能先安装archconda等虚拟环境管理包,否则会有问题!参考在Jetson Nano中为python3安装OpenCV

  1. 增加交换空间

opencv的编译时生成的中间文件很大,Jetson Nano原始空间放不下。这里介绍一种永久生效的方法。要是只想临时生效,可以参考Enlarge memory swap

查看当前系统的交换空间。

1
sudo swapon --show

查看内存大小。

1
free -h

创建用于swap的文件。

1
sudo fallocate -l 2G /swapfile

设置交换空间。

1
sudo mkswap /swapfile

激活交换空间。

1
2
3
4
sudo swapon /swapfile
#为了使这个激活永久有效
sudo gedit /etc/fstab
#粘贴 /swapfile swap swap defaults 0 0

验证增加空间是否有效。

1
2
sudo swapon --show
sudo free -h
  1. 安装依赖项
    这个依赖项的要求五花八门,取决于你对功能的要求,这里我只给出我使用的依赖项,参考compile deeplearning libraries for jetson nano。如果遇到包冲突问题,参考aptitude与apt-get解决。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
dependencies=(build-essential
cmake
pkg-config
libavcodec-dev
libavformat-dev
libopenblas-base
libopenmpi-dev
libswscale-dev
libv4l-dev
libxvidcore-dev
libavresample-dev
python3-dev
python3-numpy
libtbb2
libtbb-dev
libtiff-dev
libjpeg-dev
libpng-dev
libtiff-dev
libdc1394-22-dev
libgtk-3-dev
libcanberra-gtk3-module
libatlas-base-dev
gfortran
wget
unzip)

sudo apt install -y ${dependencies[@]}
  1. 下载源代码
    安装所有第三方依赖项后,我们就需要下载OpenCV啦。需要两个压缩包:基本库和其他拓展库。在opencv官网下载你需要的版本。这里以4.4.0版本为例。

在github网址下载opencv-4.4.0.zip,复制下面的网址,在浏览器直接下载。

1
https://github.com/opencv/opencv/archive/4.4.0.zip

在github网址下载opencv_contrib-4.4.0.zip,复制下面的网址,在浏览器直接下载。

1
https://github.com/opencv/opencv_contrib/archive/4.4.0.zip

对下载后的opencv-4.4.0.zip和opencv_contrib-4.4.0.zip进行解压缩。
在opencv-4.4.0文件夹下打开命令行,新建一个build文件夹,并切换到build文件夹下。

1
2
mkdir build
cd build
  1. 编写cmake配置文件my_cmake.sh
    这里是对opencv和cuda做的一些配置,和依赖库一样也是五花八门,看你的需求吧。这里我给出自己的配置,仅供参考。

新建脚本文件。

1
gedit my_cmake.sh

粘贴cmake命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D WITH_CUDA=ON \
-D CUDA_ARCH_PTX="" \
-D CUDA_ARCH_BIN="5.3,6.2,7.2" \
-D WITH_CUBLAS=ON \
-D WITH_LIBV4L=ON \
-D BUILD_opencv_python3=ON \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_java=OFF \
-D WITH_GSTREAMER=OFF \
-D WITH_GTK=ON \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_EXAMPLES=OFF \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.4.0/modules \
..

具体每个选项的介绍,可以参考Jetson Nano 从头配置OpenCV+CUDA+QT完整流程

执行make命令。

1
sh ./my_cmake.sh

在我们进入实际编译步骤之前,请确保检查CMake的输出!参考树莓派安装OpenCV-4.1.0及Contrib

  1. 开始构建
    1
    $ make -j4
    -j4表示4个CPU核心同时运行。
    查看CPU核心数,参考Ubuntu 18.04配置OpenCV 4.2.0
1
nproc

经过漫长的等待,约两小时。
可能遇到错误,这是网络问题导致部分依赖包没有下载。
错误一
参考Jetson Nano 从头配置OpenCV+CUDA+QT完整流程中相关部分的解决方案。

1
fatal error: boostdesc_bgm.i: No such file or directory

错误二

1
fatal error: opencv2/xfeatures2d/cuda.hpp: No such file or directory

参考opencv安装opencv_contrib出现无法打开包括文件: “opencv2/xfeatures2d/cuda.hpp”中的解决方案。记得加在最开始,不要加在最后面!

错误三

1
2
3
4
5
6
7
8
9
10
11
12
CMakeFiles/example_gpu_surf_keypoint_matcher.dir/surf_keypoint_matcher.cpp.o: In function `main':
surf_keypoint_matcher.cpp:(.text.startup.main+0x352): undefined reference to `cv::cuda::SURF_CUDA::SURF_CUDA()'
surf_keypoint_matcher.cpp:(.text.startup.main+0x579): undefined reference to `cv::cuda::SURF_CUDA::operator()(cv::cuda::GpuMat const&, cv::cuda::GpuMat const&, cv::cuda::GpuMat&, cv::cuda::GpuMat&, bool)'
surf_keypoint_matcher.cpp:(.text.startup.main+0x60d): undefined reference to `cv::cuda::SURF_CUDA::operator()(cv::cuda::GpuMat const&, cv::cuda::GpuMat const&, cv::cuda::GpuMat&, cv::cuda::GpuMat&, bool)'
surf_keypoint_matcher.cpp:(.text.startup.main+0x6af): undefined reference to `cv::cuda::SURF_CUDA::defaultNorm() const'
surf_keypoint_matcher.cpp:(.text.startup.main+0x7ca): undefined reference to `cv::cuda::SURF_CUDA::downloadKeypoints(cv::cuda::GpuMat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&)'
surf_keypoint_matcher.cpp:(.text.startup.main+0x7ea): undefined reference to `cv::cuda::SURF_CUDA::downloadKeypoints(cv::cuda::GpuMat const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&)'
surf_keypoint_matcher.cpp:(.text.startup.main+0x800): undefined reference to `cv::cuda::SURF_CUDA::downloadDescriptors(cv::cuda::GpuMat const&, std::vector<float, std::allocator<float> >&)'
surf_keypoint_matcher.cpp:(.text.startup.main+0x812): undefined reference to `cv::cuda::SURF_CUDA::downloadDescriptors(cv::cuda::GpuMat const&, std::vector<float, std::allocator<float> >&)'
collect2: error: ld returned 1 exit status
samples/gpu/CMakeFiles/example_gpu_surf_keypoint_matcher.dir/build.make:132: recipe for target 'bin/example_gpu_surf_keypoint_matcher' failed
make[2]: *** [bin/example_gpu_surf_keypoint_matcher] Error 1

参考源码编译安装OpenCV4.5+ CUDA11 带python 遇到的错误总结中的解决方案。

  1. 安装
1
make install
  1. 验证
1
2
$ python3 -c "import cv2; print(cv2.__version__)"
4.4.0

安装archconda

anaconda是深度学习的好工具。在arm64框架平台上,对应有一个archconda,是大神编译好的工具,我们可以直接使用。
从大神github网址上下载sh文件,然后就像在普通linux上安装即可。

如果需要在虚拟环境中使用opencv,有两种方法。
方法一
链接,参考Installing OpenCV 4 on NVIDIA Jetson Nano

1
2
3
4
5
6
7
8
9
10
# Go to the folder where OpenCV's native library is built
cd /usr/local/lib/python3.6/site-packages/cv2/python-3.6
# Rename
mv cv2.cpython-36m-xxx-linux-gnu.so cv2.so
# Go to your virtual environments site-packages folder if previously set
cd ~/env/lib/python3.6/site-packages/
# Or just go to your home folder if not set a venv site-packages folder
cd ~
# Symlink the native library
ln -s /usr/local/lib/python3.6/site-packages/cv2/python-3.6/cv2.so cv2.so

方法二
拷贝,参考How to check for successful install including in virtualenv. #32

1
2
3
4
# Go to the folder where OpenCV's native library is built
cd /usr/local/lib/python3.6/site-packages/cv2/python-3.6
# copy
cp usr/local/lib/python3.6/site-packages/cv2/python-3.6 [path to venv]/lib/python3.6/site-packages/cv2/python-3.6

在虚拟环境中导入cv2,可能会遇到下面一个错误。

1
2
from .cv2 import *
ImportError: numpy.core.multiarray failed to import

这主要是在编译opencv的时候使用的numpy,和虚拟环境中安装的numpy版本不一致,根据安装时的numpy版本修改一下即可,参考cv2: numpy.core.multiarray failed to import
查看编译opencv的时候使用的numpy版本,可以进入系统自带的python环境,输出numpy版本号。

1
2
>>> import numpy
>>> print(numpy.__version__)

还有可能遇到另一个问题。

1
2
>>> import numpy
>>> Illegal instruction (core dumped)

这是numpy版本的问题,将numpy=1.19.5降级到numpy=1.19.4或更低版本即可,参考Illegal instruction (core dumped)

安装mmdetection

这一部分使用的是Jetson TX2,参考在Jetson tx2安装 mmdetection环境

这里我遇到了一个小问题,TX2接上网线但是连不上网,解决方法参考Jetson TX2 有线网络网线不识别,灯不亮问题

其实,安装完opencv后,要运行mmdetection的代码,还有4个重要的包需要安装:torch,torchvision,mmcv-full,mmdet。

  1. 安装torch

去NVIDIA官网下载配套的版本PyTorch for Jetson - version 1.7.0 now available,这一步需要翻墙。
注意查看自己的Jetpack版本号,4.4要用torch1.6,否则会报错cudnn版本不合适。
查看Jetson设备的信息可以用之前提到的jtop,也可以使用查询Jetson设备与开发环境版本的基础信息
下载好pytorch之后,激活虚拟环境,使用pip命令安装。

1
pip install torch-1.6.0-cp36-cp36m-linux_aarch64.whl

有可能遇到问题

1
OSError: libmpi_cxx.so.20: cannot open shared object file: No such file or directory

参考Cannot install pytorch,安装两个依赖。

1
sudo apt-get install libopenblas-base libopenmpi-dev 
  1. 安装torchvision

需要根据torch版本来选择对应版本的torchvision进行安装,参考Jetson Nano 安装torch和torchvision

1
2
3
4
git clone --branch v0.7.0 https://github.com/pytorch/vision torchvision
cd torchvision
export BUILD_VERSION=0.7.0
sudo python setup.py install
  1. 安装mmcv-full和mmdet

这里的教程跟mmdetection官方教程来走就好了。

安装mmcv-full

1
2
3
git clone https://github.com/open-mmlab/mmcv.git
cd mmcv
MMCV_WITH_OPS=1 pip install -e . # 安装full版本

安装mmdetection

1
2
3
4
git clone https://github.com/open-mmlab/mmdetection.git
cd mmdetection
pip install -r requirements/build.txt
pip install -v -e .

注意

  • mmcv-full和mmdet的版本号要对应,官方教程已经给出来了对应关系。
  • 安装mmcv-full,而不是mmcv,否则后面可能会有奇怪的错误。
1
MMCV_WITH_OPS=1 pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple
  • 在使用pip命令时,后面跟上国内源,这样下载其他依赖包会更快一些。
  • 上面两个包安装完,也要花挺长时间的。
  • 有可能遇到安装matplotlib,scipy,pillow等包的时候,与已经安装的numpy版本冲突。这种情况下不能修改numpy的版本,要修改其他包的版本。
  • 可以使用下面这条命令,查看哪个版本的包时候你的numpy,包和版本号可以更改,参考conda查看某个安装包的依赖项
1
conda search scipy=1.0.0 -info
  1. 测试

按照官网的代码,做了一些修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
from mmdet.apis import inference_detector, init_detector, show_result_pyplot

config_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py'
# download the checkpoint from model zoo and put it in `checkpoints/`
# url: http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'
device = 'cuda:0'
# init a detector
model = init_detector(config_file, checkpoint_file, device=device)
# inference the demo image
result = inference_detector(model, 'demo/demo.jpg')
# show the results
show_result_pyplot(model, 'demo/demo.jpg', result, score_thr=0.3)

参考
【Jetson-Nano】jetson_nano安装环境配置及tensorflow和pytorch安装教程
Jetson Nano配置与使用(1)开机
在Jetson Nano (TX1/TX2)上使用Anaconda与PyTorch 1.1.0
Install OpenCV 4.5.0 on Jetson Nano
compile deeplearning libraries for jetson nano
linux命令系列 sudo apt-get update和upgrade的区别buildOpenCVXavier
nano_build_opencv
在Jetson Nano中为python3安装OpenCV
Installing OpenCV 4 on NVIDIA Jetson Nano
Jetson Nano 从头配置OpenCV+CUDA+QT完整流程
树莓派安装OpenCV-4.1.0及Contrib
Ubuntu 18.04配置OpenCV 4.2.0
opencv安装opencv_contrib出现无法打开包括文件: “opencv2/xfeatures2d/cuda.hpp”
源码编译安装OpenCV4.5+ CUDA11 带python 遇到的错误总结
cv2: numpy.core.multiarray failed to import
在Jetson tx2安装 mmdetection环境

@TOC
因为跑一个多目标跟踪的代码,要用到yolov3,所以作为pytorch用户的我,第一次用上了tensorflow。
但是我使用的镜像环境,是cuda10.1版本的:
在这里插入图片描述
代码使用的tensorflow,是1.13.1版本的;需要将cuda降到10.0。
这里有一篇博客,展示了Tensorflow不同版本要求与CUDA及CUDNN版本对应关系,一般我们都是装好了tensorflow-gpu,然后需要对应版本的CUDA及CUDNN,可以让大家参考一下。

用conda安装对应的cudatoolkit

1
conda install cudatoolkit=10.0 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/linux-64/

用conda安装对应的cudnn

1
conda install cudnn=7.5.0 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/linux-64/

这样每次运行时,会链接到这个版本的cuda和cudnn,实际的cuda版本没有变。

参考链接:
tf-gpu报错:ImportError: libcublas.so.10.0: cannot open shared object file: No such file or directory
Ubuntu下使用conda在虚拟环境中安装CUDA、CUDNN及Tensorflow
conda安装cudnn和cudatoolkit

@[TOC](Linux系统报错:Failed to execute default Terminal Emulator. Input/output error.)
最近新配了一个服务器环境,之前使用的是配置好anconda和pytorch等库的环境,但是这次申请忘记了之前那个环境是哪一个,所以要重新配置。
一登陆之后,打算打开命令行,开始配tensorflow环境,就遇到了一个问题:

1
Failed to execute default Terminal Emulator. Input/output error.

命令行打不开了!
查询资料之后得知,是Linux系统默认的命令行不对,需要自己手动修改一下:

  1. 点击桌面左上角的Applications

在这里插入图片描述

  1. 点击Settings,选择Settings Manager
    在这里插入图片描述
  2. 点击Preferred Applications

在这里插入图片描述
4. 点击Utilities下的Terminal Emulator,选择Xfce Terminal
在这里插入图片描述
然后就可以正常使用了。
参考链接:Failed to execute default Terminal Emulator. Input/output error.

@TOC

前言

最近在做一个项目,涉及到了如何用C#调用Python文件。汇总了一下网上找来的资料,具体参考了这篇博客c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)
对于第一种方法,使用IronPython2.7的方法,我找到了更详细的博客C#如何调用Python执行脚本,并将执行结果显示值显示至C#界面,不过Python2.7可能无法满足我们项目的需求,当然我也找到了类似的另外两种可以使用Python3的方法,还没有试过,在这里提供给大家参考C#使用公共语言拓展(CLE)调用Python3(使用TensorFlow训练的模型)pythonnet c#调用并集成python代码
对于第三和第四种方法,因为要使用命令行窗口,而且还要考虑不同用户的python安装情况如何,在项目实际使用时效果肯定是很不好的,所以在这里不做过多的介绍,原博主也给出了他自己的源代码,大家可以自己尝试一下。
重点说一下第二种方法。我在CSDN上找了好多博客,大家的方法都大同小异,可能真的是看人品吧,我试了好几次都失败了,最后在朋友的帮助下才成功……

配置环境

这里先说一下,我是win10+VS2017+Python3.7.4。

第一步新建一个控制台项目,修改属性页

选择Debug|x64
在这里插入图片描述第一个修改的是C/C++——常规——附加包含目录:添加你所安装的Python目录下的include目录路径。
在这里插入图片描述第二个修改的是链接器——常规——附加库目录:添加你所安装的Python目录下的libs目录路径。

第二步修改Python安装目录下文件

在这里插入图片描述
找到Python安装目录,找到libs目录复制python37.lib到本目录,改名为python37_d.lib。

代码测试

现在我们可以来简单测试一下

测试用Python3语法输出“Hello World!”

我们定义一个print(),里面用了Python3的语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "pch.h"
#include <Python.h>
#include <iostream>

using namespace std;

void print()
{
Py_Initialize();
PyRun_SimpleString("print('Hello World!')\n");//Python3语法
Py_Finalize();
}

int main()
{
print();
return 0;
}

测试用Python文件输出“Hello World!”

定义一个Hello(),里面调用了Test001.py文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "pch.h"
#include <Python.h>
#include <iostream>

using namespace std;

void print()
{
Py_Initialize();
PyRun_SimpleString("print('Hello Python!')\n");
Py_Finalize();
}

void Hello()
{
Py_Initialize();//调用Py_Initialize()进行初始化
PyObject * pModule = NULL;
PyObject * pFunc = NULL;
pModule = PyImport_ImportModule("Test001");//调用的Python文件名
pFunc = PyObject_GetAttrString(pModule, "Hello");//调用的函数名
PyEval_CallObject(pFunc, NULL);//调用函数,NULL表示参数为空
Py_Finalize();//调用Py_Finalize,和Py_Initialize相对应的.
}

int main()
{
print();
Hello();
return 0;
}

Test001.py文件内容如下:

1
2
def Hello():
print("Hello World!")

注意,要把Test001.py文件放到ConsoleApplication1.exe同级目录
在这里插入图片描述
在这里插入图片描述

结尾

如果一切顺利的话,那你现在已经在控制台看到输出了;如果不顺利的话,可以找找其他的博客,或者换一个方法,不要拘泥于这一个思路……
从今天开始,这个博客会把我之前做项目遇到的一些问题的解决办法总结一下,也算是一种积累吧,估计等我项目做完,会写成一本《扑街实录》。

引用

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)
C#如何调用Python执行脚本,并将执行结果显示值显示至C#界面
C#使用公共语言拓展(CLE)调用Python3(使用TensorFlow训练的模型)
pythonnet c#调用并集成python代码

摘要

有时候我们拿到一份PDF学习资料,发现上面有前人留下的很多注释/高亮,干扰了我们对资料的阅读。对于一条注释/高亮,我们可以选择直接删除;对于多条注释/高亮,我们可以选择全选删除。遗憾的是,直接使用ctrl+A无法全选所有注释/高亮。这里介绍一种方法,使用shift键,只需4步批量删除PDF文件中所有注释/高亮。

阅读全文 »