2008年6月27日 星期五

OpenCV隨機的實作-基本隨機的應用

CvRNG,RNG代表的意思就是Random Number Generation,隨機數產生,隨機的部份實際上用起來很簡單,但原理的部份就稍微難一些了,基本的函式為cvRNG(),初始化資料結構,cvRandInt(),32bits隨機及浮點數隨機的cvRandReal(),以下程式碼實作.

簡單的隨機程式製作1
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
    CvRNG rng;
    rng = cvRNG(cvGetTickCount());
    for(int i=0;i<100;i++)
    {
        printf("%d\n",cvRandInt(&rng));
    }
    printf("The Tick Frequency is %f\n",cvGetTickFrequency());
    system("pause");
}

執行結果:


這邊用cvGetTickCount()當種子與C語言time()不同的是,它雖然同樣用時間產生種子,但是它用的是int64長整數型別,而time()則是要看機器而定32位元電腦用32bits,64位元電腦則用64bits.這個程式產生了100個有正有負隨機均勻分佈的整數,cvRandInt()產生的是32bit隨機的數,用int去接的話會介於-2147483648~2147483647之間,而用unsign int去接的話會是0~4294967295,而printf()裡"%d"出來的型別是int,如果用printf("%d\n",cvRandInt(&rng)%256)的話出來的將會是0~255的正整數.

改成cvRandInt(&rng)%256之後


簡單的隨機程式製作2
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
    CvRNG rng;
    rng = cvRNG(cvGetTickCount());
    for(int i=0;i<100;i++)
    {
        printf("%.2f\n",cvRandReal(&rng));
    }
    system("pause");
}

執行結果:


這裡cvRandReal()是拿cvRandInt()的結果乘以二的負三十二次方,因此兩個數會被轉成double去做除法運算而變成浮點數隨機的均勻分佈,如果這邊將printf("%.2f\n",cvRandReal(&rng))改成printf("%d\n",cvRandReal(&rng))亦會出現一堆整數數字,但會因為變數格式的關係隨機的意義將會失焦,因此,這邊程式不該用"%d"來列印,這個部份就要參考計算機組織與設計的計算機算數的部份.

cvGetTickCount()
回傳長整數64bits的時間數據,在OpenCV是為CvRNG而設的的專用種子.

cvGetTickFrequency()
回傳系統時脈頻率.

cvRNG()
跟一般C語言的srand()使用方法一樣,要先給它一個種子,但srand()用到的是unsigned int的32bits的種子範圍,而cvRNG()用的是LONGLONG型態,64bits大小的長整數種子,LONGLONG這個變數型別是在windows.h底下宣告的,也可以用long long表示.這邊初始化CvRNG資料結構,假如seed給0的話,它將會自動轉成-1.
cvRNG(64bits種子的數字)

cvRandInt()
傳回均勻分佈(Uniform Distribution),32bits的隨機數,均勻分佈為統計學上的專有名詞.表示長時間下所有數字出現的機率都是一樣的,而cvRandInt()在OpenCV裡使用的公式是

temp = (uint64)(unsigned)temp*1554115554 + (temp >> 32);

這公式(演算法)的名稱叫做Multiply-with-carry (MWC) generator,有興趣的話可以在網路上找"隨機數產生器"(Random Number Generator)可以找到一些資料,Multiply-with-carry是將64bits的種子去產生32bits的隨機數
unsigned cvRandInt(CvRNG資料結構)

cvRandReal()
傳回均勻分佈,0~1之間的隨機小數.cvRandReal()的公式則是用

cvRandInt(rng)*2.3283064365386962890625e-10

的方法,其實就是cvRandInt(rng)*2^(-32),也就是將cvRandInt()隨機出來的結果(32bits)除以2的三十二次方,因此,出現的結果將會是0~1之間的小數,也就是機率0~1之間.
double cvRandReal(CvRNG資料結構)



0 意見:

Copyright 2008-2009,yester