The OpenCV Coding Style Guide
The source of this document is here.
1. Foreword
The document is a short guide on code style, used in OpenCV. The core libraries (cv, cvaux) are written in C++, so the document concerns only the codes written in C++.
2. Files
All the functionality must be put into one or more .cpp and .hpp files into the appropriate module of OpenCV (https://code.ros.org/svn/opencv/trunk/opencv/modules).
- All the file names are written in lower case for better compatibility with both POSIX and Windows.
C++ interface headers have .hpp extension
Implementation files have .cpp extension
The implementation is put to opencv/modules/<module_name>/src, interface is added to the header files in opencv/modules/<module_name>/include/opencv2/<module_name>. There is no need to add the files to the module explicitly, just rerun CMake and it will add the files automatically.
Sample code in C++, if any, is put to opencv/samples/cpp, sample code in Python - to opencv/samples/python.
Documentation is put to opencv/modules/<module_name>/doc, into one of the existing files or a new file/chapter is added there. In the latter case the file name should be added to the opencv/modules/<module_name>/doc/<module_name>.rst
Tests are put to opencv/modules/<module_name>/test. When a new test source file is added, rerun CMake. If the test needs some data, put it to the separate top-level directory (https://code.ros.org/svn/opencv/trunk/opencv_extra/testdata). For ml module the test data is put to opencv_extra/testdata/ml subdirectory, for other modules - to opencv_extra/testdata/cv subdirectory. Please, limit size of your test data files within a few megabytes.
3. File Structure
Every source file, except for the samples, starts with BSD-compatible license, which template can be found in https://code.ros.org/svn/opencv/trunk/opencv/doc/license.txt. The extra/different copyright clauses are possible, as long as the license stays BSD-compatible.
Other rules for both header and implementation files include:
All the functionality must be put into cv namespace, or, possibly, some nested namespace, e.g. cv::vslam
- Code lines should not be very long. Normally, they should be limited to 100 characters.
- No tabulation should be used. Set your editor to use spaces instead.
- Only English text is allowed. Do not put comments or string literals in other languages.
- Indentation is 4 spaces.
- Header files must use guarding macros, protecting the files from repeated inclusion.
Source files must include precomp.hpp header before other headers, in order to make precompiled headers mechanism in Visual C++ work properly.
4. Naming conventions
- OpenCV uses mixed-case style identifiers for external functions, types and class methods.
- Class names start with a capital letter.
- methods' and functions' names start with a small latter, unless they are named after the author of the algorithm, e.g. cv::Sobel(), in which case they can start with a capital letter.
- Macros and enumeration constants are written with all capital letters. Words are separated by underscore.
All external functions and classes must use CV_EXPORTS, otherwise there will be linking errors on Windows.
5. Designing functions and class interfaces
It is important to design function interface is a way, consistent with the rest of the library. The elements of function interface include:
- Functionality
- Name
- Return value
- Type of arguments
- Order of arguments
- Default values for some arguments
Functionality must be well defined and non-redundant. The function should be easy embedded into different processing pipelines that use other OpenCV functions.
Name should basically reflect the function purpose. There are a few common naming patterns in OpenCV:
Majority of function names have form: <actionName><Object>[<Modifiers>], e.g. calibrateCamera, calcOpticalFlowPyrLK.
Sometimes the function may be called by the algorithm name it implements or result object name it produces, e.g. Sobel, Canny, Rodrigues, sqrt, goodFeaturesToTrack.
Return value should be chosen to simplify function usage. Generally, a function that creates/computes a value should return it. It is the good practice to do so for the functions returning scalar values. However, in case of image processing function it would lead to often allocation/deallocation of large memory blocks, so the image processing functions don't create and return result images rather than modify an output image, passed as a parameter (using non-constant reference).
Functions should not use return value for signaling about critical errors, such as null pointers, division by zero, bad argument range, unsupported image format etc. Instead, they should throw an exception, an instance of cv::Exception or its derivative class. On the other hand, it is recommended to use a return value for signalizing about expected run-time situations that can happen in a correctly working system (e.g. tracked object goes beyond the screen etc.)
Argument types are preferably chosen from the already existing set of OpenCV types: Mat for raster images and matrices, vector<Mat> for collection of images, vector<Point>, vector<Point2f>, vector<Point3f>, vector<KeyPoint> for point sets, contours or collections of key points, Scalar for 1- to 4-element numerical tuples (like colors, quaternions etc.) It is not recommended to use plain pointers and counters, because it makes the interface lower-level, meaning more probable typing errors, memory leaks etc. For passing complex objects into functions, methods, please, consider Ptr<> smart pointer template class.
A consistent argument order is important because it becomes easier to remember the order and it helps programmer to avoid errors, connecting with wrong argument order. The usual order is: <input parameters>, <output parameters>, <flags & optional parameters>.
Input parameters usually have const qualifiers. Large objects are normally passed by a constant reference; primitive types and small structures (int, double, Point, Rect) are passed by value.
Optional arguments often simplify function usage. Because C++ allows optional arguments in the end of parameters list only, it also may affect decisions on argument order—the most important flags go first and less important—after.
For example function and class declarations, take a look at https://code.ros.org/svn/opencv/trunk/opencv/modules/core/include/opencv2/core/core.hpp.
6. Code Layout
There is a single strict coding guideline in OpenCV: each single file must use a consistent formatting style.
Currently used in OpenCV and recommended formatting style looks as follows:
Other styles might be also accepted if only the above rule is met. That is, if one changes written by others code, he (she) should use the same coding style.
7. Portability, External Dependencies
Formally, the code must comply with the C++ standard. However, since All the codes must be compliant with the following standards:
- ANSI C – the first C language standard ISO/IEC 9899:1990, modified and corrected in ISO/IEC 9899 COR1: 1994, ISO/IEC 9899 AMD1: 1995 and ISO/IEC 9899 COR2: 1996.
- C9X (newel C standard accepted in 1999) – ISO/IEC 9899.
- C++ standard – ISO/IEC 14882-1998.
One should get rid of compiler-dependent or platform-dependent constructions and system calls, such as:
- Compiler pragma's
Specific keywords, e.g. __stdcall, __inline, __int64 (or long long). Use CV_INLINE, CV_STDCALL, int64, respectively, instead.
Compiler extensions, e.g. >? and <? macros for min and max, overloaded macros etc.
- Inline assembly
Unix or Win32-specific calls, e.g. bcopy, readdir, CreateFile, WaitForSingleObject etc.
Concrete data sizes instead of sizeof's (sizeof(int) rather than 4), byte order ( *(int*)"\x1\x2\x3\x4" is 0x01020304 or 0x04030201 or what?), simple char instead of signed char or unsigned char for processed data (not for strings). Use short forms uchar for unsigned char and schar for signed char. Use preprocessor directives for surrounding non-portable pieces of code. Try not to use elements that are standard, but hardly supported by the major compiler vendors, such as functionality from C++ TR1 or just finalized C+0x standard.
8. Writing documentation on functions
The documentation for contributed functions is written in ReStructured Text and built using Sphinx tool. To build documentation, you need a full Live Tex or compatible distribution installed (e.g. texlive-full on Ubuntu, MacTex on Mac, MiKTeX on Windows) and Sphinx, which can be installed with easy_install utility (easy_install -U Sphinx).
Use the existing documentation as example. Normally, each function/method description includes:
- the declaration in C/C++
- short description
- all the parameters explained; e.g. specify, which image types are accepted, what would be the recommended values for the parameter and how they affect the algorithm etc.
- the full description with short use samples (or links to the big complete samples in OpenCV SVN repository), references to papers, formulas, etc.
9. Implementing tests
For tests we use Google Test framework. Please, check the documentation at the project site.
Each test source file should include precomp.hpp first.
All the test code is put to cvtest namespace.
- Declare your Google tests as following:
TEST(<module_name>_<tested_class_or_function>, <test_type>) { <test_body> }for exampleTEST(Imgproc_Watershed, regression) { ... }
To access test data, use cvtest::TS::ptr()->get_data_path() method. For example, if you put your test file to opencv_extra/testdata/cv/myfacetracker/clip.avi, you can use cvtest::TS::ptr()->get_data_path() + "myfacetracker/clip.avi" to get full path to the file. To make it work properly, set the environment variable OPENCV_TEST_DATA_PATH to <your_local_copy_of_opencv_extra>/testdata
11. Appendixes
Appendix A. References The document is not a complete style guide. Far more detailed and well-written papers on this topic are listed below:
- Recommended C Style and Coding Standards (updated version of Indian Hill C Style and Coding Standards). Henry Spencer et al. Rev. 6.0, 1990.
- Programming in C++. Rules and Recommendations. Mats Henricson, Erik Nyquist. Ellemtel Communications Systems Laboratories. 1990-1992.
- GNU Coding Standards. Richard Stallman. GNU Project – Free Software Foundation. 2000
Notes On Writing Portable Programs in C. A. Dolenc, A. Lemmke, D. Keppel, G.V. Reilly. 1990. Links to many of these documents can be found at http://www.softpanorama.org/Lang/c.html.
Appendix B. The brief list of rules
- Filenames are written in lower-case letters.
Headers have .h or .hpp extension.
Implementation files have .cpp extension
- Every file includes BSD-compatible license in the beginning
- Do not use tabulation. Indentation is 4 spaces. Lines should not be much longer than ~100 characters.
- Keep consistent formatting style in each particular source file (especially if you modify the existing code).
Each source file includes "precomp.hpp" as the first header.
- The code is put into cv namespace. Test code is put into cvtest namespace.
- Only English should be used in comments and string literals.
- External function names and data type names are written in mixed case. Classes start with capital letter, functions start with small letter. External macros are written in upper case.
Use CV_EXPORTS macro within external functions and classes declarations.
- Do not use conditional compilation in headers.
- Keep the external interface as compact as possible. Do not export internal-use classes or functions which are not essential and could be hidden.
- Try to make your code easily wrappable for Python, Java etc. That is, try not to introduce new types. Do not use callbacks.
Use CV_Error to report about incorrect parameters and/or use CV_Assert to verify some conditions, e.g. CV_Assert(inputImage.type() == CV_8UC3).
- Be compliant with the C/C++ standards. Avoid compiler-dependent, OS-dependent and platform-dependent constructions. Do not use TR1 extensions yet.
Try not to use malloc/free, new/delete. Use cv::Mat, std::vector, std::map, cv::AutoBuffer, cv::Ptr instead. Those classes handle the memory automatically.
- Provide GTest-based tests for your code.
- Provide documentation for your code in RST format. Doxygen comments do not count.