1、RNG
cv::RNG
类是opencv里C++的随机数产生器。它可产生一个64位的int随机数。目前可按均匀分布和高斯分布产生随机数。计算机产生的随机数都是伪随机数,是根据种子点seed和特定算法计算出来的。所以,只要种子一定,算法一定,产生的随机数是一定的。
1.1、产生一个随机数
cv::RNG
可以产生3种随机数。
(1)RNG(int seed)
使用种子seed
产生一个64位随机整数,默认-1。
(2)cv::RNG::uniform( )
产生一个均匀分布的随机数。
(3)cv::RNG::gaussian( )
产生一个高斯分布的随机数。
cv::RNG::uniform(a, b )
返回一个 [ a , b ) [a,b) [a,b) 范围的均匀分布的随机数, a , b a, b a,b 的数据类型要一致,而且必须是int
、float
、double
中的一种,默认是int
。
cv::RNG::gaussian( σ)
返回一个均值为 0 0 0,标准差为 σ σ σ 的随机数。如果要产生均值为 λ λ λ,标准差为 σ σ σ 的随机数,可以λ + cv::RNG::gaussian(σ)
RNG rng;
int randomNumber = rng;
cout << "randomNumber=" << randomNumber << endl;
>> randomNumber=130063606
double randomNumber = rng.uniform(0,99);
>> randomNumber=79
double randomNumber = rng.gaussian(2);
>> randomNumber=-3.20619e-09
1.2、返回下一个随机数
上面一次只能返回一个随机数,实际上系统已经生成一个随机数组。如果我们要连续获得随机数,没有必要重新定义一个RNG类,只需要取出随机数组的下一个随机数即可。
(1)cv::RNG:: next
返回下一个64位随机整数。
(2)cv::RNG:: operator
返回下一个指定类型的随机数。
RNG rng;
int randomNumber = rng.next(); //返回下一个随机整数,即N1.next();
//返回下一个指定类型的随机数
int randomNumber = rng.operator uchar(); //返回下一个无符号字符数
int randomNumber = rng.operator schar(); //返回下一个有符号字符数
int randomNumber = rng.operator ushort(); //返回下一个无符号短型
int randomNumber = rng.operator short int(); //返回下一个短整型数
int randomNumber = rng.operator int(); //返回下一个整型数
int randomNumber = rng.operator unsigned int(); //返回下一个无符号整型数
int randomNumber = rng.operator float(); //返回下一个浮点数
int randomNumber = rng.operator double(); //返回下一个double型数
int randomNumber = rng.operator ()(); //和rng.next( )等价
int randomNumber = rng.operator ()(100); //返回[0,100)范围内的随机数
1.3、用随机数填充矩阵 RNG::fill( )
void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false );
InputOutputArray
输入输出矩阵,最多支持4通道,超过4通道先用reshape()改变结构。
int distType
UNIFORM 或 NORMAL,表示均匀分布和高斯分布。
InputArray a
disType是UNIFORM,a表示为下界(闭区间);disType是NORMAL,a均值。
InputArray b
disType是UNIFORM,b表示为上界(开区间);disType是NORMAL,b标准差。
bool saturateRange=false
只针对均匀分布有效。当为真的时候,会先把产生随机数的范围变换到数据类型的范围,再产生随机数。如果为假,会先产生随机数,再进行截断到数据类型的有效区间。
//产生[1,1000)均匀分布的int随机数填充fillM
Mat_<int>fillM(3,3);
rng.fill(fillM,RNG::UNIFORM,1,1000);
cout << "filM = " << fillM << endl << endl;
Mat fillM1(3,3,CV_8U);
rng.fill(fillM1,RNG::UNIFORM,1,1000,TRUE);
cout << "filM1 = " << fillM1 << endl << endl;
Mat fillM2(3,3,CV_8U);
rng.fill(fillM2,RNG::UNIFORM,1,1000,FALSE);
cout << "filM2 = " << fillM2 << endl << endl;
//fillM1产生的数据都在[0,,255)内,且小于255;
//fillM2产生的数据虽然也在同样范围内,但是由于用了截断操作,所以很多数据都是255,
//产生均值为1,标准差为3的随机double数填进fillN
Mat_<double>fillN(3,3);
rng.fill(fillN,RNG::NORMAL,1,3);
cout << "filN = " << fillN << endl << endl;
1.4、用系统时间做种子点
RNG rng((unsigned)time(NULL));
当然,用这个要记得加上头函数<time.h>
RNG rng((unsigned)time(NULL)); // 用系统时间作为种子点
double x=rng.uniform((double)0,(double)255);
float y=rng.uniform(0.f,255.f);
int z=rng.uniform((int)0, (int)255 );