zoukankan      html  css  js  c++  java
  • 5. openCV中常用函数学习

    一、前言

    经过两个星期的努力,一边学习,一边写代码,初步完成了毕业论文系统的界面和一些基本功能,主要包括:1 数据的读写和显示,及相关的基本操作(放大、缩小和移动);2 样本数据的选择;3 数据归一化处理;4 绘制光谱曲线;5 获取波段信息。接下来的工作主要是完成遥感影像分类的相关算法。这部分主要是数学计算,尤其是矩阵的相关运算和操作。为此,系统的学习和了解了openCV库中常用的矩阵操作函数,记录下来,方便以后查阅。

    二、openCV函数

    1 reshape

    1 C++: Mat Mat::reshape(int cn, int rows=0) const

    官方解释:能够改变二维数组的通道和形式,并且并不拷贝数据(只是创建矩阵的信息头)。

    参数:int cn : 变换后通道数(0表示保持原通道数);

            int rows : 变换后行数(0表示行数不变),列数更具以上两个参数自动确定。

    对于遥感影像来说,我们常常将通道数据(波段数据)作为特征用作后续数据的处理,为此,我们总希望将通道数变为行或列数,对此我们可以使用如下的方法:

     1 int main(int argc, char *argv[])
     2 {
     3     QCoreApplication a(argc, argv);
     4 
     5     cv::Mat img = cv::imread("F:\paperSystem\openCV\2.tif");
     6     cv::Mat tmpB;
     7     tmpB = img.reshape(1,img.rows*img.cols); // 将通道数变成列数,每一行可表示每一个样本数据
     8     qDebug()<<img.channels()<<tmpB.cols;  //  通道个数
     9     qDebug()<<img.at<cv::Vec3b>(0,0)[0]<<tmpB.at<uchar>(0,0);
    10     qDebug()<<img.at<cv::Vec3b>(0,0)[1]<<tmpB.at<uchar>(0,1);
    11     qDebug()<<img.at<cv::Vec3b>(0,0)[2]<<tmpB.at<uchar>(0,2);
    12     return a.exec();
    13 }

    显示如下:

    2 norm

    1 C++: double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray())  // 计算矩阵src1的范数,主要包括1,2,inf范数 NORM_L1/NORM_L2/NORM_INF
    2 C++: double norm(InputArray src1, InputArray src2, int normType=NORM_L2, InputArray mask=noArray()) // 计算矩阵(src1-src2)的1、2、inf范数 NORM_L1/NORM_L2/NORM_INF (对于normType = NORM_RELATIVE_INF/NORM_RELATIVE_L1/NORM_RELATIVE_L2,则计算(src1-src2)的范数与src1的相应范数之商
    3 C++: double norm(const SparseMat& src, int normType)

    参数:大家都知道

     1 int main(int argc, char *argv[])
     2 {
     3     QCoreApplication a(argc, argv);
     4 
     5     cv::Mat img = cv::imread("F:\paperSystem\openCV\2.tif");
     6     std::vector<cv::Mat>splitImg(img.channels());
     7     cv::split(img,splitImg);
     8 
     9     cv::Mat tmp = img.reshape(1,img.rows*img.cols);
    10 
    11     double norm1_splitImg = cv::norm(splitImg[0],cv::NORM_L1);
    12     double norm2_splitImg = cv::norm(splitImg[0],cv::NORM_L2);
    13     double normInf_splitImg = cv::norm(splitImg[0],cv::NORM_INF);
    14 
    15     double norm1_img = cv::norm(img,cv::NORM_L1);
    16     double norm2_img = cv::norm(img,cv::NORM_L2);
    17     double normInf_img = cv::norm(img,cv::NORM_INF);
    18 
    19     double norm1_tmp = cv::norm(tmp,cv::NORM_L1);
    20     double norm2_tmp = cv::norm(tmp,cv::NORM_L2);
    21     double normInf_tmp = cv::norm(tmp,cv::NORM_INF);
    22 
    23     qDebug()<<norm1_splitImg<<"  "<<norm1_img<<"  "<<norm1_tmp;
    24     qDebug()<<norm2_splitImg<<"  "<<norm2_img<<"  "<<norm2_tmp;
    25     qDebug()<<normInf_splitImg<<"  "<<normInf_img<<"  "<<normInf_tmp;
    26     return a.exec();
    27 }

    显示如下:对于多通道数据是变成单通道后处理的,全部通道数据都加入计算。

    3 normalize

    1 C++: void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray())
    2 C++: void normalize(const SparseMat& src, SparseMat& dst, double alpha, int normType)

    参数: InputArray src:输入的矩阵;

             OutputArray dst:输出矩阵;

             double alpha:将矩阵规则化到aipha,或者是规则化后矩阵的最小值;

             double beta:矩阵元素规则化的上界;当前面alpha规则化到某个值时,不使用

            。。。。。。。

    cv::normalize(splitImg[0],tmp,0,255,cv::NORM_MINMAX);  // 关于这个函数我还不是很理解,将矩阵元素归一化到一个区间可以,可是为何将矩阵的某个范数归一化到一个值却一直不行

    有知道的请帮忙。

    4 reduce

    1 C++: void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1 )

    这个函数功能很强大,可以实现矩阵的列求和、均值、最大、最小。

    参数:int dim:0  --- 行      

            int rtype:  CV_REDUCE_SUM   CV_REDUCE_AVG  CV_REDUCE_MAX  CV_REDUCE_MIN

            int dtypr:默认为原始数据的类型,注意:对于求和和均值之类要改变数据类型,尤其是求和,不然数据大小超过原始数据类型会报错

    5 repeat

    1 C++: void repeat(InputArray src, int ny, int nx, OutputArray dst)
    2 C++: Mat repeat(const Mat& src, int ny, int nx)

    这个代码和Matlab中的repmat一样

    总结:openCV几乎具有MatLab中相似的矩阵操作函数,看来接下来将MatLab的代码转化为opencCV格式不是那么难  哈哈。。。

  • 相关阅读:
    sql中的exists用法
    采用spring的schedule注解配置定时任务
    java通过传入的日期,获取所在周的周一至周日
    forever start app.js 启动node时,服务访问一次后第二次就不能访问了
    linux 安装nginx
    linux 常用命令
    8位字节表示的有符号数范围是-128~127
    极光推送免费版
    tomcat 设置连接数
    查看linux内存使用情况
  • 原文地址:https://www.cnblogs.com/zyore2013/p/4674440.html
Copyright © 2011-2022 走看看