让代码更简单

OpenCV随机数RNG类函数详解

重要:本文最后更新于2018-12-20 09:08:59,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

貌似在程序中随机数的使用还是挺频繁的,opencv中也有专门的一个随机数RNG类,它提供了几种操作随机数的方法,它们分别是RandArrRandIntRandReal。在使用它们之前需要初始化RNG随机数生成器状态,我们一起来看看这三个函数的参数详情。

OpenCV

OpenCV随机数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 打赏

评论 (0)

登录后评论
QQ咨询 邮件咨询 狗哥推荐