我们先从在C/C++中的随机数与随机种子说起。
rand()、srand()
rand()可以生成一个0~RAND_MAX之间的一个随机数,返回值是一个unsigned int类型值。rand函数不是真正的随机数生成器,而srand()会设置供rand()使用的随机数种子。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。而使用同种子相同的数调用 rand()会导致相同的随机数序列被生成。
srand函数是随机数发生器的初始化函数。原型:void srand(unsigned int seed);srand和rand()配合使用产生伪随机数序列。
而如果用户在rand()前没有调用过srand(),那么系统默认将1作为伪随机数的初始 值。如果给了一个定值,那么每次rand()产生的随机数序列都是一样的。
所以为了避免上述情况的发生我们通常用srand((unsigned)time(0))或者srand((unsigned)time(NULL))来 产生种子。如果仍然觉得时间间隔太小,可以在(unsigned)time(0)或者(unsigned)time(NULL)后面乘上某个合适的整数。例如,srand((unsigned)time(NULL)*10)另外,关于time_t time(0):time_t被定义为长整型,它返回从1970年1月1日零时零分零秒到目前为止所经过的时间,单位为秒。NULL的值就是0。规定0可以赋值给任意指针,除0以外的任何数值都不能赋值给指针。
关于time函数介绍如下。
time()
time() 是指返回自 Unix 纪元(January 1 1970 00:00:00 GMT)起的当前时间的总秒数的函数,主要用来获取当前的系统时间,返回的结果是一个time_t类型。
time_t time(time_t *t);
如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。
有了以上的知识介绍,我们就可以顺利地过渡到OpenCV。
在OpenCV中,有个RNG类,用它来产生随机数。可以使用RNG的构造函数,来创建随机数生成器的对象。代码如下:
RNG rng(12345); //指定随机种子位12345
固定的随机种子,从而产生固定的随机数序列。那么如何让每次生成的随机数序列是不一样的呢?
没错,就是使用C/C++中相同的思路,使用系统时间(1970年1月1日零时零分零秒,到目前为止所经历德 总秒数)来作为随机种子。代码如下:
RNG rng((unsigned)time(NULL)); //NULL写成0是一样的,NULL就是0
uniform()
关于RNG类,再提到一个它的函数,uinform()
uniform:指定了一个在a和b范围的均匀分布的随机数
rng.uniform(1,255); //返回一个在1~255范围内的随机数
例如uniform在颜色随机上的应用。
Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)); //任意值
关于随机数指定范围,可以用随机数取余来解决。
比如,rand() % 255 ,那么就会返回在0~255范围内的一个随机数
为啥?
因为任何被除数除以一个数,余数肯定小于被除数。