cvRNG基本随机数

http://hi.baidu.com/bingshanzhu/blog/item/fefccce7d817af3fb938208d.html

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib,"cv200.lib")
#pragma comment(lib,"cxcore200.lib")
#pragma comment(lib,"highgui200.lib")
#pragma comment(lib,"cvaux200.lib")

//随机数简单示例
int _tmain(int argc, _TCHAR* argv[])
{
    CvRNG rng;
    rng= cvRNG(cvGetTickCount());
    for (int i= 0;i<10;i++)
    {
        printf("%d/n",cvRandInt(&rng)%256);//如果%256出来的将会是0~255的正整数
        printf("%.2f/n",cvRandReal(&rng));
    }
    printf("Tick Frequency= %f/n",cvGetTickFrequency());
    system("pause");
    return 0;
}

cvGetTickCount()
返回64位长整数的时间数据,在OpenCV是为CvRNG设置的专用种子

 

cvGetTickFrequency()

返回系统时钟频率

 

cvRNG()

跟一般的C语言srand()使用方法一样,要先给它一个种子,但srand()用到的是unsigned int的32位种子范围,而cvRNG()用的是64位长整数种子。初始化CvRNG资料结构,假如seed给0,它将会自动转成-1。
cvRNG(64位种子)

 

cvRandInt()

返回均匀分布32位的随机数均匀分布为统计学上的专有名词,表示长时间下所有数字出现的概率都是一样的,而cvRandint()在opencv里使用的公式

temp = (uint64)(unsigned)temp*1554115554 + (temp >> 32);

这个公式的名称叫Multiply-with-carry (MWC) generator,有兴趣的话可以在网络上找“随机数产生器”,Multiply-with-carry是将64位的种子去产生32位的随机数。
unsigned cvRandInt(CvRNG资料结构)

 

cvRandReal()

返回均匀分布,0~1之间的随机小数,cvRandReal()的公式则是用
cvRandInt(rng)*2.3283064365386962890625e-10
的方法,其实就是cvRandInt(rng)*2^(-32),也就是将cvRandInt()随机出来的结果(32位除以2的三十二次方,因此,出现的结果将会是0~1之间的小数,也就是随机0~1之间。
double cvRandReal(CvRNG资料结构)

图像添加噪声【OpenCV学习笔记1】
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
知道了上面的以后,我的需求是:  随机数可能重复. 因此希望使用一个随机数做种子用它来确定一组"无规律"的自然数序列, 并且在这个序列中不会出现重复的自然数. 即 随机数的产生不会出现重复.
方法1. 若重复,再次生成。
逐个产生这些随机数,每产生一个,都跟前面的随机数比较,如果重复,就重新产生:

这种算法越到后面,遇到已使用过的元素的可能性越高,重复次数就越多,但是当m较小时还是很好的:)

方法2.

算法四(1)

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

  a[i]=i+1;

for (i=n-1;i>0;i--)

{w=rand()%i;

 t=a[i];

 a[i]=a[w];

 a[w]=t;

}

这个算法很不错,有人会怀疑其随机性,但个人认为是没问题的,首先第二行按顺序用0到n填满整个数组;第三行,是随机产生从0到n-2个数组下标,把这个下标的元素值跟n-1下标的元素值交换,一直进行到下标为1的元素。因此它只需要遍历一次就能产生全部的随机数。

上述算法参考: c语言中的随机函数分析与生成m个不重复随机数算法比较 http://s99f.blog.163.com/blog/static/35118365200811196445340/
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
同样精彩的一篇文章:

CvRNG,RNG代表的意思就是Random Number Generation,隨機數產生,隨機的部份實際上用起來很簡單,但原理的部份就稍微難一些了,基本的函式為cvRNG(),初始化資料結構,cvRandInt(),32bits隨機及浮點數隨機的cvRandReal(),以下程式碼實作.

簡單的隨機程式製作1
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
     CvRNG rng;
     rng = cvRNG(cvGetTickCount());
    for(int i=0;i<100;i++)
     {
         printf("%d/n",cvRandInt(&rng));
     }
     printf("The Tick Frequency is %f/n",cvGetTickFrequency());
     system("pause");
}

 

 

這邊用cvGetTickCount()當種子與C語言time()不同的是,它雖然同樣用時間產生種子,但是它用的是int64長整數型別,而time()則是要看機器而定32位元電腦用32bits,64位元電腦則用64bits.這個程式產生了100個有正有負隨機均勻分佈的整數,cvRandInt()產生的是32bit隨機的數,用int去接的話會介於-2147483648~2147483647之間,而用unsign int去接的話會是0~4294967295,而printf()裡"%d"出來的型別是int,如果用printf("%d/n",cvRandInt(&rng)%256)的話出來的將會是0~255的正整數.

改成cvRandInt(&rng)%256之後

 

 

簡單的隨機程式製作2
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
     CvRNG rng;
     rng = cvRNG(cvGetTickCount());
    for(int i=0;i<100;i++)
     {
         printf("%.2f/n",cvRandReal(&rng));
     }
     system("pause");
}

執行結果:

 

這裡cvRandReal()是拿cvRandInt()的結果乘以二的負三十二次方,因此兩個數會被轉成double去做除法運算而變成浮點數隨機的均勻分佈,如果這邊將printf("%.2f/n",cvRandReal(&rng))改成printf("%d/n",cvRandReal(&rng))亦會出現一堆整數數字,但會因為變數格式的關係隨機的意義將會失焦,因此,這邊程式不該用"%d"來列印,這個部份就要參考計算機組織與設計的計算機算數的部份.

cvGetTickCount()
回傳長整數64bits的時間數據,在OpenCV是為CvRNG而設的的專用種子.

cvGetTickFrequency()
回傳系統時脈頻率.

cvRNG()
跟一般C語言的srand()使用方法一樣,要先給它一個種子,但srand()用到的是unsigned int的32bits的種子範圍,而cvRNG()用的是LONGLONG型態,64bits大小的長整數種子,LONGLONG這個變數型別是在windows.h底下宣告的,也可以用long long表示.這邊初始化CvRNG資料結構,假如seed給0的話,它將會自動轉成-1.
cvRNG(64bits種子的數字)

cvRandInt()
傳回均勻分佈(Uniform Distribution),32bits的隨機數,均勻分佈為統計學上的專有名詞.表示長時間下所有數字出現的機率都是一樣的,而cvRandInt()在OpenCV裡使用的公式是

temp = (uint64)(unsigned)temp*1554115554 + (temp >> 32);

這公式(演算法)的名稱叫做Multiply-with-carry (MWC) generator,有興趣的話可以在網路上找"隨機數產生器"(Random Number Generator)可以找到一些資料,Multiply-with-carry是將64bits的種子去產生32bits的隨機數
unsigned cvRandInt(CvRNG資料結構)

cvRandReal()
傳回均勻分佈,0~1之間的隨機小數.cvRandReal()的公式則是用

cvRandInt(rng)*2.3283064365386962890625e-10

的方法,其實就是cvRandInt(rng)*2^(-32),也就是將cvRandInt()隨機出來的結果(32bits)除以2的三十二次方,因此,出現的結果將會是0~1之間的小數,也就是機率0~1之間.
double cvRandReal(CvRNG資料結構)


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值