当前位置: 首页 > news >正文

2:OpenCV—加载显示图像

加载和显示图像

从文件和显示加载图像

在本节中,我将向您展示如何使用 OpenCV 库函数从文件加载图像并在窗口中显示图像。

首先,打开C++ IDE并创建一个新项目。然后,必须为 OpenCV 配置新项目。


#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{// 读取一个图像文件并赋给image变量Mat image = imread("lena.png");// 判断读取图像是否为空if (image.empty()) {cout << "没有发现读取图像文件";// 输入人员字符cin.get();return -1;}// 定义一个窗体的名称String winName = "lena 图像";// 创建一个窗体用于显示图像namedWindow(winName);// 把图像显示到创建窗体上面imshow(winName, image);// 等待输入字符并关闭窗口waitKey(0);destroyWindow(winName);
}

将上述代码片段复制并粘贴到 IDE 中并运行它。请注意,您必须将代码中的图像路径替换为计算机中图像的有效位置。然后,您应该会看到如下图所示的输出。

解释

让我们逐行浏览上面的OpenCV程序。

//#include "stdafx.h" 

这是由Visual Studio IDE生成的预编译头文件。如果您使用的是Visual Studio,请取消注释此行以避免编译错误。

opencv2/opencv.hpp 头文件本身将包含 OpenCV 库中所有其他必要的头文件。您必须仅包含此头文件才能编译 OpenCV 代码。

还应包含 iostream 头文件,因为我们在程序中使用 COUT 和 CIN 将错误消息打印到控制台。

所有 OpenCV 函数、类和数据结构都在 cv 命名空间内声明。因此,我们必须在程序顶部添加“**使用命名空间 cv”**行。否则,我们必须在每个 OpenCV 函数、类和数据结构之前附加 ’cv::“说明符。(例如 - cv::Mat, cv::imread() 等)。

我们还必须使用 std 命名空间,因为 cout、endl 和 cin 函数位于 std 命名空间内。

该函数从文件“*C:\Users\Desktop\lena.png*”加载图像,并将其作为 Mat 对象返回。
在你的代码中,你必须将“*C:\Users\Desktop\lena.png*”替换为计算机中图像文件的有效位置。


#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat image = imread("C:\Users\Desktop\lena.png");

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

此函数从指定文件加载图像,并作为 Mat 对象返回。如果函数无法读取文件,它将返回一个空的 Mat 对象。

  1. 文件名 - 您必须提供图像文件的相对或绝对路径。如果要提供相对路径,则它应该是相对于cpp文件的。始终支持 JPEG、JPG、BMP、PNG、TIFF 和 TIF 图像文件类型。支持其他映像文件类型,具体取决于您的平台和安装的编解码器。
  2. flags - 标志参数有几个可能的值。在上面的程序中,我没有向此参数传递任何值,以便使用默认的IMREAD_COLOR参数。
    • IMREAD_UNCHANGED - 图像将按原样加载。如果要在输入图像中获取 alpha 通道(如果可用),则必须使用此标志。
  • IMREAD_GRAYSCALE - 图像将作为灰度图像加载(即 - 单通道图像,黑白图像)
  • IMREAD_COLOR - 图像将作为BGR图像加载(即 - 3通道图像,彩色图像)

 // Check for failureif (image.empty()) {cout << "Could not open or find the image" << endl;cin.get(); //wait for any key pressreturn -1;}

如果 imread() 函数无法加载图像,则返回的 Mat 对象将为空。如果 Mat 对象为空,**则 image.empty()** 函数将返回 true。在这种情况下,我们的程序会将错误消息打印到控制台并等待任何按键。当用户按键盘中的任意键时,程序将退出,返回 -1。最好检查图像是否为空并退出程序。否则,您的程序将在尝试执行 imshow() 函数时崩溃。
此函数创建一个名为“*lena*”的窗口。窗口的名称稍后将在此代码中用于标识窗口。

namedWindow(windowName); // Create a window

void namedWindow(const String&winname, int flags = WINDOW_AUTOSIZE)
此函数创建一个可用于放置图像和跟踪栏的窗口。如果已存在具有给定名称的窗口,则此函数不执行任何操作。

  1. winname - 窗口的名称。该名称将显示在新创建的窗口的标题栏中。此名称也是此窗口的标识符,它将在以后的 OpenCV 函数调用中用于标识窗口。
  2. 标志 - 确定窗口的大小。在上面的程序中,我没有向此参数传递任何值,因此将使用默认WINDOW_AUTOSIZE参数。
    • WINDOW_AUTOSIZE - 用户无法调整窗口大小。图像将以其原始大小显示。
  • WINDOW_NORMAL-用户可以调整窗口大小。
imshow(windowName, image); // Show our image inside the created window.

此函数在上一步中创建的窗口中显示图像。

void imshow(const String&winname, InputArray mat)
此函数在 winname 指定的窗口中显示图像。如果使用WINDOW_AUTOSIZE标志创建窗口,则图像将以其原始大小显示。否则,图像可能会缩放到窗口的大小。如果尚未通过调用 namedWindow() 函数创建窗口,则此函数将创建一个带有 WINDOW_AUTOSIZE 标志的窗口。

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

  1. winname - 由 namedWindow() 函数创建的窗口的名称。
  2. mat - 保存图像的垫子对象
waitKey(0); // Wait for any keystroke in the window

waitKey(0) 函数永远等待按键。当按下任何键时,此函数返回键的 ASCII 值,您的程序将继续。

如果将正值传递给 waitKey() 函数,则它仅等待按键的持续时间,由传递的值(以毫秒为单位)指定。如果在此期间按下任何键,此函数将返回该键的 ASCII 值,您的程序将继续。如果在此期间没有按下任何键,它将返回 -1,程序将继续。

仅当程序至少打开了一个活动的 HIGHGUI 窗口时,此功能才有效。

此函数关闭以名称 windowName 标识的打开窗口,并取消分配任何关联的内存使用量。此功能对于上述程序不是必需的,因为当程序退出时,操作系统通常会关闭所有打开的窗口并取消分配任何关联的内存使用量。

destroyWindow(windowName); //destroy the created window
总结

在上面的部分中,您已经了解到,
- 如何从文件加载图像
- 如何处理图像加载失败时的错误情况
- 如何创建窗口并显示图像
- 如何在不退出程序的情况下等待,直到用户按下某个键
- 如何销毁已创建的窗口

创建空白图像和显示

以下程序也与以前的程序非常相似。唯一的区别是该程序创建一个空白图像,而不是从文件加载现有图像。

将上述简单代码片段复制并粘贴到 IDE 中并运行它。然后,您应该会看到如下图所示的输出。


#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{Mat image(200, 300, CV_8UC3, Scalar(200, 31, 120));// 定义一个窗体的名称String winName = "blank Image Window";// 创建一个窗体用于显示图像namedWindow(winName);// 把图像显示到创建窗体上面imshow(winName, image);// 等待输入字符并关闭窗口waitKey(0);destroyWindow(winName);
}

本节中新增的 OpenCV 函数说明
Mat image(600, 800, CV_8UC3, Scalar(100, 250, 30)); 

这是 Mat 类中可用的众多构造函数之一。它创建一个高 600 像素、宽 800 像素的图像。为图像中的每个像素分配 24 位。24 位将由三个无符号 8 位整数组成,分别代表蓝色、绿色和红色平面。三个整数的值应介于 0 到 255 之间。

然后,此构造函数使用 3 个无符号整数(100、250、30)初始化创建图像的每个像素。因此,它初始化蓝色通道为 100,绿色通道初始化为 250,红色通道初始化为 30。由于绿色通道的值明显大于其他通道的值,因此输出图像为绿色。您可以尝试这三个值的不同组合并查看输出图像。

Mat:**:Mat(int rows, int cols, int type, const Scalar& s)**
此构造函数将创建一个具有指定行数和列数的 Mat 对象,并使用 s 中给出的值初始化每个元素。

  1. row - 2D 数组中的行数(即 - 图像的高度(以像素为单位)

  2. cols - 2D 数组中的列数(即 - 图像的宽度(以像素为单位)

  3. type - 二维数组的数据类型,指定每个通道中每个元素的深度和数据类型以及通道数。(当然,如果通道数大于 2,则 1D 数组变为 2D 数组)。

    • CV_8UC1
  • CV_8UC2
  • CV_8UC3
  • CV_8UC4
  • CV_8UC(n)
  • CV_8SC1
  • CV_8SC2
  • CV_8SC3
  • CV_8SC4
  • CV_8SC(n)
  • CV_16UC1
  • CV_16UC2
  • CV_16UC3
  • CV_16UC4
  • CV_16UC(n)
  • CV_16SC1
  • CV_16SC2
  • CV_16SC3
  • CV_16SC4
  • CV_16SC(n)
  • CV_32SC1
  • CV_32SC2
  • CV_32SC3
  • CV_32SC4
  • CV_32SC(n)
  • CV_32FC1
  • CV_32FC2
  • CV_32FC3
  • CV_32FC4
  • CV_32FC(n)
  • CV_64FC1
  • CV_64FC2
  • CV_64FC3
  • CV_64FC4
  • CV_64FC(n)
  1. s - 使用 s 为每个通道给出的值初始化每个数组元素(像素)。

相关文章:

  • 中大型水闸安全监测系统建设实施方案
  • 工具生态构建对比分析
  • bili.png
  • Docker 无法拉取镜像解决办法
  • 什么是SMBus
  • Node.js 实战二:接口参数校验与类型安全方案
  • 《指针与整数相加减的深入解析》
  • docker学习与使用(概念、镜像、容器、数据卷、dockerfile等)
  • 14、Python时间表示:Unix时间戳、毫秒微秒精度与time模块实战
  • Android framework 中间件开发(一)
  • LearnOpenGL --- 你好三角形
  • 科达嘉数字功放电感应用于英飞凌参考设计REF_MA5302BTLSPS_400W
  • PYTHON训练营DAY27
  • Mendix 中的XPath 令牌(XPath Tokens)详解
  • Elasticsearch 分词与字段类型(keyword vs. text)面试题
  • 【python】直线型雷达图
  • 东芝第3代SiC MOSFET助于降低应用中电源损耗
  • 今日行情明日机会——20250516
  • RK3588平台GDC鱼眼矫正开发全解析:原理、实践与优化
  • 关于“集合框架底层原理”的一些问题
  • 博物馆日|为一个展奔赴一座城!上海171家博物馆等你来
  • 中国军网:带你揭开3所新调整组建军队院校的神秘面纱
  • “三个集中”之后:图说浦东新区28次撤乡并镇
  • 陈吉宁龚正黄莉新胡文容等在警示教育基地参观学习,出席深入贯彻中央八项规定精神学习教育交流会
  • 第十二届警博会在京开幕:12个国家和地区835家企业参展
  • 中东睿评|特朗普中东三国行:喧嚣的形式与空洞的实质