天天看点

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

OpenCV提供了一系列帮助函数,用来帮助开发人员能够快速进行开发,下面来逐一分析其帮助函数

cv::alignPtr()

该函数主要是将给定的指针按照给定的自己来对齐,API形式如下:

template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
           

其中ptr为传递的原内存地址, n为按照需要的字节数对齐,默认情况下是按照指针的类型进行对齐

函数返回值为对齐后的指针地址。其函数实现比较简单

template<typename _Tp> static inline _Tp* alignPtr(_Tp* ptr, int n=(int)sizeof(_Tp))
{
    CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
    return (_Tp*)(((size_t)ptr + n-1) & -n);
}
           

初次看到上述的实现,有点蒙,后来查了很多资料,看懂上述实现要首先知道原码、反码和补码的几个基础概念:

原码、反码、补码

在冯~诺依曼提出的经典计算机体系结构框架中,一台计算器由运算器、控制器、存储器、输入和输出设备有关。其中由于在初期设计的计算器比较庞大,所以在设计的时候只有加法运算器,没有减法运算器(主要是由于减法器实现比较复杂),为了实现减法运算,在设计时都是通过加法来实现的,一个a-b的运算,其减法可以看成是这个数的相反数相加即看成a+(-b),由此产生了负数,在计算机中使用一个专门的符号位来表示,由此诞生出来原码、补码、反码。具体不清楚的可以重新翻下《计算机组成原理》。

原码:是最简单的机器数表示方法。一般使用最高位来表示符号位,‘1’表示负号,0表示正号。

反码:主要是针对的是负数,负数的反码为除了符号位外,按位取反。正数的反码等于原码

补码:正数的补码等于原码,负数的补码等于反码+1(通常还有另外一种算法,不在另外详细描述)

关于原码、补码、补码可以查看https://blog.csdn.net/zhiwen_a/article/details/81192087,描述的比较形象,当然比较科学的方法还是看 《计算机组成原理》这本书,还是回归到了基础。

        比如 5的原码为0......0101 , 5的反码为0......0101, 5的补码也为0......0101

         -5的原码为1.......0101, -5的反码为111...1010, -5的补码为1111...1011

        实际在计算机系统中,数据在内存中都是以补码的形式进行存储的 

理解了上述意思就能够明白 (_Tp*)(((size_t)ptr + n-1) & -n)是如何实现的, 关键在与理解-n, 在计算机对齐首先要明白n必须为2的m次方,即n一般应该为2,4,8,16,....,当n等于16时,其-n即为-16, -16的原码为1000...0010000,其反码为1111...1101111,补码为1111...1110000,相当于取的是地址的高位,地位直接截断进行对齐!!!!!!

(_Tp*)(((size_t)ptr + n-1) & -n)整句话的意思是首先将ptr指针向后 n-1位置,最后用-n 取其最高位对齐地址

下面列举一个,按照64位对齐的用例:

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


void main()
{
	char * buffer = (char *)malloc(100);
	char * buffer2;
	if (NULL == buffer)
	{
		return;
	}

	printf("buffer address: 0x%X\n", buffer);
	printf("buffer +(n-1) address: 0x%X\n", (size_t)buffer + 64-1);

	buffer2 = cv::alignPtr(buffer, 64);

	printf("buffer2 address: 0x%X\n", buffer2);
	free(buffer);
}
           

 运行结果为:

buffer address: 0x7F5D0CF0
buffer +(n-1) address: 0x7F5D0D2F
buffer2 address: 0x7F5D0D00
           

申请到buffer地址为  0x7F5D0CF0:偏移63位之后地址为 0x7F5D0D2F,取齐后的地址为0x7F5D0D00

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

 cv::alignSize

将即将申请到的缓存 与给定自己数字节数对齐,经常用于即将申请的缓存 需要与数据结构对齐场景,以防止申请到的内存不够使用

static inline size_t alignSize(size_t sz, int n)
           

其原码实现和指针对齐类似:

static inline size_t alignSize(size_t sz, int n)
{
    CV_DbgAssert((n & (n - 1)) == 0); // n is a power of 2
    return (sz + n-1) & -n;
}
           

用例,即将即将申请的100字节的内存,需要与64字节大小对齐

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


void main()
{
	printf("Align size: %d\n", cv::alignSize(100, 64));
}
           

运行结果:

Align size: 128
           

AutoBuffer

AutoBuffer类已经替换了之前的旧版本中的cv:allocate()申请方式,改为了模板方式。该类是opencv提供的内存申请释放等内存管理模板,主要应对的场景很多时候其申请的内存大小并不知道多少,是由参数或者其他方式传递过来的,如果要申请的内存不小心太大时 在栈中申请很容易把栈击穿,所以opencv提供了针对此类场景,封装了特殊的类,便于进行管理和使用。当然也可以用于一般固定已知大小下申请内存场景,下面可以看下源代码中的注释:

The class is used for temporary buffers in functions and methods. If a temporary buffer is usually small (a few K's of memory), but its size depends on the parameters, it makes sense to create a small fixed-size array on stack and use it if it's large enough. If the required buffer size is larger than the fixed size, another buffer of sufficient size is allocated dynamically and released after the processing. Therefore, in typical cases, when the buffer size is small, there is no overhead associated with malloc()/free(). At the same time, there is no limit on the size of processed data.

AutoBuffer类申请的内存在堆中,该类模板中有两个参数 _Tp和 fixed_size,  _Tp为所申请的内存的数据类型,可以为类,数据结构等等, AutoBuffer中申请的内存相当于C语言中的数组,其数据类型为 _Tp, 数组大小为 fixed_size,占用的实际空间为sizeof( _Tp)*fixed_size: 

template<typename _Tp, size_t fixed_size = 1024/sizeof(_Tp)+8> class AutoBuffer
           

由其上述定义可知 fixed_size默认大小为1024/sizeof(_Tp)+8。

最新的4.2版本中AutoBuffe类中显示定义如下:

Method Description
typedef _Tp value_type 定义的数据类型
AutoBuffer() 默认构造函数
explicit AutoBuffer(size_t _size) 带size_t _size的构造函数
AutoBuffer(const AutoBuffer<_Tp, fixed_size>& buf) copy构造函数
AutoBuffer<_Tp, fixed_size>& operator = (const AutoBuffer<_Tp, fixed_size>& buf) 支持两个类用等号直接负责
 ~AutoBuffer(); 析构函数,通过析构函数释放内存
 void allocate(size_t _size) 申请内存,如果该类之前申请过内存,新的要申请的内存大于旧的内存,则释放掉旧内存块,重新按照新的内存大小申请
 void deallocate(); 释放内存
void resize(size_t _size) 重新申请内存,如果新申请的内存比旧的内存小 则直接返回
size_t size()  返回数组大小
  inline _Tp* data() 获取申请的内存地址,可读可写
 inline const _Tp* data() const 获取申请的内存地址,只可读
inline _Tp& operator[] (size_t i) 支持像数组一样进行访问,可读可写
 inline const _Tp& operator[] (size_t i) 支持像数组一样进行访问,只可读

三个构造函数用例:

cv::AutoBuffer<float, 1000> buf; // 创建一个包含1000 float自动缓冲区
	cv::AutoBuffer<float> dbuf(1000);// 创建一个包含1000 float自动缓冲区
	cv::AutoBuffer<float> dbuf1(dbuf);//根据dbuf类创建一个新的dbuf1
           

AutoBuffer数组访问修改方式

遍历数组对齐进行赋值的两种方式:

1:使用data()获取到内存地址:进行读写

2:AutoBuffe支持operator[]重构,可以直接像数组一样 进行访问读写。

两种用法使用用例如下:

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


void main()
{
	cv::AutoBuffer<int, 10> buf; // 创建一个包含1000 float自动缓冲区
	
	int *Dst = buf.data();

	for (int i = 0; i < 10; i++)
	{
		Dst[i] = i;
	}

	for (int i = 0; i < 10; i++)
	{
		cout << "Index: " << i << ",value: " << buf[i] << endl;
	}
}
           

AutoBuffer operator =

AutoBuffe支持两个类直接 相等进行赋值,两个AutoBuffe类为两个不同的内存空间,修改相互不影响,这点和Mat不同,两个Mat直接用的是同一块内存,下面为实现源码:

template<typename _Tp, size_t fixed_size> inline AutoBuffer<_Tp, fixed_size>&
AutoBuffer<_Tp, fixed_size>::operator = (const AutoBuffer<_Tp, fixed_size>& abuf)
{
    if( this != &abuf )
    {
        deallocate();
        allocate(abuf.size());
        for( size_t i = 0; i < sz; i++ )
            ptr[i] = abuf.ptr[i];
    }
    return *this;
}
           

现将就得内存释放掉,然后按照abuf内存大小申请内存数组,并将abuf中的数组值一一赋值到内存中。

#include <stdio.h>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


void main()
{
	cv::AutoBuffer<int, 10> buf; // 创建一个包含1000 float自动缓冲区
	
	cv::AutoBuffer<int, 10> buf2;
	int *Dst = buf.data();

	for (int i = 0; i < 10; i++)
	{
		Dst[i] = i;
	}

	buf2 = buf;
	for (int i = 0; i < 10; i++)
	{
		cout << "Index: " << i << ",value: " << buf2[i] << endl;
	}

	for (int i = 0; i < 10; i++)
	{
		buf[i] = i*10;
	}

	for (int i = 0; i < 10; i++)
	{
		cout << "Index: " << i << ",value: " << buf2[i] << endl;
	}

}
           

AutoBuffer allocate

AutoBuffer类申请内存接口allocate比较简单,首先查看是否申请过内存,如果之前申请过内存比较就得内存块是否小于新的需要申请的内存块大小, 否则直接返回, 是则释放就得内存 重新申请新的内存数组如同调用new一样

template<typename _Tp, size_t fixed_size> inline void
AutoBuffer<_Tp, fixed_size>::allocate(size_t _size)
{
    if(_size <= sz)
    {
        sz = _size;
        return;
    }
    deallocate();
    sz = _size;
    if(_size > fixed_size)
    {
        ptr = new _Tp[_size];
    }
}
           

 AutoBuffer deallocate

deallocate()方法为释放内存,相当于调用delete函数

template<typename _Tp, size_t fixed_size> inline void
AutoBuffer<_Tp, fixed_size>::deallocate()
{
    if( ptr != buf )
    {
        delete[] ptr;
        ptr = buf;
        sz = fixed_size;
    }
}
           

 AutoBuffer  resize

resize()函数重新调整内存,如果旧的内存小于新的需要调整的内存大小 则申请新的内存块,然后将旧的内存的数组值赋值给新的内存块,新的数组多余的部分则初始化为0.如果旧的内存大于新的需要调整的内存大小,还是需要申请新的内存,将旧的部分相应的部分赋值给新的内存,超过新的内存部分不在赋值给新的内存,原有的就得内存都需要释放掉。

template<typename _Tp, size_t fixed_size> inline void
AutoBuffer<_Tp, fixed_size>::resize(size_t _size)
{
    if(_size <= sz)
    {
        sz = _size;
        return;
    }
    size_t i, prevsize = sz, minsize = MIN(prevsize, _size);
    _Tp* prevptr = ptr;

    ptr = _size > fixed_size ? new _Tp[_size] : buf;
    sz = _size;

    if( ptr != prevptr )
        for( i = 0; i < minsize; i++ )
            ptr[i] = prevptr[i];
    for( i = prevsize; i < _size; i++ )
        ptr[i] = _Tp();

    if( prevptr != buf )
        delete[] prevptr;
}
           

Fast math

fast math为opencv提供的函数数学库,针对X86、ARM以及因特网SSE2指令集,以及aplple平台以及微软的C/C++编译器都经过特殊优化,重点突出‘Fast’ 特点,文件位于\core\include\opencv2\core\fast_math.hpp

cvRound

cvRound函数为求一个浮点型四舍五入到整型,入参为浮点型,返回值为整型

int cvRound( double value )
           

用例:

cout << "value1 : " << cvRound(3.14) << endl;
cout << "value2 : " << cvRound(3.9) << endl;
cout << "value3 : " << cvRound(-3.9) << endl;
           

 结果:

value1 : 3
value2 : 4
value3 : -4
           

cvFloor

cvFloor函数为向下取整,其接口为 

int cvFloor( double value )
           

 用例:

cout << "value1 : " << cvFloor(3.14) << endl;
	cout << "value2 : " << cvFloor(3.9) << endl;
	cout << "value3 : " << cvFloor(-3.9) << endl;
           

结果:

value1 : 3
value2 : 3
value3 : -4
           

cvCeil

向上取整,入参为double,返回值为整型

CV_INLINE int cvCeil( double value )
{
#if (defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS) \
    && ( \
        defined(__PPC64__) \
    )
    return __builtin_ceil(value);
#else
    int i = (int)value;
    return i + (i < value);
#endif
}
           

用例:

cout << "value1 : " << cvCeil(3.2) << endl;
cout << "value2 : " << cvCeil(3.9) << endl;
           

 运行结果:

value1 : 4

        value2 : 4

cv::cubeRoot

计算一个数的立方根,入参为float,返回值也为float 

float  cubeRoot( float value )
           

用例:

cout << "value1 : " << cubeRoot(8) << endl;
	cout << "value2 : " << cubeRoot(-8) << endl;
           

 结果:

value1 : 2
value2 : -2
           

cvIsNaN

cvIsNaN函数判断一个浮点数是不是一个数,如果不符合 IEEE754标准则返回1, 否则返回0

int cvIsNaN( double value )
           

IEEE754标准起草者加州大学伯克利分校数学系教授William Kahan,他帮助Intel公司设计了8087浮点处理器(FPU),并以此为基础形成了IEEE 754标准,并由此获得1987年图灵奖,个人主页http://www.cs.berkeley.edu/~wkahan/

IEEE754标准全名为ANSI/IEEE Std 754-1985《IEEE Standard for Binary Floating-Point Arithmetic》,规定了浮点数的二进制表示方式,主要分为单精度和双精度浮点:

单精度浮点

单精度浮点数字长32位,尾数长度23,指数长度8,指数偏移量127:

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

标准中规定32位单精度浮点数意义,其中v是浮点的值value的缩写,e是指数位, f是位数位, s是符号位:

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

 双精度浮点

双精度浮点数字长64位,尾数长度52,指数长度11,指数偏移量1023:

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

标准中规定中的双精度符号位如下: 

OpenCV辅助函数(utility functions)cv::alignPtr() cv::alignSizeAutoBufferFast mathcv::CV_Assert()cv::CV_Error()cv::fastMalloccv::fastFree()cv::format()与系统相关函数版本相关API

用例:

double test  = 0x7FF0000000000000;
	double test1 = 0x7FF0000000002340;
	double test2 = 0x2330000000002340;
	double test3 = 1.1;

	cout << "cvIsNaN(test) : " << cvIsNaN(test) << endl;
	cout << "cvIsNaN(test1) : " << cvIsNaN(test1) << endl;
	cout << "cvIsNaN(test2) : " << cvIsNaN(test2) << endl;
	cout << "cvIsNaN(test3) : " << cvIsNaN(test3) << endl;
           

cvIsInf

cvIsInf():判断是否为正负无穷,如果是则返回1,否则返回0

int cvIsInf( double value )
           

用例:

double test  = 0x7FF0000000000000;
double test1 = 0x7ff0000000000233;
double test2 = 0x2330000000002340;
double test3 = 1/3;

cout << "cvIsNaN(test) : " << cvIsInf(test) << endl;
cout << "cvIsNaN(test1) : " << cvIsInf(test1) << endl;
cout << "cvIsNaN(test2) : " << cvIsInf(test2) << endl;
cout << "cvIsNaN(test3) : " << cvIsInf(test3) << endl;
           

cv::CV_Assert()

opencv封装的断言,如果为False则会抛出异常

cv::CV_Error()

它允许传递一个错误代码ecode和一个固定C风格的字符串estring,然后它们会被打包送进cv::Exception,进而传递给cv::error()进行处理。如果需要在运行过程中构建消息,那么可以使用不同的宏CV_Error_(),CV_Error_()接受与CV_Error()相同的错误代码ecode,但需要一个sprintf()风格的字符串紧跟着各种变量参数,就是sprintf()所需要的。

CV_Assert和CV_Error两个都是宏,定义如下:

#ifdef CV_STATIC_ANALYSIS

// In practice, some macro are not processed correctly (noreturn is not detected).
// We need to use simplified definition for them.
#define CV_Error(code, msg) do { (void)(code); (void)(msg); abort(); } while (0)
#define CV_Error_(code, args) do { (void)(code); (void)(cv::format args); abort(); } while (0)
#define CV_Assert( expr ) do { if (!(expr)) abort(); } while (0)

#else // CV_STATIC_ANALYSIS
 
#define CV_Error( code, msg ) cv::error( code, msg, CV_Func, __FILE__, __LINE__ )

#define CV_Error_( code, args ) cv::error( code, cv::format args, CV_Func, __FILE__, __LINE__ )

#define CV_Assert( expr ) do { if(!!(expr)) ; else cv::error( cv::Error::StsAssert, #expr, CV_Func, __FILE__, __LINE__ ); } while(0)

#endif // CV_STATIC_ANALYSIS
           

cv::fastMalloc

这个函数的工作机制和malloc()类似,但是因为它做了缓存区内存大小对齐,所以执行速度更快。这意味着,如果传递的缓存区大小超过16bit,那么返回的缓存区会被对齐到16bit的边界。

void* fastMalloc(size_t size)
           

cv::fastFree()

释放由cv::fastMalloc()(上面提到)分配的内存

void fastFree(void* ptr)
           

cv::format()

格式化输出函数,本质上与标准库中的sprintf()相同,但是,它不需要从访问者中获得一个字符缓存区,而是构建一个STL字符串并返回它。它对Exception()构造函数格式化错误信息很有用。

String format( const char* fmt, ... )
           

与系统相关函数

与系统和硬件相关的API 其头文件主要modules\core\include\opencv2\core\utility.hpp中。

getCPUTickCount

getCPUTickCount():获取系统时钟的CPU tick数目,在一些特殊平台上比如x86,x64以及PowerPC都是经过优化,在其他一些不是很常见的平台 相当于调用getTickCount()函数,返回值为64位,8个字节

int64 getCPUTickCount()
           

函数的最终实现是在modules\core\src\System.cpp, 该文件是涉及到与硬件相关的函数都进行过特殊优化。

TickMeter

在实际处理程序中,很多地方都需要衡量一个算法或者程序的实时性,一般处理方法是在运行该段代码前获取到当前Tick start_tick,在运行完之后获取到当前tick, end_tick, 则时间搓实际为( end_tick-start_tick)。OpenCV对上述过程进行了简化,直接将该过程封装到TickMeter类中,使用方法也比较简单:

TickMeter tm;
tm.start();
// do something ...
tm.stop();
std::cout << tm.getTimeSec();
           

可以计算没轮循环实际:

TickMeter tm;
for (int i = 0; i < 100; i++)
{
    tm.start();
    // do something ...
    tm.stop();
}
double
           

 相对之前 程序时间搓方法简单了很多。 该类的定义在F:\openvino\opencv-4.1.2\modules\core\include\opencv2\core\utility.hpp文件中,有兴趣可以了解一下。

checkHardwareSupport

checkHardwareSupport()检查其CPU硬件平台时候支持某个特性,

bool checkHardwareSupport(int feature)
           

最新4.2版本中 feature支持有以下选项:

* CPU features and intrinsics support */
#define CV_CPU_NONE             0
#define CV_CPU_MMX              1
#define CV_CPU_SSE              2
#define CV_CPU_SSE2             3
#define CV_CPU_SSE3             4
#define CV_CPU_SSSE3            5
#define CV_CPU_SSE4_1           6
#define CV_CPU_SSE4_2           7
#define CV_CPU_POPCNT           8
#define CV_CPU_FP16             9
#define CV_CPU_AVX              10
#define CV_CPU_AVX2             11
#define CV_CPU_FMA3             12

#define CV_CPU_AVX_512F         13
#define CV_CPU_AVX_512BW        14
#define CV_CPU_AVX_512CD        15
#define CV_CPU_AVX_512DQ        16
#define CV_CPU_AVX_512ER        17
#define CV_CPU_AVX_512IFMA512   18 // deprecated
#define CV_CPU_AVX_512IFMA      18
#define CV_CPU_AVX_512PF        19
#define CV_CPU_AVX_512VBMI      20
#define CV_CPU_AVX_512VL        21
#define CV_CPU_AVX_512VBMI2     22
#define CV_CPU_AVX_512VNNI      23
#define CV_CPU_AVX_512BITALG    24
#define CV_CPU_AVX_512VPOPCNTDQ 25
#define CV_CPU_AVX_5124VNNIW    26
#define CV_CPU_AVX_5124FMAPS    27

#define CV_CPU_NEON             100

#define CV_CPU_MSA              150

#define CV_CPU_VSX              200
#define CV_CPU_VSX3             201

// CPU features groups
#define CV_CPU_AVX512_SKX       256
#define CV_CPU_AVX512_COMMON    257
#define CV_CPU_AVX512_KNL       258
#define CV_CPU_AVX512_KNM       259
#define CV_CPU_AVX512_CNL       260
#define CV_CPU_AVX512_CLX       261
#define CV_CPU_AVX512_ICL       262

// when adding to this list remember to update the following enum
#define CV_HARDWARE_MAX_FEATURE 512
           

getHardwareFeatureName

getHardwareFeatureName()根据其特获取到其特性字符串,

String getHardwareFeatureName(int feature)
           

支持的特性字符串为:

g_hwFeatureNames[CPU_MMX] = "MMX";
        g_hwFeatureNames[CPU_SSE] = "SSE";
        g_hwFeatureNames[CPU_SSE2] = "SSE2";
        g_hwFeatureNames[CPU_SSE3] = "SSE3";
        g_hwFeatureNames[CPU_SSSE3] = "SSSE3";
        g_hwFeatureNames[CPU_SSE4_1] = "SSE4.1";
        g_hwFeatureNames[CPU_SSE4_2] = "SSE4.2";
        g_hwFeatureNames[CPU_POPCNT] = "POPCNT";
        g_hwFeatureNames[CPU_FP16] = "FP16";
        g_hwFeatureNames[CPU_AVX] = "AVX";
        g_hwFeatureNames[CPU_AVX2] = "AVX2";
        g_hwFeatureNames[CPU_FMA3] = "FMA3";

        g_hwFeatureNames[CPU_AVX_512F] = "AVX512F";
        g_hwFeatureNames[CPU_AVX_512BW] = "AVX512BW";
        g_hwFeatureNames[CPU_AVX_512CD] = "AVX512CD";
        g_hwFeatureNames[CPU_AVX_512DQ] = "AVX512DQ";
        g_hwFeatureNames[CPU_AVX_512ER] = "AVX512ER";
        g_hwFeatureNames[CPU_AVX_512IFMA] = "AVX512IFMA";
        g_hwFeatureNames[CPU_AVX_512PF] = "AVX512PF";
        g_hwFeatureNames[CPU_AVX_512VBMI] = "AVX512VBMI";
        g_hwFeatureNames[CPU_AVX_512VL] = "AVX512VL";
        g_hwFeatureNames[CPU_AVX_512VBMI2] = "AVX512VBMI2";
        g_hwFeatureNames[CPU_AVX_512VNNI] = "AVX512VNNI";
        g_hwFeatureNames[CPU_AVX_512BITALG] = "AVX512BITALG";
        g_hwFeatureNames[CPU_AVX_512VPOPCNTDQ] = "AVX512VPOPCNTDQ";
        g_hwFeatureNames[CPU_AVX_5124VNNIW] = "AVX5124VNNIW";
        g_hwFeatureNames[CPU_AVX_5124FMAPS] = "AVX5124FMAPS";

        g_hwFeatureNames[CPU_NEON] = "NEON";

        g_hwFeatureNames[CPU_VSX] = "VSX";
        g_hwFeatureNames[CPU_VSX3] = "VSX3";

        g_hwFeatureNames[CPU_MSA] = "CPU_MSA";

        g_hwFeatureNames[CPU_AVX512_COMMON] = "AVX512-COMMON";
        g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX";
        g_hwFeatureNames[CPU_AVX512_KNL] = "AVX512-KNL";
        g_hwFeatureNames[CPU_AVX512_KNM] = "AVX512-KNM";
        g_hwFeatureNames[CPU_AVX512_CNL] = "AVX512-CNL";
        g_hwFeatureNames[CPU_AVX512_CLX] = "AVX512-CLX";
        g_hwFeatureNames[CPU_AVX512_ICL] = "AVX512-ICL";
           

getCPUFeaturesLine

getCPUFeaturesLine获取到使用到的该CPU得到的硬件平台特性

std::string getCPUFeaturesLine()
           

CPU支持的特性有可能不止一种,所以返回的字符串是一系列特性,特性之间使用空格分开

比如:

cout << "CPU features : " << getCPUFeaturesLine() << endl;
           

运行结果:

CPU features : SSE SSE2 SSE3 *SSE4.1 *SSE4.2 *FP16 *AVX *AVX2?
           

setUseOptimized

opencv不仅支持获取CPU优化特性,还支持动态关闭或者开启CPU的特性

void setUseOptimized(bool onoff)
           

可以控制的特性比如 SSE4.2, AVX/AVX2, 和其他特性

useOptimized

查看CPU的优化代码特殊是关闭还是开启的

bool useOptimized()
           

getNumberOfCPUs

获取硬件平台中CPU的数量

int getNumberOfCPUs()
           

比如:

cout << "CPU number : " << getNumberOfCPUs() << endl;
           

运行结果:

CPU number : 4
           

 getNumThreads

getNumThreads()获取到OpenCV用到的线程数目:

int getNumThreads()
           

获取到的线程数目与使用到的并行编程的第三方库有关:

如果OpenCV中的编译不支持并行计算,则返回的是1

TBB: 返回OpenCV将会使用到的并行线程,如果tbb库中tbb::thread_scheduler_init与OpenCV相冲突,则返回的是TBB默认的线程数目

OpenMP: 返回的是使用到的最大线程数目

Concurrency:返回的将要使用到的并行线程数目

GCD:不支持,返回的是GCD线程库的线程池中的数目限制512

C=:opencv尝试使用到的线程数目。如果之前没有调用setNumThreads设置过数目,则返回的数逻辑CPU上能够使用到的数目

opencv中的源码解释如下: 

Always returns 1 if OpenCV is built without threading support.

The exact meaning of return value depends on the threading framework used by OpenCV library:
- `TBB` - The number of threads, that OpenCV will try to use for parallel regions. If there is
  any tbb::thread_scheduler_init in user code conflicting with OpenCV, then function returns
  default number of threads used by TBB library.
- `OpenMP` - An upper bound on the number of threads that could be used to form a new team.
- `Concurrency` - The number of threads, that OpenCV will try to use for parallel regions.
- `GCD` - Unsupported; returns the GCD thread pool limit (512) for compatibility.
- `C=` - The number of threads, that OpenCV will try to use for parallel regions, if before
  called setNumThreads with threads \> 0, otherwise returns the number of logical CPUs,
  available for the process.
           

setNumThreads

设置并行计算中将要用到的线程数目:

void setNumThreads(int nthreads)
           

如果设置的是0,则关闭并行计算功能,所有的功能都按照串行来运行

在设置并将计算线程中还与具体并行计算框架有关

TBB: 没有特殊情况下将会按照设置的并行线程数目来运行

OpenMP:没有特殊情况

Concurrency: 如果设置的线程数目为1,则将会关闭并行计算,按照串行来执行

GCD:仅支持values \<= 0

C=:没有特殊情况

opencv中的源码解释如下: 

If threads == 0, OpenCV will disable threading optimizations and run all it's functions
sequentially. Passing threads \< 0 will reset threads number to system default. This function must
be called outside of parallel region.

OpenCV will try to run its functions with specified threads number, but some behaviour differs from
framework:
-   `TBB` - User-defined parallel constructions will run with the same threads number, if
    another is not specified. If later on user creates his own scheduler, OpenCV will use it.
-   `OpenMP` - No special defined behaviour.
-   `Concurrency` - If threads == 1, OpenCV will disable threading optimizations and run its
    functions sequentially.
-   `GCD` - Supports only values \<= 0.
-   `C=` - No special defined behaviour.
           

getThreadNum

返回正在执行并行计算的线程index

int getThreadNum()
           

如果并行计算功能被关闭 将会返回0

返回的值和具体的并行编程框架有关:

TBB: 当前4.1TBB 版本不支持

 OpenMP: 返回当前执行的team 的thread number

Concurrency:返回的是当前虚拟处理器的ID

GCD:返回的是线程ID,在执行的并行计算过程中永远不会返回0

C=:当前并行计算的任务 index

OpenCV中的源码解释如下:

/** @brief Returns the index of the currently executed thread within the current parallel region. Always
returns 0 if called outside of parallel region.

@deprecated Current implementation doesn't corresponding to this documentation.

The exact meaning of the return value depends on the threading framework used by OpenCV library:
- `TBB` - Unsupported with current 4.1 TBB release. Maybe will be supported in future.
- `OpenMP` - The thread number, within the current team, of the calling thread.
- `Concurrency` - An ID for the virtual processor that the current context is executing on (0
  for master thread and unique number for others, but not necessary 1,2,3,...).
- `GCD` - System calling thread's ID. Never returns 0 inside parallel region.
- `C=` - The index of the current parallel task.
           

版本相关API

opencv提供了一些了丰富的版本管理API,用于获取版本、以及编译选项相关的信息。

 getBuildInformation

返回cmake中系统版本信息,以及编译版本信息,以及编译选项,使用的模块,以及第三方库信息等等:

const String& getBuildInformation()
           

 用例:

cout << "Build information : " << getBuildInformation() << endl;
           

以下是本机运行的Build 信息:

General configuration for OpenCV 3.4.3 =====================================
  Version control:               3.4.3

  Platform:
    Timestamp:                   2018-08-29T10:35:45Z
    Host:                        Windows 10.0.17134 AMD64
    CMake:                       3.11.0
    CMake generator:             Visual Studio 15 2017 Win64
    CMake build tool:            C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/MSBuild/15.0/Bin/MSBuild.exe
    MSVC:                        1914

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (3 files):          + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (1 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (5 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (9 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2

  C/C++:
    Built as dynamic libs?:      YES
    C++11:                       YES
    C++ Compiler:                C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe  (ver 19.14.26433.0)
    C++ flags (Release):         /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP8   /MD /O2 /Ob2 /DNDEBUG
    C++ flags (Debug):           /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP8   /MDd /Zi /Ob0 /Od /RTC1
    C Compiler:                  C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/VC/Tools/MSVC/14.14.26428/bin/Hostx86/x64/cl.exe
    C flags (Release):           /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP8    /MD /O2 /Ob2 /DNDEBUG
    C flags (Debug):             /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP8  /MDd /Zi /Ob0 /Od /RTC1
    Linker flags (Release):      /machine:x64  /INCREMENTAL:NO
    Linker flags (Debug):        /machine:x64  /debug /INCREMENTAL
    ccache:                      NO
    Precompiled headers:         NO
    Extra dependencies:
    3rdparty dependencies:

  OpenCV modules:
    To be built:                 calib3d core dnn features2d flann highgui imgcodecs imgproc java_bindings_generator ml objdetect photo python_bindings_generator shape stitching superres video videoio videostab world
    Disabled:                    js python2 python3
    Disabled by dependency:      -
    Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java ts viz
    Applications:                apps
    Documentation:               NO
    Non-free algorithms:         NO

  Windows RT support:            NO

  GUI:
    Win32 UI:                    YES
    VTK support:                 NO

  Media I/O:
    ZLib:                        build (ver 1.2.11)
    JPEG:                        build-libjpeg-turbo (ver 1.5.3-62)
    WEBP:                        build (ver encoder: 0x020e)
    PNG:                         build (ver 1.6.34)
    TIFF:                        build (ver 42 - 4.0.9)
    JPEG 2000:                   build (ver 1.900.1)
    OpenEXR:                     build (ver 1.7.1)
    HDR:                         YES
    SUNRASTER:                   YES
    PXM:                         YES

  Video I/O:
    Video for Windows:           YES
    DC1394:                      NO
    FFMPEG:                      YES (prebuilt binaries)
      avcodec:                   YES (ver 57.107.100)
      avformat:                  YES (ver 57.83.100)
      avutil:                    YES (ver 55.78.100)
      swscale:                   YES (ver 4.8.100)
      avresample:                YES (ver 3.7.0)
    GStreamer:                   NO
    DirectShow:                  YES
    Media Foundation:            YES

  Parallel framework:            Concurrency

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Intel IPP:                   2017.0.3 [2017.0.3]
           at:                   C:/build/3_4_winpack-build-win64-vc15/build/3rdparty/ippicv/ippicv_win
    Intel IPP IW:                sources (2017.0.3)
              at:                C:/build/3_4_winpack-build-win64-vc15/build/3rdparty/ippicv/ippiw_win
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.5.1)

  OpenCL:                        YES (no extra features)
    Include path:                C:/build/3_4_winpack-build-win64-vc15/opencv/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python (for build):            C:/utils/soft/python27-x64/python.exe

  Java:
    ant:                         C:/utils/soft/apache-ant-1.9.7/bin/ant.bat (ver 1.9.7)
    JNI:                         C:/Program Files/Java/jdk1.8.0_112/include C:/Program Files/Java/jdk1.8.0_112/include/win32 C:/Program Files/Java/jdk1.8.0_112/include
    Java wrappers:               NO
    Java tests:                  NO

  Matlab:                        NO

  Install to:                    C:/build/3_4_winpack-build-win64-vc15/install
-----------------------------------------------------------------
           

getVersionString

获取OpenCV版本信息,返回值为字符串

String getVersionString()
           

用例:

cout << "Version : " << getVersionString() << endl;
           

以下是本人机器上运行的版本信息:

Version : 3.4.3
           

getVersionMajor

获取opencv主版本号

int getVersionMajor()
           

getVersionMinor

获取中间版本号

int getVersionMinor()
           

getVersionRevision

获取库版本号,即最后一个版本号

int getVersionRevision()
           

(持续更新中... ...)