Win10_VS2013_CPU_Darknet编译踩坑_CarnivoreRabbit的博客-程序员宝宝

技术标签: 计算机视觉  深度学习  学习数字图像处理  

Win10_VS2013_CPU_Darknet_YOLOV4编译踩坑

1 踩坑原因

  • 手贱
  • 使用Darknet;
  • 学习Darknet源码;
  • 配合VS2013开发项目的需要

这里再梳理一下我的路线:

→ \rightarrow 编译Darknet(CPU版本/GPU版本)

→ \rightarrow 使用别人训练的模型进行图片推理

→ \rightarrow 训练自己的模型

→ \rightarrow 调试修改Darknet源码

→ \rightarrow 集成到其他的图像处理项目

→ \rightarrow 部署项目并使用

编译只是第一步,编译CPU版本是第一步中的第一步。

其实如果使用VS2015以上版本进行编译,会少很多坑。但是截至目前为止仍然有很多开发团队仍在采用VS2013。小白发现在网络上,鲜有详细介绍如何在VS2013下进行no_gpu版本Darknet编译的文章或资料。偶尔有一两篇,可能由于作者自身调试编译水平较高,对一些问题一笔带过。

win10+vs2013+opencv 3.1编译darknet YOLOv3 采坑记录
Windows下 YOLOv3配置教程(YOLOv3项VS2013平台迁移的方法)

以上这两篇是小白读到的比较有参考价值的两篇,但小白进行编译的时候遇上的不少坑,是这两篇博客里都没有提到的。小白在两台电脑上分别编译了两次,第一次编译侥幸成功后,竟然把中间一些细节给忘记了。第二次编译仍然把一些坑重新趟了一遍。因此,第二次编译时,小白把一些问题记录了下来,聊以作为后来者的参考。
限于小白的水平,若有错漏,欢迎指正!敬请见谅!

2 VS工程下载

DarkNet YoloV3及其之前的系列是由pjreddie维护的https://pjreddie.com/darknet/,但这个版本是Linux下的源码版本,如果需要在win10系统下进行VS工程的编译,则需要自己从头去建立工程,这对于像小白一样水平有限的读者来说是困难的。
好在从YoloV4开始,AlexeyAB大神为大家提供了可供VS编译的版本:
https://github.com/AlexeyAB/darknet
让我们先从github上把工程和源码下载下来.
从.\darknet-master\build\darknet 路径下可以看到no_gpu版的工程文件.
在这里插入图片描述

我们的趟坑之旅就从这里开始.

3 修改VS工程文件

第一个坑来自我们使用的VS版本,AlexeyAB大神提供的工程文件是由VS2015完成的。所以我们需要修改VS工程文件,使工程文件可以为VS2013所用。
鉴于我们要编译的是no_gpu版本,所以我们首先修改工程文件中VS的版本。 这里需要操作的是darknet_no_gpu.sln和darknet_no_gpu.vcxproj这两个文件。
首先我们来看darknet_no_gpu.sln文件:
在这里插入图片描述

上图是已经修改好的darknet_no_gpu.sln文件,大家可以跟原先的版本进行比较,可以发现主要是把Visual Studio的版本进行了修改。
VisualStudioVersion改成了12.0.40629

对于darknet_no_gpu.vcxproj,则需要修改的地方更多。
在这里插入图片描述

14.0对应的是VS2015,如果是VS2013则需要将其改成12.0;
在这里插入图片描述

v140对应的是VS2015,如果是VS2013则需要将其改成v120。

4 配置OpenCV

既然我们是用VS2013来进行编译,那么显然我们也需要能支持VS2013的OpenCV版本,而OpenCV官网已经没有直接可用的VS2013对应版本,需要用源码进行编译。 关于这个问题可以参看小白之前的博客。
OpenCV学习笔记(2)_CMake+Visual Studio 2013 源码编译CPU版本的OpenCV
配置时可以针对darknet_no_gpu.vcxproj文件进行修改。也可以直接在VS里面直接进行配置。以下举例如何在darknet_no_gpu.vcxproj文件中进行修改。

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <OutDir>$(SolutionDir)$(Platform)\</OutDir>
    <IntDir>$(Platform)\nogpu_$(Configuration)\</IntDir>
    <LibraryPath>..\..\3rdparty\opencv\x64\vc12\bin;..\..\3rdparty\pthreads\bin;..\..\3rdparty\opencv\x64\vc12\lib;..\..\3rdparty\pthreads\lib;$(LibraryPath)</LibraryPath>
    <ReferencePath>$(ReferencePath)</ReferencePath>
    <IncludePath>..\..\3rdparty\opencv\include;$(IncludePath)</IncludePath>
  </PropertyGroup>

小白是把opencv放在了3rdparty路径下,用的是opencv3.4.16

  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <Optimization>MaxSpeed</Optimization>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <AdditionalIncludeDirectories>..\..\3rdparty\opencv\include;..\..\3rdparty\opencv\include\opencv;..\..\3rdparty\opencv\include\opencv2;..\..\include;..\..\3rdparty\stb\include;..\..\3rdparty\pthreads\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>OPENCV;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_RAND_S;WIN32;NDEBUG;_CONSOLE;_LIB;_XKEYCHECK_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <CLanguageStandard>c11</CLanguageStandard>
      <CppLanguageStandard>c++1y</CppLanguageStandard>
      <PrecompiledHeaderCompileAs>CompileAsCpp</PrecompiledHeaderCompileAs>
      <CompileAs>Default</CompileAs>
      <UndefinePreprocessorDefinitions>CUDNN</UndefinePreprocessorDefinitions>
      <OpenMPSupport>true</OpenMPSupport>
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
    </ClCompile>
    <Link>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <AdditionalLibraryDirectories>..\..\3rdparty\opencv\x64\vc12\lib;..\..\3rdparty\pthreads\lib;..\..\3rdparty\opencv\x64\vc12\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <AdditionalDependencies>pthreadVC2.lib;opencv_world3416.lib;opencv_world3416d.lib;%(AdditionalDependencies)</AdditionalDependencies>
      <OutputFile>$(OutDir)\$(TargetName)$(TargetExt)</OutputFile>
    </Link>

5 应对各种报错

这一部分其实是很多博客中忽略而过的。 有一位博主如是写道“百度基本上都可以解决”。 小白自己确实也是通过各种百度来解决这些问题,但是其中艰辛。。。咳咳,虽然很有可能小白所遇到的不是各位读者都会遇到的问题,但至少在小白编译过程中遇上了这些问题,在此聊以记录。
小白编译了两次,两次遇上的问题基本上也差不多,但是小白没有把错误的截图截下来,所以只能用文字的方式记述一下大概的问题。
注意我们需要在release x64下进行编译。

  • 报错1:error C2065:"__func__":未声明的识别符

    • 需要找到utils.h文件,把__func__改成 __FUNCTION__
  • 报错2:error C2054: 在“inline”之后应输入“(”

    • 问题出在col2im.c,解决方案是把出错行的inline static删除掉
    • 虽然这么做可能会有隐患,但是,对!就这么做了!还就起效了!
  • 报错3:error C2059: 语法错误:“数字上的错误后缀”

    • 问题出在gemm.c,把错误行中0b1111改写成0x0f或直接就是15
    • 这个问题的原因似乎是VS中不支持二进制数的写法,写成十六进制或者十进制好像都可以
  • 报错4:未定义的ct

    • 在项目上右键 → \rightarrow 属性 → \rightarrow C/C++ → \rightarrow 预处理器 → \rightarrow 预处理器定义,去掉TIME开头的那个定义
      在这里插入图片描述
  • 报错5:错误名称忘记了,反正记得跟上一个错误的解决方法类似,在预处理器中添加_XKEYCHECK_H

  • 报错6:error C2065: “bufsiz”: 未声明的标识符

    • 解决方法是在httplib.h中,把报错行中的bufsiz改写成BUFSIZ
  • 报错7:error C2664: “int _snprintf_s(char *,size_t,size_t,const char *,...)”: 无法将参数 1 从“std::array<char,0x0800>”转换为“char *”

    • 还是在httplib.h文件中,把报错行中的buf改成buf.data()

解决完以上错误之后,语法上的错误基本上就结束了,接下来进入链接器的错误修改:

  • 报错8:error LNK2001: 无法解析的外部符号 snprintf
    • 需要在darknet.h中添加
#if defined(_MSC_VER)
#define snprintf _snprintf_s
#endif
  • 报错9:error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for more information.
  • 报错10:链接器错误之无法解析的外部符号 this_thread_sleep_for custom_join等
    • 问题的原因:VS2013并没有完全支持C++11
    • 解决方法:http_stream.c文件中,改写cpp的版本,只需要大于等于199711L即可,即#if __cplusplus >= 199711L || _MSC_VER >= 1900
  • 补充11:因为需要用到多线程,且编译时用到的是lib库文件。所以需要做以下调整:
    在这里插入图片描述
    在这里插入图片描述

6 下载yolov4.weights权重文件并测试

如果趟过以上诸坑,那你应该能最终获得编译好的darknet_no_gpu.exe文件。但很遗憾,你还不能立刻进行测试,因为在源码包里,唯独缺了模型的权重文件。
我们可以在github上查看ModelZoo
在这里插入图片描述

可以在这里直接下载yolov4.weights,放到backup文件路径下。
接下来就可以在cmd中用以下命令行测试了:

darknet_no_gpu.exe detector test ./data/coco.data ./cfg/yolov4.cfg ./backup/yolov4.weights dog.jpg

因为是cpu版本,所以自然是比较慢的,耐心等待。。。
在这里插入图片描述

到此时,小白泪牛满面。终于把这个坑都踩过去了。不容易啊。
希望读者也能成功趟坑,开启我们的深度学习之旅。
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/horsee/article/details/124203943

智能推荐

java创建临时文件上传服务器,解决springboot项目上传文件出现临时文件目录为空的问题..._weixin_39719989的博客-程序员宝宝

最近写文件上传到服务器读取的代码,前端使用FormData上传,服务端用MultipartFile接收,自己测试了下MultipartFile对象有什么东西,结果一般属性都能出来,测试getInputStrea()方法的时候出现了以下错误,简单一看这是什么目录,从来没见过啊:百度一番之后发现了这是临时文件存放的路径,不清楚根据什么去放在这个目录的,但是这个目录本机的确没有,linux系统下好像系统..._1671465600

postman调用rpc服务器接口_接口测试基础之入门篇_weixin_39557373的博客-程序员宝宝

前言 什么是接口呢?一、常见接口:接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。程序内部的接口:方法与方法之间,模块与模块之间的交互,程序内部抛出的接口,比如bbs系统,有登录模块、发帖模块等等,那你要发帖就必须先登录,那么这两个模块就得有交互,它就会抛出一个接口,供内部系统进行调用。系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,他给你提供一个他们写好的方法来获取数...

c语言延时函数delay延时一秒_使用树莓派拍摄延时动画,制作GIF图_weixin_39717825的博客-程序员宝宝

本期教大家将编写一个小脚本用树莓派来捕获多个图像,然后可以将这些图像组合成动画GIF,使用延时摄影功能,可以在几秒钟内查看非常慢的事情。我们需要用到ImageMagick,这是一个用于图像处理的命令行程序。要安装ImageMagick,请在终端窗口中运行以下命令:sudo apt-get updatesudo apt-get install imagemagick -y使用树莓派的延时动画。延...

两万字,清华刘云浩教授回答新生关于AI的90个问题_BigDataDigest的博客-程序员宝宝_刘云浩教授关于人工智能的2000个问题

大数据文摘授权转载自清华招生8月1日,一个好消息备受瞩目:清华大学依托精密仪器系的类脑计算研究中心施路平教授团队开发出全球首款异构融合类脑计算芯片——“天机芯”!该芯片是面向人工通用智能的世界首款异构融合类脑计算芯片。基于此研究成果的论文作为封面文章登上了8月1日《自然》(Nature&nbsp;)。研究团队还展示了由该芯片驱动的“无人驾驶自行车”。与此同时,清华大学软件学院教授刘云浩亲手写下了这...

求生之路怎么显示服务器ip,怎么在求生之路后台查看本机局域网IP_谢中用的博客-程序员宝宝

可以尝试以下方法查看: Windows 2000/XP系统,则要在命令提示符下输入“ipconfig /all”。显示列表中的“Physical Address”就是MAC地址,“IP Address”就是IP地址;要将二者绑定,可以输入“arp -s 你的IP地址 你的MAC地址”,如“ARP -s 192.168.1.5 80-00-0B-B4-36-70”。 详细说明:打开命令行以后. 输放...

随便推点

solrcloud/solr error_luyee2010的博客-程序员宝宝

1,Exception in thread "main" org.apache.solr.common.SolrException: Unknowndocument router '{name=implicit}'

交互设计入门–了解交互设计_load_life的博客-程序员宝宝

为什么会有交互设计,交互设计能够做什么?▎1.成功的互联网产品具备哪些要素?①当你的Boss需要做个产品时,它首先必须是可实现的,这也是为什么核心程序员架构师的待遇普遍较高的原因,因为他们是生产力。那么成功的产品首先要具备–可实现模型。②产品做出来干什么?“方便用户,让用户玩的爽?”当然不是,产品的终极目标是盈利,你的领导也只关心这个。怎么才能盈利,而且是可持续的盈利。这需

python可视化stackplot函数用法-绘制堆积面积图。_海宝7号的博客-程序员宝宝_stackplot

matplotlib.pyplot.stackplot(x, *args, labels=(), colors=None, baseline=’zero’, data=None, **kwargs)堆栈图的思想是随着时间的推移显示“部分到整体”。它用于表示各种数据集而不会彼此重叠。Stackplot用于绘制堆积面积图。它显示完整的数据以进行可视化。它显示了每个零件相互堆叠以及每个零件如何构成完整的图形。它显示数据的各种组成部分,其行为类似于饼图。它具有x-label,y-label和标题,其中各个部分可

Elsa-审批流实现_大熊程序猿的博客-程序员宝宝_elsa flow

一、新建项目:ElsaFlowDemo&lt;Project Sdk="Microsoft.NET.Sdk"&gt; &lt;PropertyGroup&gt; &lt;OutputType&gt;Exe&lt;/OutputType&gt; &lt;TargetFramework&gt;netcoreapp3.1&lt;/TargetFramework&gt; &lt;/PropertyGroup&gt; &lt;ItemGroup&gt; &lt;Proje_1671465600

AOP基于XML配置详解_流年蚁梦的博客-程序员宝宝_aop xml配置

1、切点表达式写法execution([修饰符] 返回值类型 包名.类名.方法名(参数))访问修饰符可以省略返回值类型、包名、方法名可以使用星号(*)代表任意包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类参数列表可以使用两个点..表示任意参数个数及类型的参数示例:execution(* *..*.*(..)) 表示任意返回值类型的任意包及其子包下的任意类的任意参数的任意方法2、(通知/增强)的类型&lt;aop:通知类型 method="切面类中的方法名" po

PADS 复制公版DDR和SOC布线的一种简便方法_h8sir的博客-程序员宝宝

做PCB layout设计时,遇到复杂的电路,一般会参考方案商给的公版设计,特别是有DDR高速信号的走线一般比较复杂,尝试用PADS的reuse功能要求比较严格,需要part type、Decal Type和Value完全一致,网络和元器件比较多, make like reuse很容易报错,最终导致reuse电路失败。现在介绍一种简便的方法:1.首先原理图设计的时候,DDR部分的封装和...

推荐文章

热门文章

相关标签