1. 程式人生 > 其它 >Opencv筆記(11)隨機數發生器cv::RNG

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;