貌似在程序中随机数的使用还是挺频繁的,opencv中也有专门的一个随机数RNG类,它提供了几种操作随机数的方法,它们分别是RandArr、RandInt、RandReal。在使用它们之前需要初始化RNG随机数生成器状态,我们一起来看看这三个函数的参数详情。
RNG
初始化随机数生成器状态
CvRNG cvRNG( int64 seed=-1 );
- seed
- 64-bit 的值用来初始化一个随机序列
函数 cvRNG 初始化随机数生成器并返回其状态。指向这个状态的指针可以传递给函数 cvRandInt, cvRandReal 和 cvRandArr . 在通常的实现中使用一个 multiply-with-carry generator 。
RandArr
用随机数填充数组并更新 RNG 状态
void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );
- rng
- 被 cvRNG 初始化的 RNG 状态.
- arr
- 输出数组
- dist_type
- 分布类型:
- CV_RAND_UNI – 均匀分布
- CV_RAND_NORMAL – 正态分布 或者 高斯分布
- param1
- 分布的第一个参数。如果是均匀分布它是随机数范围的闭下边界。如果是正态分布它是随机数的平均值。
- param2
- 分布的第二个参数。如果是均匀分布它是随机数范围的开上边界。如果是正态分布它是随机数的标准差。
函数 cvRandArr 用均匀分布的或者正态分布的随机数填充输出数组。在下面的例子中该函数被用来添加一些正态分布的浮点数到二维数组的随机位置。
/* let's noisy_screen be the floating-point 2d array that is to be "crapped" */ CvRNG rng_state = cvRNG(0xffffffff); int i, pointCount = 1000; /* allocate the array of coordinates of points */ CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 ); /* arr of random point values */ CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 ); CvSize size = cvGetSize( noisy_screen ); cvRandInit( &rng_state, 0, 1, /* 现在使用虚参数以后再调整 */ 0xffffffff /*这里使用一个确定的种子 */, CV_RAND_UNI /* 指定为均匀分布类型 */ ); /* 初始化 locations */ cvRandArr( &rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) ); /* 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 */ cvRandArr( &rng_state, values, CV_RAND_NORMAL, cvRealScalar(100), // average intensity cvRealScalar(30) // deviation of the intensity ); /* set the points */ for( i = 0; i < pointCount; i++ ) { CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 ); float value = *(float*)cvPtr1D( values, i, 0 ); *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 )) += value; } /* not to forget to release the temporary arrays */ cvReleaseMat( &locations ); cvReleaseMat( &values ); /* RNG state does not need to be deallocated */
RandInt
返回 32-bit 无符号整型并更新 RNG
unsigned cvRandInt( CvRNG* rng );
- rng
- 被 cvRNG 初始化的 RNG 状态,被 RandSetRange (虽然, 后面这个函数对我们正讨论的函数的结果没有什么影响)随意地设置。
函数 cvRandInt 返回均匀分布的随机 32-bit 无符号整型值并更新 RNG 状态。它和 C 运行库里面的 rand() 函数十分相似,但是它产生的总是一个 32-bit 数而 rand() 返回一个 0 到 RAND_MAX (它是 2**16 或者 2**32, 依赖于操作平台)之间的数。
该函数用来产生一个标量随机数,例如点, patch sizes, table indices 等,用模操作可以产生一个确定边界的整数,人和其他特定的边界缩放到 0.. 1可以产生一个浮点数。下面是用 cvRandInt 重写的前一个函数讨论的例子:
/* the input and the task is the same as in the previous sample. */ CvRNG rng_state = cvRNG(0xffffffff); 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; for( i = 0; i < pointCount; i++ ) { CvPoint pt; /* generate random point */ pt.x = cvRandInt( &rng_state ) % size.width; pt.y = cvRandInt( &rng_state ) % size.height; if( valuesLeft <= 0 ) { /* fulfill the buffer with normally distributed numbers if the buffer is empty */ cvRandArr( &rng_state, &normalValueMat, CV_RAND_NORMAL, cvRealScalar(100), cvRealScalar(30) ); valuesLeft = bufferSize; } ((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 ) = 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 */
RandReal
返回浮点型随机数并更新 RNG
double cvRandReal( CvRNG* rng );
- rng
- 被 cvRNG 初始化的 RNG 状态
函数 cvRandReal 返回均匀分布的随机浮点数,范围在 0..1 之间 (不包括 1 )。
评论 (0)