OpenCV编程样式指南

更新时间:2023-05-11 22:41:38 阅读: 评论:0

[编辑][编辑][编辑]OpenCV 编码样式指南
目录
[隐藏]1前言2文件命名3文件结构4命名约定5函数接口设计6函数实现7代码布局8移植性9函数文档编写10函数测试实现11提示12附录12.1附录A: 参考12.2附录B: 规则简述列表12.3附录C: 附加说明前言
  本文档是对OpenCV 中代码风格的简短说明,因为OpenCV 的核心库
(cv,cvaux )是用C 和C++编写的,所以本文档仅对用C 和C++代码的编写有效。文件命名
  所有cv 和cvaux 库文件的命名必须服从于以下规则:
1.所有的CV 库文件名前缀为cv
2.混合的C/C++接口头文件扩展名为 .h
3.纯C++接口头文件扩展名为 .hpp
4.实现文件扩展名为 .cpp
5.为了与POSIX 兼容,文件名都以小写字符组成文件结构
  每个文件以BSD 兼容的许可声明(模板在Contributors_BSD_Licn.htm 文件中可以找到)开头;其它头文件和实现文件的规则包括:
1.一行最多90个字符,不包括行结束符
2.不使用制表符
[编辑][编辑]3.缩进为4个空格符,所以制表符应该用1-4个空格替换(依据开始列确定)
  头文件必须使用保护宏,防止文件被重复包含。混合C/C++接口头文件用extern “C” { } 包含C 语言定义。为了使预编译头机制在Visual C++中工作正常,源文件必须在其它头文件前包含precomp.h 头文件。   同时,请参见头文件和实现文件的示例。命名约定
  OpenCV 中使用大小写混合样式来标识外部函数、数据类型和类方法。宏全部使用大写字符,词间用下划线分隔。
所有的外部或内部名称,若在多个文件中可见,则必须含有前缀:
1.外部函数使用前缀cv
2.内部函数使用前缀Icv
3.数据结构(C 结构体、枚举、联合体、类)使用前缀Cv
4.外部或某些内部宏使用前缀CV_
5.内部宏使用前缀ICV_函数接口设计
  为了保持库的一致性,以如下方式设计接口非常重要。函数接口元素包括:1.功能
2.名称
3.返回值
4.参数类型
5.参数顺序
6.参数默认值
  函数功能必须定义良好并保持精简。函数应该容易镶入到使用其它OpenCV 和IPL 函数的不同处理过程。函数名称应该简单并能体现函数的功能。以下是OpenCV 中的一些基本命名模式:
1.大多数函数名形式:cv<ActionName>
  返回值应该选择能简化功能的用法。通常一个函数创建一个对象并返回该对象。对于函数,处理动态数据结构或标量,这是一个好的方法。然而在图片处理函数中会经常分配和回收大内存块,所以图片处理函数不能创建和返回图像结果而是修改输出一个作为参数传入的图像。
  函数不应该用关于严重错误(例如空指针,0除数,错误参数范围,不支持的图像格式等)的信号作为返回值。在这种情况下,可以用一种类似于IPL 中特殊的错误处理机制。相反,使用期望的运行时情况信号作为返回值比较好。(例如,跟踪图像移动到屏幕外)。
  参数类型选择已经存在于OpenCV 中的类型更适宜:IplImage 用于光栅图
像,CvMat 用于矩阵,CvSeq 用于轮廓线等。建议不使用简单指针和计数,因为有许多函数参数,它降低了库接口并使程序更难读。
  一个一致的参数顺序很重要,因为它使参数易于记住顺序并且帮助程序员避免错误和使用错误的参数顺序联接函数。
1.对于简单过程函数(在命名模式列表中的第一种和第二种类型)典型的顺序是:输入参数,输出参数,标记或可选参数。
[编辑]2.对于容器元素方法,顺序是:容器,元素位置,标记或可选参数。
  输入参数经常用const 修饰符。可选参数经常简化函数用法。因为C++允许在参数列表后跟随可选参数,它也可能影响决定以参数顺序,最重要的是标记位于最前,次重要的随后。在函数声明中用CV_DEFAULT 宏指定可选参数的默认值.它使声明与C 相兼容。
  示例函数声明请参见cvexample.h 和cv.h 、cvaux.h.函数实现
  本节主要关注以下几点:
1.参数类型检查
2.错误产生和处理
3.内存管理和资源回收
4.调用低级函数
  如前面所说,OpenCV 函数广泛使用高级数据类型传送和返回参数。它简化了函数的使用,但是增加了使用错误的参数组合调用函数的可能性(例如浮点图像代替位图,或两个不同大小的图像)。检查标准类型参数存在标准的方法。
  IplImage 图像能通过CV_CHECK_IMAGE 宏被检查。该宏检查传给IplImage 的指针和潜在的图像数据指针不为空,图像有像素顺序,没有ROI 掩码或冗馀信息。  CV_CHECK_MASK_IMAGE 用于检查掩码图像,二值图和灰度图。除了CV_CHECK_IMAGE 检查的条件外,它还能确保图像有8位深度和单通道。并且,所有的输入和输出图像在进行深度\通道数和尺寸组合前应该被检查。随后,应该在调用cvGetImageRawData 函数返回的图像ROI 尺寸后应该被检查。输入等高线和其它动态数据结构能够用CV_IS_CONTOUR 和相关的宏进行检查。
  任何时候,当传入一个错误的参数或在函数执行时发生其它严重错误时,应该通过cvError 函数抛出一个错误. OpenCV 中与几乎所有标准的低级C 库的IPL 类似,有一个错误处理机制.那就是存在一个全局错误状态代替返回错误码:可以通过以下实现:1.使用cvError 函数设置
2.使用cvClearErrStatus 清除
3.使用cvGetErrorStatus 读取
  除了设置错误状态和指定值外,cvError 还能进行额外的操作,依据错误处理模式而不同,错误处理模式可以通过cvSetErrorMode 调整.在silent 模式或parent 模式下cvError 立即返回.在子模式下,它打印出错误消息并终止应用程序。
  为了更方便使用. 可以通过使用如下宏来代替以上函数:
1.CV_ERROR 和 OPENCV_ERROR 代替cvError
2.CV_CALL 和OPENCV_CALL 代替调用函数和检查状态
  CV_*宏需要在函数中定义”FuncName”字符串变量和”exit”标签,OPENCV_*宏则不需要。
在OpenCV 中临时缓存用cvAlloc 和cvFree 函数分配和回收.函数应注意适当对齐,对未释放的内存保持跟踪,检查溢出。
  当程序运行出内存泛围时,cvAlloc 抛出一个错误.函数能够调用能由用户赋予完全控制内存分配的低级函数.因此强烈建议使用这些函数.以上描述仅对简单缓存有效.临时图像,内存存储和其它结构使用cvCreate<Object>和cvRelea<Object>的方式分配和回收.
  如果错误发生,并且CV_ERROR 或CV_CALL 宏被调用,控制转到exit 标签处.同在在程序流中可以通过EXIT 宏跳转控制.标签可以通过手动或__BEGIN__和宏被定义.
[编辑][编辑][编辑]
此标签引入是为了资源回收.尽管执行分支,当程序流进行时,还是经常发生内存泄漏.这种情况通常发生在分支语句中使用返回语句.
  使用库中的技术,可以帮助程序员避免大多数内存泄漏.在函数开始所有的指针被清除(通常在初始化中).在”exit”标签后,对每个指针调用cvFree 函数.cvFree 函数可以安全处理空指针.在函数内部,返回语句用EXIT 宏代替.这样,我们可以确保内存的回收.当然,我们可能忘记对某些块调用cvFree 函数,函数执行时,仅仅只是内存泄漏发发生,并且易于捕捉.
  OpenCV 中的低级函数象IPP 中那样主要是是C 语言实现原始操作的.它们不同于前面讨论的接口级高级函数(他们使用简单的指针和数值,几乎不用结构体)和错误处理方法(它们返回错误代码而不是全局错误状态).方便并安全的调用这些函数的方法是使用IPPI_CALL 宏.
  函数实现示例请参见cvexample.cpp 文件。代码布局
在OpenCV 中有一个单独的字符串规则:每个文件必须使用一致格式样式。当前使用在OpenCV 中,并推荐使用的样式如下:if( a > 5 ) { int b = a*a; c = c > b ? c : b + 1; } el if( abs(a) < 5 ) { c--; } el {
printf( "a=%d is far to negative\n", a ); }在符合以上样式的前提下其它样式也可能接受。也就是说,如果一个人修改别人的代码,他应该使用相同的代码样式。移植性
所要代码必须符合以下标准:
1.ANSI C 第一个语言标准ISO/IEC 9899:1990
2.C9X (1999年修订的新标准) – ISO/IEC 9899.
3.C++ 标准 – ISO/IEC 14882-1998.
你应该去除编译器依赖或平台依赖和系统调用,例如:
1.编译器: pragma's
2.特定关键字: __stdcall, __inline, __int64(or long long).使用CV_INLINE,CV_STDCALL, int64分别代替。
3.编译器扩展,例如?<;和<?宏表示最小和最大,重载宏等。
4.内联汇编
5.Unix 或Win32调用,如:bcopy, readdir, CreateFile,WaitForSingleObject 等。
6.用sizeof 代替具体的数据大小(如sizeof(int)而不是4),字节顺序(*(int*)"\x1\x2\x3\x4"是0x01020304或0x04030201或什么?),用简单的字符有符号字符或无符号字符处理数据(不是字符串)。使用短形
式,uchar 表示unsigned char 和schar 表示signed char 。使用预处理指令包含非可移植性代码片段。不要试途使用标准元素,主要编译器制造商几乎不支持这些。
[编辑]函数文档编写
文档以HTML 格式提供,因为HTML 格式提供文本格式化功能和超级链接,同时它非常简单,易用和易于维护。每个函数的文档或相关函数组的文档放入不同文件中,该文可以从主页链接到。  这是一个包含链接到函数示例文档的主页原型,实现在cvexample.cpp 中。看一下这些页面和相应的HTML 代码,包括详细的格式化注释。你对拷贝函数文档HTML,适当的更改和加入一个链接到索引页中。  函数文档HTML 文件包知以下基本元素(以如下顺序):
1.页面标题——显示在浏览器标题栏中并且表示一个扩展的函数名或函数组名。
2.关键字列表——用于搜索引擎和各种工具检索文档。
3.可见的页面标题——简单的重复页面标题。
4.函数名——真实的函数名,但是不包括前缀。它应该标签化以便从文档的其它位置引用它。
5.Blurb——单行函数描述。
6.函数声明——按它在头文件中的形式,用<pre >和</pre >包围。除了OPENCVAPI 被忽略外,默认参数的普通C++语法用CV_DEFAULT 宏代替。
7.函数参数描述——一个<;参数名,描述>对的列表。
8.讨论——描述函数功能的节。允许或支持的参数组合的限制,算法参考(链接或标题)。
9.使用示例——一个可选的代码片断或伪代码段.几个相关函数可以共享相同示例.10.请参见——包含零个或多个相关函数链接。函数测试实现
  每个测试实现为从文本文件输入和输出结果到另外一个文本文件的C/C++函数。这样,函数就有如下接口:bool <TestName>( const char* inputfile,const char* output file );  输入输出文件的格式没有定义。然而,如果测试系统函数用于从文件中读取或写入高级数据(矩阵,文件名,轮廓等),那么文件的格式应与函数兼容。  外部或主测试函数执行所有或选择的测试并且与标准结果相比较,它可以由其它程序或以前执行的相同测试创建。
使用这种设计可以实现检查在一个函数上检查几个特殊的数据集和测式比较函数在武断的数据上的输出和标准输出。在这种情况下输出文件能以不同的两个输出和从前面段的标准结果将全部是零。
  测试系统API 使测试更容易,它包括:
1.系统测试内核(测试注册,文件管理,用异常处理能力控制测试)
2.从文本文件取得矩阵、文件名和其它数据和写入数据到文本文件的函数。
3.检查数组中的特殊值。
4.内存管理函数帮助捕捉内存泄漏和缓冲区越界。
5.随机数据生成。
6.简单算法函数(矩阵操作)
7.可视化函数
8.很多功能实现在OpenCV 和HighGUI API 上的瘦层.
  以下是一步一步描述怎样实现测试的示例://创建一个测试体文件: // //skeleton_test.cpp // #include "opencv_tst.h" // 测试函数 bool test_skeleton( const char* input, const char* output ) { // 从

本文发布于:2023-05-11 22:41:38,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/885176.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   使用   参数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图