代码
// IED:VS2017
// OpenCV: 4.1.0
#include <opencv2/opencv.hpp> // 包含opencv的头文件
#include <iostream>
using namespace cv; // 包含cv命名空间
using namespace std;
int main(int argc, char** argv)
{
Mat img = imread("C:/Users/90307/Desktop/hua.jpg"); // 读入一张图片,名为hua.jpg
if (img.empty()) // 判断读入的图片是否为空
{
printf("Could not load image...\n");
return -1;
}
namedWindow("Input_Image", WINDOW_AUTOSIZE); // 创建图像显示窗口
imshow("Input_Image", img); // 显示图像img
waitKey(0); // 等待任意按键按下
return 0;
}
运行结果
知识点笔记
1. OpenCV的命名空间
OpenCV中的C++类和函数都是定义在命名空间cv之内的。有两种方法可以访问:第一种是在代码开头的适当位置加上using namespace cv,这句代码规定了程序位于此命名空间之内;第二种是在使用OpenCV的每个类和函数时都加入cv::命名空间。相比较而言,推荐采用第一种方式。因而每次写OpenCV代码时,都在开头处加上using namespace cv。
2. main 函数中 argc 和 argv 的说明
首先建议使用 int main(int argc, char** argv) 的写法。argc 和 argv 中的 arg 指的是“参数”的意思,argc 为 argument counter,argv 为 argument vector。int 类型的 argc 用来统计程序运行时发送给 main 函数的命令行参数的个数,在 Visual Studio 中默认值为1;char** 类型的 argv 是一个字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数,各成员的含义如下:
- argv[0] 指向程序运行的全路径名
- argv[1] 指向在DOS命令行中执行程序名后的第一个字符串
- argv[2] 指向在DOS命令行中执行程序名后的第二个字符串
- argv[3] 指向在DOS命令行中执行程序名后的第三个字符串
- ...
- argv[argc] 为NULL
以一个例子来解释上述的说明。假设有以下的代码:
#include <stdio.h>
int main(int argc, char** argv) // 整数类型 主函数 (整数类型统计参数个数,字符类型指针数组指向字符串参数)
{
printf("%d\n", argc); // 输出 argc 的值
while (argc) // 当(统计参数个数)
{
printf("%s\n", argv[--argc]);
}
return 0;
}
如果上述代码是在 Vsiual Studio 中运行的话,则打印如下:
这里假设该程序不是在 Visual Studio 中运行。在命令行下输入
> opencv_exercise.exe hello world
得到的结果将是
3
world
hello
opencv_exercise
本例中,argc 指的是命令行参数的个数,即 hello 和 world 这两个参数以及程序运行的全路径名或者程序名,因此这里的argc等于3;argv 是一个char*的数组,其中存放指向参数变量的指针,此处 argv[0] 指向 opencv_exercise.exe,argv[1] 指向 hello, argv[2] 指向 world。
3. Mat -- 基础图像容器(The basic image container)
https://docs.opencv.org/4.1.0/d6/d6d/tutorial_mat_the_basic_image_container.html
Mat 是用于保存图像以及其他矩阵数据的数据结构。在OpenCV 1.0时代,使用名为 IplImage 的C语言结构体在内存中保存图像,但这种方式存在手动内存管理的麻烦,因此从OpenCV 2.0时代开始,使用 Mat 类数据结构替代 IplImage,这也使得上手OpenCV 更加容易。
Mat 类定义在 core.hpp 中,其由两个数据部分组成:
- the matrix header. (containing information such as the size of the matrix, the method used for storing, at which address is the matrix stored, and so on)
- a pointer to the matrix containing the pixel values. (taking any dimensionality depending on the method chosen for storing)
矩阵头的尺寸是固定的,但矩阵本身的尺寸可能会因图像的不同而不同,通常比矩阵头的尺寸大几个数量级。
OpenCV 是一个图像处理库,它包含了大量的图像处理函数。为了解决问题,很多时候我们都会调用库中的多个函数,因此将图像传递给函数是一个很常见的操作。图像处理的计算量很大,所以我们应该避免对图像进行不必要的复制,以进一步降低程序的运行速度。
为了解决这个问题,OpenCV 使用了一种引用计数机制 (reference counting system),其想法是:each Mat object has its own header, however the matrix may be shared between two instance of them by having their matrix pointers point to the same address。而且,复制操作只会把矩阵头和指针复制到大矩阵中,而不复制数据。