东寻

导航

分析一套源代码的代码规范和风格并讨论如何改进优化代码

OpenCV源码规范与风格分析

项目方向是基于计算机视觉的行人检测,

所以从github上找了OpenCV的源码,对OpenCV源码进行讨论分析,

源码不仅遵循了语言规范,同时做了许多变通,可读性很好;

 

因为选题是计算机视觉相关,同时又是实时性应用,对处理速度要求较高,所以直接选择OpenCV的源码进行分析;

OpenCV主要是由C函数实现,同时包含有少量的C++类构成,源码目录结构如下:

源代码目录下包含9个子文件夹、5个文件;

子文件夹:3rdparty

  包含第三方的库,比如视频解码用的 ffmpeg,jpg、png、tiff等图片的开源解码库。

子文件夹:apps

  包含进行 haar 分类器训练的工具,opencv 进行人脸检测便是基于 haar 分类器。

子文件夹:cmake

  包含生成工程项目时 cmake 的依赖文件,用于智能搜索第三方库,普通开发者不需要关心这个文件夹的内容。

子文件夹:data

  包含 opencv 库以及范例中用到的资源文件,haar 物体检测的分类器位于haarcascades子文件中。

子文件夹:doc

  包含生成文档所需的源文件以及辅助脚本。

子文件夹:include

  包含入口头文件。opencv 子文件夹中是 C 语言风格的API,也就是《Learning OpenCV (第一版)》中描述的API函数,官方将逐渐淘汰 C 风格函数,因此不推荐使用该文件夹中的头文件。

  opencv2 子文件中只有一个 opencv.hpp 文件,这是 cv2 以及 cv3 推荐使用的头文件。

子文件夹:modules

  包含核心代码,opencv 真正的代码都在这个文件夹中。

  opencv 从2.0开始以模块的方式组织各种功能,近两年模块的数量增长得很快。

子文件夹:platforms

  包含交叉编译所需的工具链以及额外的代码,交叉编译指的是在一个操作系统中编译供另一个系统使用的文件。

子文件夹:samples

  范例文件夹,用于了解学习模块的使用。

.editorconfig文件

   EditorConfig官网是这么介绍的:

  “EditorConfig帮助开发人员在不同的编辑器和IDE之间定义和维护一致的编码样式。

   EditorConfig项目由用于定义编码样式的文件格式和一组文本编辑器插件组成,这些插件使编辑器能够读取文件格式并遵循  定义的样式。

   EditorConfig文件易于阅读,并且与版本控制系统配合使用。”

   OpenCV的.editorconfig文件内容如下:

CMakeLists.txt文件

  CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。 通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程。

CONTRIBUTING.md

  全方位指导你如何参与贡献代码,如何进行本地开发,如何提ISSUE,如何提PR等等,参与开源项目前必看的文档。

 LICENSE

  使用协议和服务条款。

README.md

  开源项目的门面,让用户第一时间了解该项目具体是做什么的,一份好的README文件应包含但不仅限于项目标题、描述、主要内容、如何安装、如何使用、API文档、如何参与贡献、版权类型等等内容。 

  

OpenCV的项目核心代码在modules文件夹下

 

 

 

有关行人检测的源码在modules的objdetect模块中,

objdetect的src/opencl文件夹下包含了源码,主要函数在hog.cpp中;

 

类名/函数名/变量名等命名遵循驼峰命名法

  类名采用大驼峰命名法,变量名采用小驼峰命名法;

 

C++接口头文件是.hpp文件,

实现文件是.cpp文件,

实现文件放在modules/<module_name>/src,头文件放置modules/<module_name>/include/opencv2/<module_name>/

C++的样例代码写在opencv/samples/cpp中,

文档写在opencv/modules/<module_name>/doc,该文档以图片简介了图像的边缘特征、线性特征与中心环绕特征,

测试文件放在opencv/modules/<module_name>/test,

 

代码规范和风格细节:

友元重载,IO操作单行紧跟assert宏保护程序,

 

单行if-else无括号代码简洁,

单行if-elseif加括号代码清晰,

短函数单行实现,严格const保护权限,

合理擅用三元运算符,且不单行实现(代码清晰),

三元运算符侧重两者选择性,而if-else更侧重多重判断,

合理使用三元运算符比if-else更具有逻辑性,

指针定义*靠近变量名,

合理使用&传参节省资源,一行代码长度合理(代码转行严格到单位字符位),

命名空间调用清晰,没有直接using,

第1688行的case使用了{ },相比其他case明显不协调,

但1690行出现了局部对象,用意在缩短v的生命期,

虽然v的生命期本来就很短,但这里仍然做了优化,

生僻用法合理注释,

 

OpenCV的代码已进行了规范,且一直以来更新维护的也很好,许多细节就不再列举;

源码满足简洁清晰无歧义的要求,也做了很多优化;

项目的目的也就是对比OpenCV的源码实现,进行新算法的优化与实现;

 

同类编程语言或项目在代码规范和风格的一般要求:

  OpenCV使用了C语言和C++混编,代码风格兼具了C和C++的特点。语言本身有自身的要求与规范,比如C++代码限制很宽松,而Python严格控制缩进。这是与语言本身的特性相关的,Python因为简练明了,很多东西都打包了相对比较黑盒,所以很需要代码规范,而C与C++语言相对底层,粒度更细灵活度更大,所以代码格式降低了限制,如果Python没有缩进限制,Python会变得很模糊混乱,如果C++有了缩进限制,那么写一些底层复杂的东西就会很痛苦。

  就OpenCV的开源项目而言,一方面她尽量遵循了C与C++的语言规范,同时又进行了许多变通,使得代码更适宜阅读这也代表了C和C++一类混编开源项目的规范,这种规范使得这些开源代码具有很好的可读性。

posted on 2019-10-13 17:35  东寻  阅读(406)  评论(0编辑  收藏  举报