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 */


<think>嗯,用户想了解OpenCV中的RNG函数的功能和用法。首先,我需要回忆一下RNG在OpenCV中的作用。RNG应该是随机数生成器,用于生成各种随机数,比如整数、浮点数,或者填充矩阵。那它的主要功能应该包括生成均匀分布和正态分布的随机数,可能还有设置种子之类的操作。 接下来,用户可能需要具体的例子,比如如何初始化RNG对象,生成不同类型的随机数,以及实际应用场景。比如在图像处理中,生成噪声或者随机颜色都会用到RNG。记得要检查引用的资料是否符合,用户提供的引用里提到了Mat类,线程安全,引用计数这些,可能和RNG的使用场景相关,比如多线程中使用RNG是否安全? 然后,我需要确认RNG的成员函数,比如uniform、gaussian、fill等。这些函数的具体参数和用法可能需要详细说明。比如,uniform函数生成指定范围的随机数,gaussian生成符合正态分布的数,fill用随机数填充矩阵。 还要注意用户提到的官方文档和示例代码,需要确保给出的代码是正确的,符合C++的语法,并且注释清晰。例如,初始化RNG对象时,可以使用默认构造函数或者指定种子,生成随机整数、浮点数,填充矩阵,以及生成高斯噪声等。 另外,用户的问题可能涉及RNG的线程安全性。根据引用[1],OpenCV的实现是可重入的,可以在不同线程使用不同的实例,但同一个RNG实例在多线程中可能需要加锁。这点需要提到,避免用户在多线程环境下出错。 最后,生成的相关问题需要考虑用户可能进一步想知道的内容,比如种子设置的影响,与其他随机数库的区别,性能优化,或者实际应用案例。这些问题可以帮助用户更深入地理解RNG的使用。</think>### OpenCV中RNG函数的功能与用法 #### 一、功能说明 OpenCV中的`cv::RNG`类是用于生成伪随机数的工具,支持均匀分布、正态分布等随机数生成,常用于数据增强、噪声模拟、算法初始化等场景。其核心功能包括: 1. **生成均匀分布的整数或浮点数**:例如在指定区间$[a, b)$内生成随机数[^1]。 2. **生成正态分布的随机数**:通过高斯分布参数$(\mu, \sigma)$生成随机值。 3. **填充矩阵**:快速生成随机数填充`cv::Mat`对象,适用于生成测试数据或噪声[^2]。 4. **可重复性**:通过设定种子值,可复现随机序列,便于调试[^3]。 #### 二、基本用法 ##### 1. 初始化RNG对象 ```cpp #include <opencv2/opencv.hpp> // 默认构造函数(基于时间戳种子) cv::RNG rng; // 指定种子值(保证随机序列可复现) cv::RNG rng_fixed(12345); ``` ##### 2. 生成随机数 ```cpp // 生成[0, 100)的整数 int rand_int = rng.uniform(0, 100); // 生成[0.0, 1.0)的浮点数 double rand_double = rng.uniform(0.0, 1.0); // 生成均值为0、标准差为1的高斯分布数 double gaussian = rng.gaussian(1.0); ``` ##### 3. 填充矩阵 ```cpp // 创建3x3矩阵,填充[0, 255)的整数 cv::Mat mat(3, 3, CV_8UC1); rng.fill(mat, cv::RNG::UNIFORM, 0, 256); ``` #### 三、应用示例 ##### 为图像添加高斯噪声 ```cpp cv::Mat addGaussianNoise(const cv::Mat& src, double sigma) { cv::Mat noise(src.size(), src.type()); cv::RNG rng; rng.fill(noise, cv::RNG::NORMAL, 0, sigma); return src + noise; } ``` #### 四、注意事项 1. **线程安全**:每个线程应使用独立的`RNG`实例(OpenCV的线程安全设计允许跨线程使用不同实例)[^1]。 2. **性能优化**:批量生成数据时优先使用`fill()`而非多次调用`uniform()`。 3. **种子管理**:调试时固定种子,生产环境使用动态种子。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值