IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]OpenCV 2.x/3.x 随机初始化矩阵

    bendanban发表于 2016-03-31 13:17:27
    love 0

    简介

    在测试算法的时候,或者某些算法需要使用随机数,本文介绍如何使用OpenCV的随机数相关功能。

    主要内容:
    1. cv::RNG类 —— random number generator
    2. cv::randu —— 填充均匀分布随机数
    3. cv::randn —— 填充高斯分布随机数


    cv::RNG

    RNG是OpenCV用来产生随机数的类,他可以产生标量随机数,也可以使用随机数填充Mat对象。当前它只支持均匀分布和高斯分布的随机数。

    用实例展示如何产生标量随机数和填充Mat对象。

    例1,产生标量随机数。

    #include <iostream>
    #include <opencv2/opencv.hpp>
    int main(){
        cv::RNG rnger(cv::getTickCount());
        for (int i = 0; i < 10; i++){
            std::cout << "int    uniform  random number : " << rnger.uniform(0, 10) << std::endl;
            std::cout << "float  uniform  random number : " << rnger.uniform(0.f, 1.f) << std::endl;
            std::cout << "double uniform  random number : " << rnger.uniform(0., 1.) << std::endl;
            std::cout << "double gaussian random number : " << rnger.gaussian(1.) << std::endl;
            std::cout << std::endl;
        }
        return 0;
    }

    例2,用随机数填充矩阵

    #include <iostream>
    #include <opencv2/opencv.hpp>
    int main(){
        cv::RNG rnger(cv::getTickCount());
        int width = 1280, height = 720;
        cv::Mat data;
        cv::Scalar mm, ss;
        // CV_8UC3 uniform distribution
        data.create(height, width, CV_8UC3);
        rnger.fill(data, cv::RNG::UNIFORM, cv::Scalar::all(0), cv::Scalar::all(256));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_8UC1 uniform distribution
        data.create(height, width, CV_8UC1);
        rnger.fill(data, cv::RNG::UNIFORM, cv::Scalar::all(0), cv::Scalar::all(256));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC3 uniform distribution
        data.create(height, width, CV_32FC3);
        rnger.fill(data, cv::RNG::UNIFORM, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC1 uniform distribution
        data.create(height, width, CV_32FC1);
        rnger.fill(data, cv::RNG::UNIFORM, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC3 normal distribution
        data.create(height, width, CV_32FC3);
        rnger.fill(data, cv::RNG::NORMAL, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::meanStdDev(data, mm, ss);
        std::cout << mm << ", " << ss << std::endl;
    
        // CV_32FC1 normal distribution
        data.create(height, width, CV_32FC1);
        rnger.fill(data, cv::RNG::NORMAL, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::meanStdDev(data, mm, ss);
        std::cout << mm << ", " << ss << std::endl;
    
        return 0;
    }

    void RNG::fill(InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange=false );

    mat :待填充的矩阵,他的内存必须已经分配!
    distType :随机数的分布(cv::RNG::UNIFORM或者 cv::RNG::NORMAL)!
    a :分布的第一个参数,如果distType=cv::RNG::UNIFORM,那a是均匀分布的下限。如果distType=cv::RNG::NORMAL 那么a 就是分布的均值。
    b :分布的第二个参数,如果distType=cv::RNG::UNIFORM,那b 是均匀分布的上限(但不包括b)。如果distType=cv::RNG::NORMAL 那么b 就是分布的标准差。

    randu,randn

    randn和randu 可以用来替代 fill函数,唯一的区别是这两个函数使用默认的随机状态(state),而在使用fill的时候,我们用的是cv::getTickCount()来初始化随机状态的。

    实例3,使用randu和randn

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    int main(){
        int width = 1280, height = 720;
        cv::Mat data;
        cv::Scalar mm, ss;
    
        // CV_8UC3 uniform distribution
        data.create(height, width, CV_8UC3);
        cv::randu(data, cv::Scalar::all(0), cv::Scalar::all(256));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_8UC1 uniform distribution
        data.create(height, width, CV_8UC1);
        cv::randu(data, cv::Scalar::all(0), cv::Scalar::all(256));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC3 uniform distribution
        data.create(height, width, CV_32FC3);
        cv::randu(data, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC1 uniform distribution
        data.create(height, width, CV_32FC1);
        cv::randu(data, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::imshow("data", data);
        cv::waitKey();
    
        // CV_32FC3 normal distribution
        data.create(height, width, CV_32FC3);
        cv::randn(data, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::meanStdDev(data, mm, ss);
        std::cout << mm << ", " << ss << std::endl;
    
        // CV_32FC1 normal distribution
        data.create(height, width, CV_32FC1);
        cv::randn(data, cv::Scalar::all(0.), cv::Scalar::all(1.));
        cv::meanStdDev(data, mm, ss);
        std::cout << mm << ", " << ss << std::endl;
    
        return 0;
    }


沪ICP备19023445号-2号
友情链接