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;

 

posted @ 2022-05-30 21:19  湾仔码农  阅读(854)  评论(0编辑  收藏  举报