OpenCV 加载&显示图像

2,197 阅读4分钟

本节讲述一下 OpenCV 怎样加载图像文件显示的, 笔者的环境是 Mac OS, 如果你是 Windows 请自行查看如何配置,代码是一样的。具体的代码都有注释,后面会解释用到的函数。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, const char * argv[]) {
    // 读取图像文件, 请更换你的图像路径.
    Mat image = imread("/Users/xxx/Pictures/art1.png");
    
    // 检查打开成功与否
    if (image.empty())
    {
        cout << "打开图像失败" << endl;
        // 等待用户按下按键.
        cin.get();
        return -1;
    }
    
    // 创建窗口名称
    String windowName = "show image";
    
    // 创建窗口.
    namedWindow(windowName);
    
    // 显示图像在窗口上
    imshow(windowName, image);
    
    // 等待用户按下按键
    waitKey();

    // 销毁创建的窗口.
    destroyWindow(windowName);
    
    return 0;
}

你只需要更改下你的图像路径即可,执行结果如下:

详细介绍

  1. 头文件与命名空间

这个没啥好说的,使用 OpenCV 时必须导入,命名空间是为了更方便使用 OpenCV 提供的类

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

  1. 读取图像 Mat image = imread("/Users/xxx/Pictures/art1.png");

imread 函数用来加载图像,你只需要修改为你的图像路径即可。返回 Mat 对象, Mat 是图像的容器。

Mat imread( const String& filename, int flags = IMREAD_COLOR );

imread 加载指定的图像,返回 Mat 对象,如果读取失败,返回空的对象

1. filename: 图像的绝对绝对或相对路径,如果使用相对路径的话,需要相对于你的 .cpp 所在目录,
默认支持的图像格式有: JPEGs, PNGs 和 TIFFs,其他的图像支持需要平台安装编解码器。

2. flags: 有如下常见的几个值,全部的值在枚举常量 cv::ImreadModes 中。上面的例子中使用的默认 IMREAD_COLOR
  * IMREAD_UNCHANGED: 如果有的话,会保留 alpha 通道被加载 
  * IMREAD_GRAYSCALE: 转为单通道的灰度图像加载,由编码器内部转换
  * IMREAD_COLOR: 作为 BGR 图像加载
  ...

  1. 创建窗口 namedWindow(windowName)
void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);

函数创建一个窗口,用作图像和图像的占位符,创建的窗口由其名称引用。

1. winname: 窗口名称,标示一个窗口
2. flags: 决定窗口的大小,在上面的例子中采用默认的方式,即为图像的尺寸。保存在枚举常量 cv::WindowFlags 中
  * WINDOW_AUTOSIZE: 用户不能调整窗口大小
  * WINDOW_NORMAL: 用户可以调整窗口大小
  ...

  1. imshow(windowName, image)
void imshow(const String& winname, InputArray mat);

在指定窗口中显示图像,如果窗口是用 WINDOW_AUTOSIZE 标志创建的,图像以原始大小显示,否则图像会根据窗口大小进行缩放显示。如果未通过 namedWindow() 函数创建窗口,imshow 函数会默认创建 WINDOW_AUTOSIZE 标志的窗口。

此函数调用之后应加上 waitKey(int) 函数调用,以便为指定的连续时间(以毫秒为单位)提供足够的时间在窗口中绘制和显示图像。如果不调用 waitKey(int) 函数, 图像不会显示在窗口中。

1. winname: 窗口名称,通过 namedWindow() 函数创建
2. mat: 图像的 Mat 对象

  1. waitkey(0)

等待按键被按下,返回该按键的 ASCLL 码值。如果传入的值大于 0, 那么会在这个时间内等待按键被按下,如果这个时间内没有被按下将会返回 -1,程序继续执行。

该函数要起作用的前提是,当前有窗口被激活。

  1. destroyWindow(windowName)

关闭指定 windowName 的窗口,释放分配任何关联的内存。

总结: 在上面的例子中,你学习到了如下:

  • 怎样加载图像文件
  • 怎样处理加载图像失败
  • 怎样创建窗口和显示图像
  • 怎样使得程序等待直到按键被按下
  • 怎样销毁创建的窗口

创建空白图像 & 显示

创建黑白图像并显示和上面的例子十分类似,不同的地方是通过创建 Mat,而不是加载图像文件。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main(int argc, const char * argv[]) {
    
    // 创建 320 * 480 的 3通道图像,每一个像素占用 3 个 8 位无符号整数的元素
    Mat image(320, 480, CV_8UC3, Scalar(100, 250, 30));
    
    // 窗口名称
    String windowName = "Window with blank image";
    
    // 创建窗口.
    namedWindow(windowName);
    
    // 显示 image 图像
    imshow(windowName, image);
    
    // 等待用户按下按键
    waitKey();
    
    // 销毁窗口,释放内存
    destroyWindow(windowName);
    
    return 0;
}

我相信除了 Mat image(320, 480, CV_8UC3, Scalar(100, 250, 30)); 其他也不需要解释了,分别解释一下这几个参数的意思:

  • CV_8UC3: 表示 8 位无符号整数的 3 通道图像的数据类型
  • 320: 表示图像的高由 320 像素组成
  • 480: 表示图像的宽由 480 像素组成
  • Scalar(100, 250, 30): 图像颜色,BGR 格式,表示该图像偏向浅绿色

关于 CV_8UC3 不清楚,请参考 OpenCV C++ API