美文网首页
OpenCV数字图像知识

OpenCV数字图像知识

作者: BrotherTree | 来源:发表于2018-06-04 23:29 被阅读0次

    数字图像
    我们的图像是存储在存储器里面 ,那么存储器存储格式归根结底不外乎0和1。
    再往高点也就是数据的基本类型,以0和1去存储,每一个内存单元可以存储8位的二进制数

    0000 0000
    

    再往高走,图像也可以看成一个数组,数组存的就是一个一个的像素。

    数组[] = 像素的集合
    

    数字图像在存储器里面是如何存储的呢?


    image.png image.png

    三通道RGB可以表示多少种颜色呢?

    16 * 16 * 16 = 4096(4位)
    256 * 256 * 256  = 16777216(8位),即 1600W色
    

    人眼可以识别的是 32 * 32 * 32 = 1048576种
    我们可以使用RGB来表示几乎所有的颜色,为何还有单通道的存在呢?因为单通道内存开销小。

    下面我们看下Bitmap.Config

    public static enum Config {
            ALPHA_8,// 只有明暗度(透明度),每一个像素占8位
            ARGB_4444,// 4通道,一个像素的每个通道占4位,一共16位
            ARGB_8888,// 4通道,一个像素的每个通道占8位,一共32位
            HARDWARE,// 硬件表示,只有01010101
            RGBA_F16,// float类型单通道表示16位的数
            RGB_565;// 3通道   R占5位  G占6位  B占5位  共16位
            private Config() {
            }
        }
    

    颜色深度

    一个像素所占的数据位数,比如ARGB_8888,就是32位深度的图片
    

    图像模式

    1. 位图模式
        只占1位深度,只有黑白两种颜色(黑白打印机)
    2. 灰度模式
        8位深度,可以表示0-255之间的不同灰度(黑灰白图片)
    3. 双色调模式
        只有一个通道,可以表现色彩,是单色调、双色调、三色调和四色调的统称
    4. RGB模式
        24位深度 真彩
    5. CMYK模式
        印刷专业使用
    6. Lab模式
        24位深,L亮度 a色彩分量由绿色向红色过度 b色彩分量由蓝色向黄色过度
    7. 索引颜色模式
        只能表现256种颜色
    

    上节课我们知道,OpenCV是以大部分的C的函数和少量的C++的类构成的。这里面有一个很重要的东西就是cv的命名空间。

    using namespace cv;
    

    OpenCV在2.0以后才开始使用Mat数据结构,如果不使用cv命名空间,我们就需要这样写才能使用Mat。

    cv::Mat
    

    所以推荐大家使用命名空间方式,可以减少很多不必要的麻烦。

    下面我们重点看下Mat
    Mat是用来保存图像和其他矩阵的一个数据结构,默认情况下尺寸为0,通过Mat我们可以对图片进行转换

    Mat imgData(h, w, CV_8UC4, (unsigned char *) pixels);
    

    imgData是我们自定义的函数名,它就像一个对象一样,我们可以对这个对象进行操作。
    下面介绍一下各个参数的含义:

    h:图片的高
    w:图片的宽
    CV_8UC4:cv-表明是OpenCV里面使用; 8-指的是8位,即每一个通道代表的位数;U-无
             符号unsigned;C-char类型;4-通道数
    (unsigned char *) pixels:强转成无符号char类型
    
    • CV_8U - 8位无符号整型 ( 0..255 )
    • CV_8S - 8位有符号整型 ( -128..127 )
    • CV_16U - 16位无符号整型( 0..65535 )
    • CV_16S - 16位有符号整型 ( -32768..32767 )
    • CV_32S - 32位有符号整型 ( -2147483648..2147483647 )
    • CV_32F - 32位 floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
    • CV_64F - 64位 floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
    

    下面是我们之前做的灰度图的代码

    Mat imgData(h, w, CV_8UC4, (unsigned char *) pixels);
        uchar *ptr = imgData.ptr(0);
        for (int i = 0; i < w * h; i++) {
            // 灰度值计算公式 R * 0.3 + G * 0.59 + B * 0.11
            uchar gray = (uchar) (ptr[4 * i + 2] * 0.299 + ptr[4 * i + 1] * 0.587 +
                                  ptr[4 * i + 0] * 0.114);
            ptr[4*i+0]=gray;
            ptr[4*i+1]=gray; 
            ptr[4*i+2]=gray;  
        }
    

    那么我们是怎么确定图像通道具体是哪个呢?
    可以这样做(第四个通道不能改0,即变成全透明 ):

    ptr[4*i+0];
    ptr[4*i+1]=0; 
    ptr[4*i+2]=0; 
    

    经过测试,ptr[4*i+0]为蓝色通道部分
    依次进行,我们可以得出:

    ptr[4*i+0]=gray; // blue
    ptr[4*i+1]=gray;// green
    ptr[4*i+2]=gray; // red
    ptr[4*i+3]=gray; // alpha
    
    *上述代码可以得出BGRA的顺序,实际上是Bitmap做了处理,下面是获取图片的代码:
    Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Bitmap中ARGB_8888实际通道顺序是BGRA
    

    通道分离
    在OpenCV中,有专门的函数去处理颜色通道的分离和合并。

    相关文章

      网友评论

          本文标题:OpenCV数字图像知识

          本文链接:https://www.haomeiwen.com/subject/uvtusftx.html