Opencv筆記(11)隨機數發生器cv::RNG
阿新 • • 發佈:2022-05-30
一個隨機數物件(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;