【OpenCV3编程入门学习笔记】——第3章 HighGUI图形用户界面初步

这篇博客介绍了OpenCV3的HighGUI模块,重点讲解了如何使用OpenCV进行图像的载入、显示和输出到文件。通过Mat类的使用、imread()和imshow()函数的详细解析,以及namedWindow()和imwrite()函数的介绍,为读者提供了OpenCV图形用户界面的基础知识。此外,还提及了滑动条的创建和鼠标操作的实现方法。
摘要由CSDN通过智能技术生成

前言

笔记系列

参考书籍:OpenCV3编程入门

作者:毛星云

版权方:电子工业出版社

出版日期:2015-02

笔记仅供本人参考使用,不具备共通性

笔记中代码均是OpenCV+Qt的代码,并非用vs开发,请勿混淆

HighGUI模块为高层GUI图形用户界面模块

它的功能包括

  • 媒体的输入输出
  • 视频捕捉
  • 图像和视频的编码解码
  • 图形交互界面的接口

3.1 图形的载入、显示和输出到文件

  • OpenCV1.0时代的基于C语言接口而建的图像存储格式IplImage*十分不好用
  • 进入到2.0时代后,OpenCV采用了Mat类作为数据结构进行图像存取
    • 此改进使得OpenCV变得容易上手和用于实际开发

3.1.1 OpenCV的命名空间

  • OpenCV中的C++类和函数都是定义在命名空间cv之内的

  • 我们有两种方法可以访问cv

    • 其一:在代码开头的适当位置加上using namespace cv;这句代码以规定我们的程序位于词命名空间之内
    • 其二:在使用OpenCV的每一个类和函数时,都在前面加上cv::
    • 相较而言,显然第一种方法更加方便,推荐使用

平常在写简单的OpenCV程序时,以下三句可以作为标配

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

3.1.2 Mat类简析

  • Mat类

    • 是用于保存图像以及其他矩阵数据的数据结构

    • 默认情况下Mat类的尺寸为0

      • 可以用类似于cv::Mat pic(320,640,cv::Scalar(100));的代码来定义一个初始带尺寸的Mat类
    • Mat最基本的用法如下

      • using namespace cv;
        Mat srcImage = imread("需要加载的图像路径");//路径可以是绝对路径,也可以是相对路径
        
      • 上面的代码表示将一张图片载入到Mat类型的srcImage变量中

        • (尽量是jpg或png格式的,其他格式我还没试过,不知道可不可行)
      • 代码中的imread()函数,是用于将图片读入Mat类型中,后面会详细讲解

3.1.3 图像的载入与显示概述

  • 图像载入用到的代码

    • imread()
      
  • 图像显示用到的代码

    • imshow()
      

3.1.4 图像的载入:imread()函数

  • 功能:用于读取文件中的图片到OpenCV中

  • 函数的原型如下:

    • enum ImreadModes{
             
      IMREAD_COLOR                = 1,  //!< If set, always convert image to the 3 channel BGR color image.};
      //上面是截取的部分代码,下面是imread()函数的声明
      Mat imread( const String& filename, int flags = IMREAD_COLOR );
      //参数一:需要载入的图片路径名    参数二:载入标识符
      
    • 第一个参数:const String& filename ---- 我们需要载入的图片路径名

      • 在Windows操作系统下,OpenCV的imread函数支持如下类型的图像载入

        • 图片类型 对应的文件后缀名
          Windows位图 *.bmp, *.dib
          JPEG文件 *.jpeg, *.jpg, *.jpe
          JPEG 2000文件 *.jp2
          PNG图片 *.png
          便携文件格式 *.pbm, *.pgm, *.ppm
          Sun rasters光栅文件 *.sr, *.ras
          TIFF文件 *.tiff *.tif
    • 第二个参数:int flags = IMREAD_COLOR

      • 载入标识符,它指定一个加载图像的颜色类型和图片深度

      • flags默认值为IMREAD_COLOR,也就是1,所以有些时候这个参数在调用时可以忽略,此时表示载入三通道的彩色图图像

      • 同时通过上面的代码展示可以看出来,此参数可以在OpenCV中标识图像格式的枚举体中取值

      • 让我们转到定义,看看这个枚举体,如下

        • //! Imread flags
          enum ImreadModes {
                     
                 IMREAD_UNCHANGED            = -1, 
              //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). Ignore EXIF orientation.
              //如果设置,则按原样返回加载的图像(带有Alpha通道,否则将被裁剪)。 忽略EXIF方向
                 IMREAD_GRAYSCALE            = 0,  
              //!< If set, always convert image to the single channel grayscale image (codec internal conversion).
              //如果设置,则始终将图像转换为单通道灰度图像(编解码器内部转换)。
                 IMREAD_COLOR                = 1,  
              //!< If set, always convert image to the 3 channel BGR color image.
              //如果设置,则始终将图像转换为3通道BGR彩色图像。
                 IMREAD_ANYDEPTH             = 2,  
              //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
              //如果设置,则当输入具有相应的深度时返回16位/ 32位图像,否则将其转换为8位。
                 IMREAD_ANYCOLOR             = 4,  
              //!< If set, the image is read in any possible color format.
              //如果设置,将以任何可能的颜色格式读取图像。
                 IMREAD_LOAD_GDAL            = 8,  
              //!< If set, use the gdal driver for loading the image.
              //如果已设置,则使用gdal驱动程序加载图像。
                 IMREAD_REDUCED_GRAYSCALE_2  = 16, 
              //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
              //如果设置,则始终将图像转换为单通道灰度图像,并且图像尺寸减小1/2。
                 IMREAD_REDUCED_COLOR_2      = 17, 
              //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
              //如果设置,则始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/2。
                 IMREAD_REDUCED_GRAYSCALE_4  = 32, 
              //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
              //如果设置,则始终将图像转换为单通道灰度图像,并且图像尺寸缩小1/4
                 IMREAD_REDUCED_COLOR_4      = 33, 
              //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
              //如果设置,则始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/4。
                 IMREAD_REDUCED_GRAYSCALE_8  = 64, 
              //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
              //如果设置,则始终将图像转换为单通道灰度图像,并且图像尺寸减小1/8。
                 IMREAD_REDUCED_COLOR_8      = 65, 
              //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
              //如果设置,则始终将图像转换为3通道BGR彩色图像,并且图像尺寸减小1/8。
                 IMREAD_IGNORE_ORIENTATION   = 128 
          	//!< If set, do not rotate the image according to EXIF's orientation flag.
          	//如果已设置,则不要根据EXIF的方向标志旋转图像。
               };
          
        • 上述代码选择解释

          • 枚举值 解释说明
            IMREAD_UNCHANGED 等价取值为-1,该标识符在新版本中已被废置,忽略
            IMREAD_GRAYSCALE 等价取值为0,如果取这个标识的话,会将载入的图像转换成灰度图在返回
            IMREAD_COLOR 等价取值为1,若是取这个标识的话,会将图片转换成3通道BGR彩色图像并返回
            IMREAD_ANYDEPTH 等价取值为2,若是取这个标识的话,会先检查图像的深度,若图像深度为16位或32位,则返回对应深度的图像,否则,会将图像转换位8位图像再返回
          • 注意:如果输入有冲突的标志,则采用较小的数字值,例如:

            • flag = IMREAD_COLOR|IMREAD_ANYCOLOR时,程序将载入三通道图
              • 这里的IMREAD_COLOR(等价于1)和IMREAD_ANYCOLOR(等价于4)是相互冲突的,因为二者都是对读取图像的颜色的方法做规定
            • 而如果想要载入最真实无损的源图像,可以选择flag = IMREAD_ANYCOLOR|IMREAD_ANYDEPTH
              • 此处的IMREAD_ANYCOLOR(等价于4)和IMREAD_ANYDEPTH(等价于2)是不相互冲突的,因为前者是对读取图片的颜色的方面做规定,后者是对读取图片的深度的方面做规定
              • 因此,flag = IMREAD_ANYCOLOR|IMREAD_ANYDEPTH标识符所代表的意思是以任何可能的颜色格式,任何可能的图像深度来读取图像
      • 注意:下面的表格并不全对,这只是书上的描述,在最新的OpenCV3的版本中,有些许出入

      • 因为flags是int型的变量,若我们不在这个枚举体中去固定的值,可以这样进行

        • flags取值 达到的效果
          flags > 0 返回一个3通道的彩色图像,但数值越大,图片就会呗压缩得越厉害!
          flags = 0 返回灰度图像
          flags < 0 返回包含Alpha通道的加载图像
        • 输出的图像默认情况下不返回Alpha通道,所以若想载入Alpha通道,这里就需要取负值

        • 在书上,作者这样写道:通过表可知,flags = 1999也是可以的,它和flags = 1的效果一样,同样标识返回一个3通道的彩色图像

        • 然而,最新的Opencv3的代码已经不太一样了,flag>1时,不一定会返回一个BGR三通道的图像,甚至flag在不同的数字区间中,所返回的图片大小也是不一样的(具体原因看上面的枚举体代码)

    • imread的一些常见用法

      • Mat image0 = imread("1.jpg",2|4);//载入无损的源图像
        Mat image1 = imread("1.jpg",0);//载入灰度图
        Mat image2 = imread("1.jpg",1);//载入3通道的彩色图像
        

3.1.5 图像的显示:imshow()函数

  • imshow()函数用于在指定的窗口中显示一副图像

  • 其函数原型如下

    • void imshow(const String& winname, InputArray mat);
      //参数一:图像窗口的标识名称		参数二:需要显示的图像
      
    • 第一个参数:const String& winname

      • 填写要显示的窗口标识名称(暂时不能打中文,问题未解决)
    • 第二个参数:InputArray mat

      • 填需要显示的图像
    • imshow()函数的显示规则

      • imshow函数用于在指定的窗口中显示图像
      • 如果窗口使用CV_WINDOW_AUTOSIZE(默认值)标志创建的,那么显示图像原始大小
      • 否则,将图像进行缩放以适合窗口
    • imshow()函数缩放图像,取决于图像的深度,具体如下

      • 如果载入的图像是8位无符号类型(8-bit unsigned),就显示图像本来的样子
      • 如果载入的图像是16位无符号类型(16-bit unsigned)或32位整型(32-bit integer),便用像素值除以256,也就是说,值的范围是[0,255 x 256]映射到[0,255]
      • 如果图像时32位浮点型(32-bit floating-point),像素值要乘以255,也就是说,值的范围是[0,1]映射到[0,255]
    • 此外,若是在窗口创建的时候,程序设定支持OpenGL(WINDOW_OPENGL),那么imshow还支持olg::Bufferolg::Texture2Dgpu::GpuMat作为输入,其函数原型如下

      • namespace ogl
        {
                 
            class CV_EXPORTS Buffer;
            class CV_EXPORTS Texture2D;
            class CV_EXPORTS Arrays;
        }
        
        void imshow(const String& winname, const ogl::Texture2D& tex);
        
    • 关于imread()和imshow()函数最精简的示例程序,可以参考书本第一章中,1.3.8节的"最终的测试",或者1.4.1中"第一个程序:图像显示"中的代码.

3.1.6 关于InputArray类型

找到InputArray类型的定义,再OpenCV 3.4.13版本中,该类型位于...\opencv2\core\mat.hpp

typedef const _InputArray& InputArray;

从此处可以看出:此处是一个类型声明引用,亦即_InputArrayInputArray是同一个变量,所以我们接着做定义跳转

跳到_InputArray的定义处

class CV_EXPORTS _InputArray
{
   
public:
    enum {
   
        KIND_SHIFT = 16,
        FIXED_TYPE = 0x8000 << KIND_SHIFT,
        FIXED_SIZE = 0x4000 << KIND_SHIFT,
        KIND_MASK = 31 << KIND_SHIFT,

        NONE              = 0 << KIND_SHIFT,
        MAT               = 1 << KIND_SHIFT,
        MATX              = 2 << KIND_SHIFT,
        STD_VECTOR        = 3 << KIND_SHIFT,
        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
        STD_VECTOR_MAT    = 5 << KIND_SHIFT,
        EXPR              = 6 << KIND_SHIFT,  //!< removed
        OPENGL_BUFFER     = 7 << KIND_SHIFT,
        CUDA_HOST_MEM     = 8 << KIND_SHIFT,
        CUDA_GPU_MAT      = 9 << KIND_SHIFT,
        UMAT              =10 << KIND_SHIFT,
        STD_VECTOR_UMAT   =11 << KIND_SHIFT,
        STD_BOOL_VECTOR   =12 << KIND_SHIFT,
        STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT,
        STD_ARRAY         =14 << KIND_SHIFT,
        STD_ARRAY_MAT     =15 << KIND_SHIFT
    };

    _InputArray();
    _InputArray(int _flags, void* _obj);
    _InputArray(const Mat& m);
    _InputArray(const MatExpr& expr);
    _InputArray(const std::vector<Mat>& vec);
    template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
    template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
    _InputArray(const std::vector<bool>& vec);
    template<typename _Tp> _InputArray
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值