-
本篇博客的主要内容是对官方OpenCV教程的翻译、总结与理解,并记录自己在学习过程中的心得体会。
-
官方教程地址:https://docs.opencv.org/4.0.0-alpha/db/deb/tutorial_display_image.html
目标
- 使用cv::imread()加载图像
- 使用cv::namedWindow()创建带有名称的窗口
- 使用cv::imshow()在窗口中显示图像
源代码
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
String imageName( "HappyFish.jpg" ); // by default
if( argc > 1)
{
imageName = argv[1];
}
Mat image;
image = imread( samples::findFile( imageName ), IMREAD_COLOR ); // Read the file
if( image.empty() ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
解释
与其他C++程序一样,编写程序时,首先需要包含头文件,头文件里声明了我们需要使用的类、方法。
OpenCV2由很多模块组成,这些模块大多面向的是图像处理的不同领域,我们想要使用这些模块,就需要先包含它们对应的头文件。
本次使用的头文件:
- core.hpp:定义了OpenCV底层的类和方法,Mat类及其实现方法就是在这里声明并定义的。
- highgui.hpp:定义了OpenCV的输入、输出等相关操作,imshow()、imread()、waitKey()等方法都是在这里声明并定义的。
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
同样OpenCV库有自己的名称空间,能够避免OpenCV库中类、方法的名称与其他库的相同而产生冲突,这里直接将名称空间导入了整个文件,能够省略使用类、方法时的cv::前缀。
初学的时候尽量不要直接添加opencv.hpp这个万能头文件,了解每一个头文件的功能和包含的内容,对之后学习是很有帮助的,熟练了之后为了提高开发调试速度,可以直接添加opencv.hpp这个万能头文件。
using namespace std;
using namespace cv;
我们可以优先从命令行获取一张图像的合法路径,否则输出默认的图像。
String imageName( "HappyFish.jpg" ); // by default
if( argc > 1)
{
imageName = argv[1];
}
创建一个Mat对象,用来存储读入的图像数据。
Mat image;
使用 cv::imread 方法加载图像,第一个参数是图像的名称(绝对路径、相对路径),第二个参数是我们希望以什么格式读取图像。
常用的格式如下:
- IMREAD_UNCHANGED (<0):原封不动的读取图像,同样读取可能存在的alpha通道
- IMREAD_GRAYSCALE (0):将图像读取为灰度图像
- IMREAD_COLOR (>0):以RGB格式读取图像
image = imread( samples::findFile( imageName ), IMREAD_COLOR ); // Read the file
OpenCV原生支持bmp、pbm、pgm、ppm、sr、ras图像格式的读取。通过修改CMake预编译时的配置,能够实现JPEG、JPEG 2000、TIFF、png等图像格式的读取。
在检查完图像是否被成功读取之后,需要使用namedWindow方法创建一个窗口。除了需要指定窗口的名称之外,还需要对窗口进行其他配置,例如:指定该窗口是否能够调整大小,可以使用多个标志关键字进行配置,关键字之间需要使用|分隔开。
- WINDOW_AUTOSIZE:如果不使用Qt,那么只能使用这个参数,创建的窗口无法修改大小!
- WINDOW_NORMAL:使用Qt时,这个参数允许改变窗口的大小,图像大小也会随着窗口大小的改变而改变,此时可以使用WINDOW_KEEPRATIO关键字锁定图像宽高比,反之,则可以使用WINDOW_FREERATIO关键字。
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
最后,需要使用imshow方法更新刚刚创建的窗口的内容,注意名称需要与刚刚创建的窗口名称一致,不然的话,会创建一个新的窗口。
imshow( "Display window", image ); // Show our image inside it.
如果现在直接运行程序,会发现图像窗口一闪而过。需要使用waitKey方法使得窗口能够一直显示直到有任意按键被按下时关闭(参数为0),或者显示一段时间后自动关闭(参数大于0,单位为毫秒)。
waitKey(0); // Wait for a keystroke in the window
结果
- 编译、运行代码,在命令行输入一张图像的相对或绝对路径,按下回车!
- 将弹出一个显示输入图像的窗口。
END