OpenCV中的Rand隨機數函數簇學習

因爲學習卡爾曼濾波,所以發現了OpenCV居然還能發生隨機數的。特意把隨機數函數簇拿出來學習下。

注:正態分佈曲線的對稱軸是正態樣本的平均值;樣本的平均值增大,曲線向右側平移,樣本的平均值減小,曲線向左側平移。





正態樣本的標準差越大,則正態分佈曲線越平坦,峯值越小。 

RandInit

Initializes random number generator state

void cvRandInit( CvRandState* state, double param1, double param2, int seed,


                 int distType=CV_RAND_UNI );


state
Pointer to the initialized random number generator state structure.傳入結構CvRandState,必須,
param1
The first distribution parameter. In case of uniform distribution it is the inclusive lower boundary of random numbers range. In case of normal distribution it is the standard deviation of random numbers.
在平均分佈是下限,在正態分佈是標準差
param2
The second distribution parameter. In case of uniform distribution it is the exclusive upper boundary of random numbers range. In case of normal distribution it is the mean value of random numbers.
在平均分佈是上限,正態分佈是平均值
seed
Initial 32-bit value to start a random sequence.
種子數,可以用+-1代替,也可以用GetTickCount()代替。
distType
Distribution type:
CV_RAND_UNI - uniform distribution平均分佈
CV_RAND_NORMAL - normal or Gaussian distribution正態分佈,高斯分佈

The function cvRandInit initializes the state structure that is used for generating uniformly distributed numbers in the range [param1, param2) or normally distributed numbers with param1 mean and param2 standard deviation. The parameters are set for all the dimensions simultaneously - resemble that RNG has separate parameters for each of 4 dimensions. A multiply-with-carry generator is used.

RandSetRange RandInit用於設置全局,可以指定其中的一個通道用其它的方式發生隨機數。可見Rand可以發生N個通道的CvArr*

Changes the range of generated random numbers without touching RNG state

void cvRandSetRange( CvRandState* state, double param1, double param2, int index=-1 );


state
State of random number generator (RNG).
param1
New lower boundary/deviation of generated numbers.
param2
New upper boundary/mean value of generated numbers.
index
The 0-based index of dimension/channel for which the parameter are changed, -1 means changing the parameters for all dimensions.

The function cvRandSetRange changes the range of generated random numbers without reinitializing RNG state. It is useful if a few arrays of different types need to initialized with random numbers within a loop. Alternatively, you may have a separate generator for each array, but then you should provide several uncorrelated initialization seeds - one per each generator.

 

Rand 發生隨機數到CVArr* cvbRand產生隨機數到數組[]

Fills array with random numbers and updates the RNG state

void cvRand( CvRandState* state, CvArr* arr );


state
RNG state initialized by RandInit and, optionally, customized by RandSetRange .
arr
The destination array.

The function cvRand fills the destination array with uniformly or normally distributed random numbers within the pre-set range and updates RNG state. In the sample below this and two functions above are used to put a few normally distributed floating-point numbers to random locations within a 2d array

/* let's noisy_screen be the floating-point 2d array that is to be "crapped" */


CvRandState rng_state;


int i, pointCount = 1000;


/* allocate the array of coordinates of points */


CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 );


/* array of random point values */


CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 );


CvSize size = cvGetSize( noisy_screen );





cvRandInit( &rng_state,


            0, 1, /* use dummy parameters now and adjust them further */


            0xffffffff /* just use a fixed seed here */,


            CV_RAND_UNI /* specify uniform type */ );





/* customize the RNG to use it for initialiazing locations:


   the 0-th dimension is used for x's and the 1st - for y's */


cvRandSetRange( &rng_state, 0, size.width, 0 );


cvRandSetRange( &rng_state, 0, size.height, 1 );





/* initialize the locations */


cvRand( &rng_state, locations );





/* modify RNG to make it produce normally distributed values */


rng_state.disttype = CV_RAND_NORMAL;


cvRandSetRange( &rng_state,


                30 /* deviation */,


                100 /* average point brightness */,


                -1 /* initialize all the dimensions */ );


/* generate values */


cvRand( &rng_state, values );





/* set the points */


for( i = 0; i < pointCount; i++ )


{


    CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 );


    float value = *(float*)cvPtr1D( values, i, 0 );


    cvSetReal2D( noisy_screen, pt.y, pt.x, value );


}





/* not to forget to release the temporary arrays */


cvReleaseMat( &locations );


cvReleaseMat( &values );





/* cvRandInit does not allocate any memory, so there is no need


  (and no function) to deinitialize it */








RandNext 產生單個隨機數

Returns 32-bit unsigned integer and updates RNG

unsigned cvRandNext( CvRandState* state );

state
RNG state initialized by RandInit and, optionally, customized by RandSetRange (though, the latter function does not affect on the discussed function outcome).

The function cvRandNext returns uniformly-distributed (regardless of the RNG distribution type settings) "plain" integer random number and updates RNG state. It is similar to rand() function from C runtime library, but it always generates 32-bit number whereas rand() returns a number in between 0 and RAND_MAX which is 2**16 or 2**32, depending on the platform.

The function is useful for generating scalar random numbers, such as points, patch sizes, table indices etc, where integer numbers of a certain range can be generated using modulo operation and floating-point numbers can be generated by scaling to 0..1 of any other specific range. Here is the example from the previous function discussion rewritten using cvRandNext :

/* the input and the task is the same as in the previous sample. */ CvRandState rng_state; int i, pointCount = 1000; /* ... - no arrays are allocated here */ CvSize size = cvGetSize( noisy_screen ); /* make a buffer for normally distributed numbers to reduce call overhead */ #define bufferSize 16 float normalValueBuffer[bufferSize]; CvMat normalValueMat = cvMat( bufferSize, 1, CV_32F, normalValueBuffer ); int valuesLeft = 0; /* initialize RNG to produce normally distributed values. Coordinates will be uniformly distributed within 0..2**32 anyway as they are generated using cvRandNext */ cvRandInit( &rng_state, 100, 30, 0xffffffff /* just use a fixed seed here */, CV_RAND_NORMAL /* specify uniform type */ ); for( i = 0; i < pointCount; i++ ) { CvPoint pt; /* generate random point */ pt.x = cvRandNext( &rng_state ) % size.width; pt.y = cvRandNext( &rng_state ) % size.height; if( valuesLeft <= 0 ) { /* fulfill the buffer with normally distributed numbers if the buffer is empty */ cvRand( &rng_state, &normalValueMat ); valuesLeft = bufferSize; } cvSetReal2D( noisy_screen, pt.y, pt.x, normalValueBuffer[--valuesLeft]); } /* there is no need to deallocate normalValueMat because we have both the matrix header and the data on stack. It is a common and efficient practice of working with small, fixed-size matrices */

 

轉自http://blog.csdn.net/darkread/article/details/5671966

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章