OpenCV学习入门(四):RNG 伪随机问题

在我的上一篇博客《OpenCV学习入门(三):kmeans原理及代码 》中调试kmeans时发现一个问题:每次运行时,以下两行代码

int clusterCount = rng.uniform(2, MAX_CLUSTERS + 1);		
int sampleCount = rng.uniform(1, 1001);

生成的两个变量结果是一样的!于是我就研究了一下随机类RNG,最终找到了问题的原因。

在解释原因之前先了解一下伪随机数,百度里面对计算机产生随机数的过程有详细解释,看不懂也没关系,关于伪随机数记住下面一句话即可:

计算机的伪随机数是由随机种子根据一定的计算方法计算出来的数值。所以,只要计算方法一定,随机种子一定,那么产生的随机数就是固定的
注意到程序中有如下一行代码
RNG rng(12345); //随机数产生器
OpenCV里RNG类构造函数初始化为固定的值后随机种子也是固定的,所以在相同的平台环境下,编译后每次运行它,显示的随机数是一样的。
我们来做一个小测试:
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <ctime>
#define n 5
using namespace cv;
using namespace std;
int main()
{
	RNG rng(12345);
	cout << "Generate 5 random numbers within [1,1000)" << endl;
	for (int i = 0; i < n; ++i)
	{
		cout << rng.uniform(1, 1000) << endl;
	}
}

构造函数rng初始化为12345,程序运行后,每次生成的“随机数”都一样,如下图1:
OpenCV学习入门(四):RNG 伪随机问题_第1张图片
图1:rng(12345)结果
更改构造函数rng初始化为1234,每次运行生成的 “随机数”仍然都一样,如下图2:

图2:rng(1234)结果
继续更改构造函数rng初始化为123,每次运行生成的 “随机数”仍然都一样,如下图3:

图3:rng(123)结果
好吧,看来确实如我所料的,RNG类构造函数初始化为固定的值后随机种子也是固定的,那怎样才能不需要更改初始化值,同样的代码,同样的编译环境,每次生成的结果都是随机的呢?
解决办法就是利用系统时间初始化一个随机种子,具体代码如下:
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <ctime>
#define n 5
using namespace cv;
using namespace std;
int main()
{
	RNG rng((unsigned)time(NULL)); // initialize with the system time
	cout << "Generate 5 random numbers within [1,1000)" << endl;
	for (int i = 0; i < n; ++i)
	{
		cout << rng.uniform(1, 1000) << endl;
	}
}

编译后连续运行3次的结果如下图4:

OpenCV学习入门(四):RNG 伪随机问题_第2张图片
图4 rng((unsigned)time(NULL))
到此,相同的程序每次运行生成的才是我们要的随机数

你可能感兴趣的:(入门,opencv,RNG,伪随机)