【AndroidStudio NDK之使用OpenCV——第二节】浅谈OpenCV Mat类(上)

一、什么是Mat?

在计算机内存中,数字图像都是以矩阵的形式存储和运算的。而OpenCV中的Mat类就是用于保存图像以及其他矩阵数据的数据结构的。

二、Mat的方法介绍

1.构造方法(如何创建Mat)
 /**
 * Mat(int rows, int cols, int type, void* data);
 * 作用:创建矩阵
 * 
 *【参数:
 *      1.行数。
 *      2.列数。
 *      3.数组类型(图像类型,关于图像类型请看上图列表)
 *      4.图像数据,在Android中一般为数组或Bitmap 】
 * */
 
  // 例如:
  //创建一个 height x  width 的 8 位无符号型 4 通道全 0 的 Mat
    Mat imgData(height, width, CV_8UC4, pixels);

图像类型解释:

   OpenCV中Mat存在各种类型,其中mat有一个type()的函数可以返回该Mat的类型。类型表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为
      CV_<bit_depth>(S|U|F)C<number_of_channels>


1--bit_depth---比特数---代表8bite,16bites,32bites,64bites
      举个例子吧--比如说,
        如果你现在创建了一个存储灰度图片的Mat对象,这个图像的大小为宽高都为
        100,那么,现在这张灰度图片中有10000个像素点,它每一个像素点在内存
        空间所占的空间大小是8bite,8--所以它对应的就是CV_8
        
2--S|U|F--S--代表--signed int----> 有符号整形
          U--代表--unsigned int--> 无符号整形
          F--代表--float---------> 单精度浮点型
          
3--C<number_of_channels>----代表--- 一张图片的通道数,
       例如:
         1--灰度图片--grayImg------ 单通道图像
         2--RGB彩色图像------------ 3通道图像
         3--带Alph通道的RGB图像----- 4通道图像

【1】CV_8UC1---则可以创建---8位无符号的单通道---灰度图片
【2】CV_8UC3---则可以创建---8位无符号的三通道--RGB彩色图像
【3】CV_8UC4---则可以创建---8位无符号的四通道--带透明色的RGB图像

具体的有以下值:

类型C1C2C3C4
CV_8U 0 8 1624
CV_8S 1 9 1725
CV_16U2101826
CV_16S3111927
CV_32S4122028
CV_32F5132129
CV_64F6142230
2. Mat 像素读取方式 ----- at() 、ptr() 、迭代器遍历图像 等
大家都是成年人(老码农)我们先直接讲区别

at()可用來读取和修改某个像素值,通常用來对随机位置的像素进行读写,就效率考量
,並不适合用在循序查访影像所有像素

ptr()函式返回指标,指向图像指定列的首像素,使用时须输入像素位深度和第几列, 
对于一个深度8位的图,我们可用img.ptr(j)指到第j列的第一个像素,接着逐列查访
,最后可查访图像所有像素,这种方法运行速度较at()快,在分辨率大或是重视效率
的地方,是比较好的方法。

迭代器遍历图像:
用迭代器来遍历图像像素,可简化过程降低出错的机会,比较安全,不过效率较低。

其他方式  【略】(有很多种方式自己百度搜吧!不一一例举了!!!)
================================================================
at()函数读取像素:

  Mat  image(height, width, CV_8UC4, pixels);
     for(int i=0; i<image.rows;i++){
        for(int j=0; j<image.cols; j++){
          //随意访问图像中任何一个像素,i表示第i行,j表示该行第j个像素。
          image.at<Vec3f>(i,j)[0]=  ;
        }
     }; 
     
================================================================
ptr()函数读取像素:
 Mat imgData(height, width, CV_8UC4, pixels);
    //指向imgData第一行第一个元素的指针
    uchar *ptr = imgData.ptr(0);
    //找到所有像素点
    for (int i = 0; i < width * height; i++) {
        ptr[4 * i + 0] =   ;//蓝色通道
        ptr[4 * i + 1] =   ;//红色通道
        ptr[4 * i + 2] =   ;//绿色通道
    }

===============================================================
 //迭代器遍历图像:
 
  Mat image(height, width,CV_8UC1); 
  MatIterator_<uchar>Mbegin,Mend;
    //遍历所有像素,设置像素值
	for (Mbegin=image.begin<uchar>(),
	     Mend=image.end<uchar>();Mbegin!=Mend;++Mbegin){
	     
                 *Mbegin=rand()%255;

        } 
3. Mat 类型转换 ---- convertTo
/**
 * convertTo(OutputArray m, int rtype, 
 *           double alpha=1, double beta=0 )const;
 * 
 * 作用:矩阵类型转换
 * 
 * 【参数:
 *       1.输出矩阵(就是修改后的结果矩阵)。
 *       2.输出矩阵的类型
 *       3.尺度变换因子(可选)
 *       4.附加到尺度变换后的值上的偏移量(可选)
 * 
 * 注意:
 *   1.OpenCV的convertTo函数如果第三个参数使用默认的话,就会导致数值只
 *      是类型的改变,但在浮点数表示的颜色空间中,数值范围是0-1.0。
 * 
 *   2.灰度或rgb图像的颜色分量都在0~255之间,
 *     而CV_64FC1取值范围远远不止0~255,需要先归一化成0~1.0。
 *     所以要这样写 convertTo(Mat,CV_64FC1,1/255.0);
 * 
 * */

 例如: 把 CV_32F 转为  CV_8U
  
        //得到一个浮点型的100*100的矩阵
        Mat matTemp = cv::Mat::zeros(100,100,CV_32F); 
        Mat matTemp2;
  
       //把 CV_32F 转为  CV_8U
        matTemp.convertTo(matTemp2, CV_8U); 
        // 注意 在转换过程中有可能数值上会出现一些变化
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值