机器视觉及图像处理系列之一(C++,VS2015)——搭建基本环境

     自《人脸识别》系列发布至今,已一年多矣,期间除答复些许同好者留言外,未再更新文,盖因项目所迫,不得已转战它途,无暇、无料更博耳。其时,虽人已入项目中,然终耿怀于人脸识别方案之谬。初,写此文时,纯粹兴趣使然,未思其它,更有前人博文指引,一路低首猛冲,事成。后,同好者参考此文复盘,不料未达预期者众矣,观文后留言多纠结于此。究其因,方案之缪矣。彼长于分类,亦即如猫、狗、茄子、香蕉、飞机、自行车等物体之检测、分类,短于人脸识别。其实,使之于人脸分类,亦无不可,然问彼汝为何人,则弱矣,其因有四:

1、每添新人,须采集大量图像;

2、每添新人,须重新训练模型;

3、训练数据,须事先清洗,工作浩繁;

4、调参困难、耗时、耗工;

以上种种,皆示彼之不可行。故吾于闲暇时常百度、谷歌之,以求解缪之法,历月余,终成。然事成后,吾觉图像识别应用之广远非人脸识别所能盖之,故吾续进之,有暇时静心研习机器视觉之学,以吾趣为导向,徐徐进之,力避速而不达,以求跬步致远。忽一日,吾心生一念,何不积研习所得成一开源视觉库,既巩固平日所学,又能为他人所用,两全之事,何乐而不为乎?如此,历一年有余,库初成。然令人愧者,其所涵应用者仅数矣,积跬步方至数米耳,盖因吾之识犹远而不足,才所不能也。虽如此,吾亦当续行,累积新知,续增新应用者以实库。吾志所存,以为普通开发者使用之机器视觉工具库,重应用,简使用,繁藏于内而简于外。每念及此,吾长陷于己有所不能而期有同志者同担此任哉,甚矣!如有意者,烦站内短消息与吾,吾与之github开发者权限。如此。

      以上为本系列开篇序文,下转首篇。

      机器视觉及图像处理库(以下简称工具库)基于VS2015开发,开发语言为C++,用到的图像处理库为OpenCV3.4(以下简称OCV3),深度学习网络为caffe和DLib。这几个第三方的支持库都需要自行编译以支持VS2015。网上有大把的资料介绍如何用CMake构建支持VS2015的工程,以实现VS2015下的源码编译,本文就不再重复此类工作了。这里需要特别说明的是OCV3我们需要opencv contrib模块,所以编译OCV3时记得要把这个模块加上。另外,如果你的机器支持GPU,请一定编译成GPU版本,如果不支持也没事,工具库支持源码级的CPU和GPU切换,使用时你只须根据现场环境定制编译就行了。

      除了以上三个库,我们还用到了libvlc和libfacedetection库,前者是著名的开源视频播放器VLC media player,我们要用它播放RTSP视频流。OCV自带的ffmpeg播放器对RTSP流的支持很不好,掉帧、卡顿现象很严重,即使最新的OCV3.4.2也没有解决这个问题(估计OCV还是要看ffmpeg团队的心情才能彻底解决这个问题,毕竟两个不是一家)。后者则是Shiqi.Yu老师开发的不依赖于神经网络的人脸检测库libfacedetection,这个库可以用caffe网络及DLib代替,可用可不用,速度上并没有像传说中的比caffe网络快(这个结论依据的是我通过公开、合法渠道获得的版本与caffe网络对比得出的,如有异议请告之,我们可以再次评测)。但是,由于历史原因,工具库在最初开发人脸检测模块时用到了libfacedetection,后来虽然在实际应用中废弃不用,但相关函数还是存在的,因此,要么你在使用工具库时去掉相关函数再编译,要么把这个库引入到VS2015中。

      当然,以我的风格,我是不会挖个大坑给诸君跳的(顺便鄙视某些博主,写东西藏着掖着,要么代码给不全,要么说话说半句,要么照着博文做下来,错误一堆,差评),开发环境需要的这些第三方库(编译好的),包括后续开发中用到的预训练模型,请在我的百度云盘获取:

链接:https://pan.baidu.com/s/1B15sSHizPUA1C-aZ0Fvn2g 密码:65hk

云盘上有三个文件夹,它们分别是:

预训练模型 - 保存了工具库中使用的所有预训练模型,必须下载,后面会陆续用得上;

        CPU - CPU版本的第三方库;

        GPU - GPU版本的第三方库(cuda版本:v8.0.60, cudnn版本:v5.1,支持系统均为win10 x64,显卡为GeForce GTX 1050 Ti);

需要特别说明的是,GPU版本的第三方库可能存在兼容性问题,如果你的机器上安装的并不是8.0版本的cuda(特别是低版本的cuda),那么建议不要使用我提供的库,还是自行编译OCV3、caffe和DLib为上。当然,不死心的话可以先试试再说,说不定能用呢。

      从云盘下载后请解压到C盘,解压时注意鼠标右键菜单点选“解压到当前文件夹”,解压后的路径为“C:\MVLThirdPartyLib”,其下就是各个第三方库的相关文件夹。如果你不想这样组织,可以按照自己的爱好重新调整。不过你从github上clone下来的VS2015工程就无法直接编译通过了,需要你修改工程配置到调整后的路径下。相信我,这会很麻烦,还是保持原样更好。接着从github上clone工程,项目地址:

https://github.com/Neo-T/MachineVisionLib

控制台输入clone指令:

git clone https://github.com/Neo-T/MachineVisionLib.git

稍等片刻,整个工程即可clone到你的机器上。关于git安装使用的问题,请找度娘或谷歌,资料多了去了,这里就不占篇幅了。clone下来的工程组织如下:

双击MachineVisionLib.sln,打开该工程。注意,该操作的前提是你的机器上已经成功安装VS2015了,否则,先安装再双击。

打开后的工程如下图所示:

截止到本文撰写完毕时共有6个项目工程,后续我会继续增加,所以当你clone下来的工程比这还多时不要奇怪:

                         common_lib - DLL工程,与OS及非图像处理相关的操作函数均由其提供,如建立共享内存、建立临界区、起停进程等;

                      MachineVisionLib - DLL工程,机器视觉库,核心工程,所有与机器视觉 、图像处理相关的函数均由其提供,实际应用均围绕该库展开;

                          WhoYouAre - 应用工程,实现人脸识别应用,该工程实现人脸注册、人脸识别两大主要业务功能;

                  WhoYouAreByVideo - 应用工程,实时视频流级别的人脸识别应用,解决WhoYouAre应用在实时视频流识别时的卡顿、掉帧问题;

                                ImageMagic - 应用工程,实现比较冷门的图像处理应用,如映射变换、背景分离、背景色变换、提高图像清晰度、去除马赛克等;

ConveyorBeltTearingDetector - 应用工程,分析单张皮带图片找出存在的裂缝并标记;

ImageMagic工程目前只完成了映射变换,其余的功能正在编码实现中,特别是去除马赛克功能,我计划用GAN来实现,这个会在讲解ImageMagic工程时再详细描述。对于MachineVisionLibcommon_lib两个工程,我不会单独进行讲解,我会结合具体的应用工程来讲解,应用涉及哪些函数就讲那些函数,包括设计思想和使用方式都会给出详尽描述。

到这里,心急的同学可以试着编译一下了,编译之前需要再做一项工作,就是在工程的编译输出路径建一个文件夹“bin”,VS生成的DLL和可执行文件会在编译完成后被复制到这个文件夹下,这样方便测试,具体的建立位置如下:

在工程主文件夹“x64”下建立,即最终结果应为“x64\bin”。

      如果你前面的操作是严格按照上述步骤依次进行的,那么理论上,你应该能够编译通过。如果你很不幸没有编译通过,那么你需要回头仔细检查看看是否遗漏了什么。通常编译不通过时请仔细阅读VS2015给出的错误信息,看是否是因为第三方库的路径设置问题导致的。

      OCV3、caffe、DLib以及libvlc、libfacedetection几个库在VS2015中的配置很简单,只需4步:

1、配置相关头文件所在的路径;

2、配置相关LIB库文件所在的路径;

3、添加几个预处理器定义;

4、指定工程要使用的LIB库具体名称;

针对不同的设计目标,这几个工程每一步的配置内容均有些许不同,以核心工程MachineVisionLib为例,鼠标右键点选MachineVisionLib工程“属性”,在弹出的属性窗口选择左侧的“VC++目录”,然后在右侧窗口设置头文件和LIB库文件所在的路径:

其中,“包含目录”设定第三方库头文件的所在位置,其值如下:

$(SolutionDir)common_lib
C:\MVLThirdPartyLib\dlib-19.10
C:\MVLThirdPartyLib\libfacedetection\include
C:\MVLThirdPartyLib\opencv\build\include\opencv2
C:\MVLThirdPartyLib\opencv\build\include\opencv
C:\MVLThirdPartyLib\opencv\build\include
C:\MVLThirdPartyLib\.caffe\dependencies\libraries_v140_x64_py27_1.1.0\libraries\include
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include
C:\MVLThirdPartyLib\caffe\build\include
C:\MVLThirdPartyLib\vlc\sdk\include
C:\MVLThirdPartyLib\vlc\sdk\include\vlc\plugins

点击输入框的下选单按钮,选择“编辑”,然后将上述值逐一输入进去即可。其中第一项包含的“$(SolutionDir)”为VS2015支持的一个预处理宏,其指代VS解决方案所在的绝对路径,这个宏由VS自行处理转换,我们只需知道它的含义及使用方式就行了。另外,如果你的机器不支持GPU,则无需添加“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include”。当然,如果上述值的路径你自行做了调整,那么就需要你根据实际情况逐一修改了,没做调整的,clone的工程都已经配置好了,就不用再管了,只需了解怎么回事就可以了。

      “库目录”设定第三方库LIB文件的所在位置,其值如下:

$(SolutionDir)$(Platform)\$(Configuration)
C:\MVLThirdPartyLib\libfacedetection\lib
C:\MVLThirdPartyLib\dlib-19.10\build\x64\bin
C:\MVLThirdPartyLib\opencv\build\x64\vc14\lib
C:\MVLThirdPartyLib\.caffe\dependencies\libraries_v140_x64_py27_1.1.0\libraries\lib
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64
C:\MVLThirdPartyLib\.caffe\dependencies\libraries_v140_x64_py27_1.1.0\libraries\x64\vc14\lib
C:\MVLThirdPartyLib\caffe\build\lib
C:\MVLThirdPartyLib\vlc\sdk\lib

“包含目录”的操作完全相同,不再赘言。

      关于预处理的定义,依然是在属性窗口,鼠标左键点选左侧的“C/C++”->“预处理器”,然后在右侧的“预处理器定义”一栏添加如下值:

GLOG_NO_ABBREVIATED_SEVERITIES
CPU_ONLY
NO_STRICT
DLIB_HAVE_SSE2
DLIB_DISABLE_ASSERTS
DLIB_JPEG_SUPPORT
DLIB_PNG_SUPPORT
DLIB_HAVE_AVX

其中,如果你的机器支持GPU,则把CPU_ONLY去掉,同时修改工程文件MachineVisionLib.h,找到NEED_GPU宏,将其值置1即可启用GPU模式。

      最后就是指定具体使用的LIB库名称了,还是在属性窗口,鼠标左键点选左侧的“链接器”->“输入”,然后在右侧的“附加依赖项”添加如下值:

common_lib.lib
opencv_world341.lib
caffe.lib
caffeproto.lib
caffehdf5.lib
caffehdf5_hl.lib
gflags.lib
glog.lib
leveldb.lib
libprotobuf.lib
libopenblas.dll.a
lmdb.lib
compute_image_mean.lib
convert_imageset.lib
libfacedetect-x64.lib
dlib19.10.0_64bit_msvc1900.lib
boost_thread-vc140-mt-1_61.lib

至此,库支持相关的基本配置已完成。同一解决方案下的应用工程要想使用common_libMachineVisionLib两个动态库工程提供的相关操作函数,我们只需把这两个工程的头文件、LIB库文件的路径以及LIB文件配置上就可以了:

其中,库目录使用了VS 的预处理宏,其指代了该解决方案的编译输出路径,这个路径下正好包含两个核心DLL工程编译后的LIB文件。说到这里,聪明的同学应该能意识到,其它依赖这两个核心DLL的应用工程必须等它们生成LIB后才能进行编译、链接,否则会报找不到相关LIB文件的错误。因此,我们还需要配置项目依赖项,我们的依赖顺序为:MachineVisionLib依赖common_lib,其它几个应用工程依赖MachineVisionLib,而common_lib没有任何依赖。设置项目依赖项请鼠标右键点选VS主界面左侧顶部的“解决方案‘MachineVisionLib’”,然后在弹出的右键菜单中选择“项目依赖项”,在弹出的界面中按照上述顺序逐一设置即可,参考设置界面如下:

到这里,配置工作还差最后一小步,设置“后期生成事件” ,让VS在编译完成后将结果文件复制到前面已经建好的指定文件夹“x64\bin”下。此项工作,解决方案下的所有工程都需要设置。具体操作依然是在工程“属性”页面,鼠标左键点击左侧的“生成事件”->“后期生成事件”,然后在右侧“命令行”一栏输入以下内容:

copy $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName).dll $(SolutionDir)$(Platform)\bin\$(ProjectName).dll

需要注意的是,红色“dll”   部分需要根据具体工程类型调整,应用工程要改为“exe”。除了这个地方,其它都不要动,原样复制即可,设置结果如下图所示:

 

      耐心看到这里,还未进行编译的同学,现在可以试着编译了,顺利的话,不应该出什么幺蛾子了,除非你前面漏了什么。不过话说回来,能耐着性子,不嫌我啰嗦看到这里的,绝不是一般人,肯定都能顺利通过。编译完成,要想让程序能够正常运行,还得配置系统环境变量,将第三方库提供的dll文件路径添加到系统“PATH”中:

其值如下:

C:\MVLThirdPartyLib\opencv\build\x64\vc14\bin

C:\MVLThirdPartyLib\libfacedetection\bin

C:\MVLThirdPartyLib\caffe\build\bin

C:\MVLThirdPartyLib\vlc

(注意,DLib是静态库形式提供,所以PATH中不需要添加它的BIN路径)

配置完毕,可以到工程目录的"x64\bin" 下,双击“ImageMagic.exe”,如果程序顺利打开则意味着配置成功。有兴趣的同学可以研究一下这个程序的功能,在打开的窗口中点击“打开”,然后找到工程输出目录“x64\bin\TEST-PICS”下的“5yuan.jpg”文件打开,然后选择“编辑”->“透视变换”,此时,程序会弹出图片编辑界面:

同时还有一个控制台的帮助界面弹出:

你可以根据帮助试着操作一下,比如我只是想把这个5元“大票”调正,那么你只需顺时针选好4个点:

程序会立即弹出结果图:

按键盘“Q”或“Esc”键结束操作,程序主界面即是最终的结果图,此时我们选择保存就能得到调整后的图片文件了。如果这一切都很顺利,说明你已经成功获取完整的、可以使用的0.001版本的机器视觉库了。接下来我会开始讲解WhoYouAre工程,详细描述如何实现不用训练人脸模型的人脸识别。

附注如果你不是从我的云盘获取的libvlc(我提供的是libvlc3.0.3)而是从官网下载的最新版本,那么VS2015编译MachineVisionLib时会报如下错误:

1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(368): error C2065: “libvlc_media_read_cb”: 未声明的标识符
1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(368): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(368): error C2513: “int”: 在“=”前没有声明变量
1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(368): error C2143: 语法错误: 缺少“;”(在“(”的前面)
1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(368): error C2062: 意外的类型“void”
1>C:\MVLThirdPartyLib\vlc\sdk\include\vlc/libvlc_media.h(478): error C2061: 语法错误: 标识符“libvlc_media_read_cb”

其实这是缺少ssizet_t的定义导致的,我们只需打开vlc.h文件(“C:\MVLThirdPartyLib\vlc\sdk\include\vlc\vlc.h”)在头部添加针对ssize_t的定义即可:

 

最后,特别声明:视觉库工程一直处于持续开发中,感兴趣的同学可以隔几天"git pull"一次,说不定有你想要的东西……

posted @ 2018-09-06 22:30  Neo-T  阅读(8912)  评论(7编辑  收藏  举报