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

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