• OpenCV 代码规范


    这份文档主要针对C++代码。

     

    目录和文件

    所有的代码必须写在一个或多个.cpp.hpp文件中,并放入适当的OpenCV模块目录,如果提交的代码很多,或当前没有适当的模块,可以新建一个模块。

    所有文件名小写。

    l  C++接口头文件应该是.hpp的。

    l  实现文件应该是.cpp的。

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

    l  C++的样例代码写在opencv/samples/cpp,Python代码写在opencv/samples/python2

    l  文档写在opencv/modules/<module_name>/doc

    l  测试文件放在opencv/modules/<module_name>/testml模块的测试数据放在opencv_extra/testdata/ml

    文件结构

    l  所有的代码放在namespace cv,或者,嵌套的namespace,例如cv::vslam

    l  一行代码不应太长,最好限制在100字符内。

    l  不要使用tab,用空格代替。

    l  只能使用英文文本,不要使用其他语言的文本在任何地方。(注,汉语不要使用拼音格式)

    l  缩进4字符。

    l  头文件必须使用宏进行控制,如下

     

        #ifndef _OPENCV_your_header_name_HPP_

        #define _OPENCV_your_header_name_HPP_

        #ifdef __cplusplus

        namespace cv { namespace mynamespace { ...}}

        #endif

        #endif

     

     

    l  源文件必须包含precomp.hpp头文件。

    命名惯例

    l  OpenCV中的函数,自定义类型,类函数使用大小写混合的表示符。

    l  类名以大写字母开头

    l  函数和方法名以小写字母开头,除非是以算法作者命名的函数,例如cv::Sobel()

    l  宏和枚举全部大写,以下划线分割。

    l  所有的函数和类必须用CV_EXPORTS,否则在windows上会有链接错误,如果函数或类有PythonJava的接口,则要用CV_EXPORTS_W代替CV_EXPORTS

    l  函数,函数被定义良好,没有多余内容。

    命名

    函数名应该反映函数目的,大多数函数有这样的格式:<actionName><Object><Modifiers>,例如:calibrateCamera,calcOpticalFlowPyrLK,或者是算法名或函数的返回值得名,例如Sobel,CannyRodirgues,sqrt,goodFeaturesToTrack.

    返回值

    函数最好返回标量类型,为了减少内存的分配释放,最好将返回的图像用引用形式传入,函数内修改后作为一个输出参数返回。不要因为空指针,除0这样的错误而返回值,应该使用cv::Exception抛出一个异常。

    参数类型

    最好使用OpenCV中已经存在的类型,Mat代表图像或矩阵,vector<Mat>代表一组图像,vector<Point>,vector<Point2f>,vector<Point3f>,vector<KeyPoint>代表点集,连通域,或一组关键点。Scalar代表14个元素的数值元组。最好不要使用指针,可以考虑用Ptr<>代替。

    参数顺序:<input parameters>,<output parameters> <flags & optional parameters>

    入参添加const,大的数据类型通常使用引用传递,原类型和小的结构(intdoublePointRect。。。)可以传值。

     

    高级C++接口,Algorithms

    Algorithm的设计规范

    l  我们希望当算法实现改变的时候接口依然保持稳定。

    l  我们希望不但要保持源文件级别的兼容性,也要保持二进制级别的兼容性。

    l  我们希望保持头文件的整洁,并且容易跟踪接口的变化。

    l  我们希望我们的工具解析OpenCV的头文件是简单和鲁棒的。

    l  我们希望构建OpenCV能够很快。

    为了达到以上目的,我们物理的将C++类的接口和实现分开。

    我们只暴露类的接口,没有类的构造函数,没有成员数据,只有虚函数。真正的实现方式是用类去继承接口。类的构造方式是统过暴露一个函数,这个函数返回一个指向接口的智能指针。

    一步步写自己的类

    1.  继承Algorithm类或它的子类,作为抽象基类。

    ... namespace cv { namespace mynamespace {

    class MyStereoMatcher :public StereoMatcher {

    public: virtual voidsetLambda(double lambda) = 0;

    virtual double getLambda()const = 0;

    ...

    };

    }}

    2.  写一个构造函数返回抽象基类的智能指针。

    CV_EXPORTS Ptr<MyStereoMatcher>createMyStereoMatcher(<params...>);

    3..cpp文件中实现你的接口和构造函数。

    /* <OpenCV license with your copyright added> */ #include"precomp.hpp"

    namespace cv { namespace mynamespace {

    class MyStereoMatcherImpl : MyStereoMatcher {

    MyStereoMatcherImpl(...) { ... }

    virtual ~MyStereoMatcherImpl() { ... }

    ...

    double getLambda() const { return lambda; } // implement gettersand setters

    void setLambda(double l) const { CV_Assert(l >= 0); lambda =l;}

    void compute(InputArray _left, InputArray _right, OutputArray_disp) // implement necessary methods from StereoMatcher, Algorithm etc.

    {

     Mat left =_left.getMat(), right = _right.getMat(); _disp.create(left.size(), CV_16S);

    Mat disp = _disp.getMat(); ...

    }

    ... double lambda;

    };

    Ptr<MyStereoMatcher> createMyStereoMatcher(<args>) {return new MyStereoMatcherImpl(<args>); } }}

     

    扩展修改算法

    代码格式

    1 if( a > 5 )

    2 {

    3 int b = a*a;

    4 c = c > b ? c : b + 1;

    5 }

    6 else if( abs(a) < 5 )

    7 {

    8 c--;

    9 }

    10 else

    11 {

    12 printf( "a=%d is farto negative ", a );

    13 }

    可移植性,扩展的依赖性

    l  代码使用C++98标准,不建议使用C++11TR1扩展。

    l  避免使用依赖编译器或平台的指令,例如

    l  编译器的pragma

    l  特定的关键字,例如__stdcall, __inline,__int64( long long),使用CV_INLINE,CV_STDCALL,int64代替

    l  编译器扩展,一些宏像minmax

    l  内嵌汇编

    l  UnixWin32的特定调用,像, bcopy, readdir, CreateFile, WaitForSingleObject()

    l  sizeof(int)代替4

    写函数文档

    ReStructured Text编写文档

    每个函数应该包括如下内容:

    l  C/C++的函数声明

    l  简短的描述

    l  解释所有的参数

    l  用一个简短的例子详细描述函数使用

    实现测试代码

    OpenCV使用GoogleTest框架。

    所有的源文件都要保护precomp.hpp文件

    所有的测试代码都在cvtest命名空间内。

    照一下样式声明测试代码

    TEST(<module_name>_<tested_class_or_function>,<test_type>) { <test_body> }

    例如:

    TEST(Imgproc_Watershed,regression) { ... }

    为了读取测试数据,使用cvtest::TS::ptr()->get_data_path()函数。例如:

    你把文件放在了opencv_extra/testdata/cv/myfacetracker/clip.avi,你可以使用

    cvtest::TS::ptr()->get_data_path()+ "myfacetracker/clip.avi"来读取这个文件。

    将环境变量OPENCV_TEST_DATA_PATH设置为<your_local_copy_of_opencv_extra>/testdata

    附录

    。。。

     





  • 相关阅读:
    常用FPGA功能块记录
    鸿蒙相关
    微波相关
    Python库大全
    C#环境实现代码的自动生成编译
    STM32相关
    硬件相关
    C# 获取枚举中文注释
    C# 获取自定义特性值
    Asp.Net Core 中 Host 与 WebHost的区别
  • 原文地址:https://www.cnblogs.com/fireae/p/3707507.html
Copyright © 2020-2023  润新知