第二章 VS2017版本YOLO
第一步:在windows用git下载YOLO的源码。PS:安装windows版本的git,使用git下载
第二步:创建一个windows console application工程
第二步:删除掉工程所有.h .cpp文件
第三步:导入yolo的源码,我建议把git下载的yolo代码一股脑的全部放到vs新建的工程里边去,主要是examples include src三个文件夹下的代码
第四步:将所有代码复制到vs工程根目录后然后在vs添加这些代码,右键项目->添加->现有项目。只添加.h .c文件,因为我这边暂时不用cuda,所以不用导.cu
第五步:到这步我们直接编译,出现什么问题解决什么问题
a. 出现pch.h的问题,我们直接关闭掉预编译头就可以了
Error C1010 unexpected end of file while looking for precompiled header. Did you forget to add '#include "pch.h"' to your source?
b. 出现pthread.h的问题我们直接导入pthread的头文件
Error C1083 Cannot open include file: 'pthread.h': No such file or directory
因为pthread是posix的线程相关操作,所以windows没有也很正常,不过有替代方案。
去 http:// sourceware.org/pthreads -win32/ 下载,由于我已经下载好了,所以我就不下载了。
右键工程添加pthread的头目录
右键工程属性添加pthread库目录
这儿要注意区分64位和32位,因为源码就在这里,想用多少位就用多少位,主要是pthread要区分好。
右键工程添加pthread库:
c. 打不开sys/time.h,打不开unistd.h
Error C1083 Cannot open include file: 'sys/time.h': No such file or directory
由于sys/time.h unistd.h 为linux的函数,打不开我们注释掉就好了。
d. 关于C语言自带函数不安全的问题
Error C4996 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
微软已经提出解决办法了,右键添加预编译宏
e. attention.c 'show_image'参数错误问题
Error C2198 'show_image': too few arguments for call
这个时候我们去看一下linux的版本的makefile有没有这个.c
因为找不到这个.c表明这个已经被弃用了,所以从工程里边删除吧。
同理还有这些
compare.c
Error C2440 'function': cannot convert from 'network' to 'network *'
dice.c
Error C2440 'function': cannot convert from 'network' to 'network *'
voxel.c
Error C2440 'function': cannot convert from 'network' to 'network *'
writing.c
Error C2440 'function': cannot convert from 'network' to 'network *'
swag.c
Error C1083 Cannot open include file: 'sys/time.h': No such file or directory
然后我发现go.c的错误最多,对于整个程序运行YOLOV3模型也有没帮助所以我们直接删除掉go.c,我们工程的错误仅剩下如下错误:
我们把what_time_is_it_now用标准C的函数代替:
double what_time_is_it_now()
{
time_t t = time(NULL);
return t;
}
arr前边加上(char*)强转
void sorta_shuffle(void *arr, size_t n, size_t size, size_t sections)
{
size_t i;
for(i = 0; i < sections; ++i){
size_t start = n*i/sections;
size_t end = n*(i+1)/sections;
size_t num = end-start;
shuffle((char*)arr+(start*size), num, size);
}
}
void shuffle(void *arr, size_t n, size_t size)
{
size_t i;
void *swp = calloc(1, size);
for(i = 0; i < n-1; ++i){
size_t j = i + rand()/(RAND_MAX / (n-i)+1);
memcpy(swp, (char*)arr+(j*size), size);
memcpy((char*)arr+(j*size), (char*)arr+(i*size), size);
memcpy((char*)arr+(i*size), swp, size);
}
}
删除掉go.c带来的弊病
Error LNK2019 unresolved external symbol _run_go referenced in function _main
屏蔽所有对go.c的函数调用
至此编译成功
但是我们跑程序的时候还需要输入参数,我比较懒,不想去加vs的调试运行参数,直接注释掉以前的mian,重写一个main带上我们参数
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
我们把分析上边参数对应main函数的走向,可以看到
detect走的这儿,我们直接拷贝代码段到新的main函数稍微修整一下,生成如下代码
最后记得把yolov3.weights放到工程的根目录。
Darknet下的cfg 和 data目录也拷贝到工程的根目录。
整个目录按照类型来排大致是这个样子:
f.运行提示少dll,我们把pthread的dll拷贝到debug目录
g.加载39层卷积层出错,看不出错误原因,看到内存超过2G了。
所以我们应该要切到64位去看看了,64位下重新配置一下工程的pthread,然后debug成功。
由于没有开优化,整整跑了358秒。
下一篇我们分析yolov3.cfg,以及对应算法层的.c。