OpenCV(三) Mat像素操作

像素读写

  • Mat作为图像容器,其数据部分存储了图像的像素数据,我们可以通过相关的API来获取图像的数据部分。在获取图像数据的时候,知道Mat的类型与通道数目至关重要,根据Mat的类型与通道数目,开辟适当大小的内存空间,然后通过get方法就可以循环实现每个像素点值的读取、修改,然后再通过put方法修改与Mat对应的数据部分即可

  • 常见的Mat的像素读写get与put方法支持如下表。表中是当前OpenCV支持读取图像的方法、将像素值写入到Mat对象中使用与每个get方法相对于的put方法即可。根据开辟的缓存区域data数据的大小,读写像素即可以每次从Mat中读取一个像素点数据。或者可以每次从Mat中读取一行像素数据,还可以一次从Mat中读取所有全部数据。

    方法 支持类型
    double[] get(int row,int col) 以下全部
    int get(int row,int col,double[] data) CV_64FC1~CV_64FC4
    int get(int row,int col,float[] data) CV_32FC1~CV_32FC4
    int get(int row,int col,int[] data) CV_32SC1~CV_32SC4
    int get(int row,int col,short[] data) CV_16SC1~CV_16SC1
    int get(int row,int col,byte[] data) CV8UC1~CV_8UC1
  • 从Mat 中读取一个像素点数据

     byte[] bytes =new byte[channels];
            int b,g,r;
            for (int i = 0; i <rows ; i++) {
                for (int j = 0; j < cols; j++) {
                    mRgba.get(rows,cols,bytes);
                    b=bytes[0]&0xff;
                    g= bytes[1]&0xff;
                    r =bytes[2]&0xff;
    
                    b = 255-b;
                    g = 255-g;
                    r = 255-r;
    
                    bytes[0]= (byte) b;
                    bytes[1]= (byte) g;
                    bytes[2]= (byte) r;
                    mRgba.put(rows,cols,bytes);
                }
            }
        
    	//频繁访问JNI而效率低下,但是内存需求小
         
    
  • 从Mat中每次读取一行像素数据

    byte[] data = new byte[channels*width];
    int pv;
    for(int i=0;i<height;i++){
         
         
        src.get(i,0,data);
        for(int j=0;col<data.length;j++){
         
         
            pv = data[j]&0xff;
            pv  = 255-pv;
            data[j]=(byte)pv;
        }
        src.put(i,0,data)
    }
    //相比第一种方式有所提高,但是内存增加
    
    
  • 从Mat中一次读取全部数据,完整数据长度T=图像宽 * 图像高 * 通道数

     byte[] data = new byte[width*height*channels];
            int pv;
            mRgba.get(0,0,data);
            for (int i = 0; i <data.length ; i++) {
         
         
                pv = data[i]&0xFF;
                data[i]=(byte) (250-pv);
            }
            mRgba.put(0,0,data);
    //调用jni次数少,效率也高,但是对于高分辨图像容易OOM
    

图像通道与均值方差计算

  • 图像中通道数目的多少可以通过Mat对象channels()进行查询获取。对于多通道图像,Mat提供Api方法可以把它分为多个单通道图像;同样对于多个单通道的数据也可以组合成一个多通道的图像。此外,OpenCV还提供了计算机图像每个通道像素值与标准方差的API方法,通过它们可以计算得到图像的像素平均值与方差,根据平均值可以实现基于平均值的二值图像分割,根据标准方差可以找到空白图像或者无效图像。

图像通道分离与合并

  • 图像通道数通过Mat的channels()获取,如果通道数目大于1,那么久调用split方法就可以实现通道分离,通过merge方法就可以实现通道合并。

    split(Mat m,List<Mat> mv)//通道分离
    //m:表示输入多通道图像
    //mv:表示分离之后多个单通道图像,mv的长度与m的通道数目一致。
        
    merge(List<Mat>mv,Mat dst)//通道合并
    //mv:表示多个待合并的单通道图像
    //dst:表示合并之后生成的多通道图像    
        
    //上面两个方法都来自Core模块,Core模块只要包含一些Mat操作与基础矩阵数学功能。    
    

均值与标准方差计算与应用

  • OpenCV Core模块中实现了这类API

    meanStdDev(Mat src,MatOfDo
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值