Opencv笔记(11)随机数发生器cv::RNG
一个随机数对象(RNG)用来产生随机数的伪随机序列。这样做的好处是你可以方便地得到多重伪随机数流。一旦随机数发生器创建,就会开始按需提供产生随机数的“服务”,无论是平均分布还是正态分布。
RNG& theRNG(void);
theRNG()函数为调用它的线程返回一个默认的随机数生成器。OpenCV自动为每一个执行中的线程创建一个cv::RNG的实例,因此再多线程中非常安全。如果你只想要一个数或者只初始化一个数组,用cv::randu()或者cv::randn()。
void setRNGSeed(int seed);//设置随机数序列的种子
cv::RNG::operator T()
下面是重载的类型转换操作符,可以将RNG对象转换成任何你想要的类型。
operator uchar(); /** @overload */ operator schar(); /** @overload */ operator ushort(); /** @overload */ operator short(); /** @overload */ operator unsigned(); /** @overload */ operator int(); /** @overload */ operator float(); /** @overload */ operator double();
产生整型数的时候,它们将覆盖整个可能的取值范围。当产生浮点数的时候,它的范围始终是{0.0,1.0]。
RNG rng = theRNG(); cout << "An integer: " << int(rng) << endl; cout << "An float: " << float(rng) << endl;
cv::RNG::operator()
unsigned operator ()();//返回随机值在0-UINT_MAX之间 unsigned operator ()(unsigned N);//返回值在0-(N-1)之间
cv::RNG::uniform()
int uniform(int a, int b); float uniform(float a, float b); double uniform(double a, double b);
函数在[a,b)的范围内产生平均分布的随机数。
float x = rng.uniform(0, 1);
注意,上面这个情况只能得到0.f,因为0和1是整型数,在[0,1)范围内只有0,要想得到浮点数,应使用
float x = rng.uniform(0.f, 1.f);
主要是在YOLOv5的部署中,不同类别用不同的颜色,当类别很多时,随机产生num_classes个颜色比较方便.
RNG rng = theRNG(); vector<Scalar> colors; for (int i = 0; i < 80; i++){ int b = rng.uniform(0, 255); int g = rng.uniform(0, 255); int r = rng.uniform(0, 255); colors.push_back(Scalar(b, g, r));
cv::RNG::gaussian()
double gaussian(double sigma); void fill( InputOutputArray mat, //输入数组,值会被覆盖
int distType, //分布的类型(gaussian or uniform)
InputArray a, //min(uniform) or mean(Gaussian)
InputArray b, //max(uniform) or std-deviation(Guassian)
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 只针对均匀分布有效。当为真的时候,会先把产生随机数的范围变换到数据类型的范围,再产生随机数。如果为假,会先产生随机数,再进行截断到数据类型的有效区间
RNG rng = theRNG(); double a = rng.gaussian(2.0); cout << a << endl; Mat b(1, 10, CV_8UC1); rng.fill(b, RNG::UNIFORM, 1, 10); cout << b << endl;