opencv编程
引言:
·
本实验旨在介绍使用OpenCV进行图像处理和视频处理的基本操作。OpenCV(Open Source Computer Vision Library)是一个开源计算机视觉库,提供了丰富的图像和视频处理功能,既可以进行图像的读取、显示和保存,也可以对图像进行各种处理操作,如滤波、边缘检测、图像分割等。同时,OpenCV还支持视频的读取、播放和保存,可以实时处理摄像头捕获的视频数据。
·
在本实验中,我们将使用OpenCV库来展示图片并获取摄像头的视频数据。
·
通过本实验的学习,将了解到如何使用OpenCV库进行图像和视频处理的基本操作。这些技术在计算机视觉、图像处理、机器学习等领域具有广泛的应用,对于理解和掌握这些领域的基础知识具有重要意义。现在,让我们开始实验,探索OpenCV的魅力吧!
·
希望你在本次学习过后,能够有一定的收获!!!
·
推荐歌曲—只是太爱你-歌手:丁芙妮
·
冲啊!!!! ٩(͡๏̯͡๏)۶ ٩(͡๏̯͡๏)۶ ٩(͡๏̯͡๏)۶
一、Opencv介绍
OpenCV(Open Source Computer Vision Library)是一个开源计算机视觉库,旨在提供广泛的图像处理和计算机视觉功能。它由一系列的函数和算法组成,可用于处理图像和视频数据,以及进行目标检测、特征提取、图像分割、摄像头标定等任务。
OpenCV最初由Intel于1999年开发,并于2000年首次发布。自那时以来,它已经成为计算机视觉领域最受欢迎和广泛使用的库之一。OpenCV提供了C++、Python和Java等多种编程语言的接口,使开发者能够在各种平台上使用该库进行图像处理和计算机视觉应用的开发。
OpenCV的主要特点包括:
- 广泛的功能:OpenCV提供了大量的函数和算法,涵盖了图像处理和计算机视觉的各个方面。它支持图像的读取、保存和显示,以及各种图像处理操作,如滤波、边缘检测、变换等。此外,OpenCV还提供了强大的机器学习功能和计算机视觉算法,如目标检测、人脸识别、人体姿态估计等。
- 跨平台支持:OpenCV可在多个操作系统上运行,包括Windows、Linux、macOS和Android等。这使得开发者能够在不同的平台上开发和部署他们的应用程序,并且无需进行太多的修改。
- 高性能和优化:OpenCV使用优化的算法和数据结构,以提供高性能的图像处理和计算机视觉功能。它利用硬件加速和并行计算等技术,以提高算法的执行效率。
- 开放源代码:OpenCV是一个开源库,其源代码可在GitHub上公开获取。这使得开发者能够自由地查看和修改库的实现细节,并为其贡献代码和改进。
- 大型社区支持:OpenCV拥有一个庞大的用户社区,其中包括开发者、研究者和爱好者。这个社区提供了文档、教程、示例代码和论坛等资源,以帮助开发者解决问题和学习使用OpenCV。
二、三个小实验
1. 展示opencv图片
gedit test3.cpp // 编辑代码
test3.cpp
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat img;
img = imread("./opencv.jpg");
imshow("img",img);
waitKey(0);
return 0;
}
编译与运行
g++ test3.cpp -o test3 `pkg-config --cflags --libs opencv` # 编译
./test3 # 运行
2. 展示摄像头视频
gedit test1.cpp // 编辑代码
test1.cpp
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
VideoCapture capture(0);
while (1)
{
Mat frame;
capture >> frame;
imshow("读取视频帧", frame);
waitKey(30);
}
system("pause");
return 0;
}
编译与运行
g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv` # 编译
./test3 # 运行
3. 录制摄像头视频
gedit test2.cpp // 编辑代码
test2.cpp
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return 0;
}
//获得cap的分辨率
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
}
编译与运行
g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv` # 编译
./test2 # 运行
三、命令解析
命令 — g++ test1.cpp -o test1 pkg-config --cflags --libs opencv
这条编译命令是用于编译名为 test1.cpp
的源代码文件,并生成可执行文件 test1
。并且使用了 pkg-config
工具来获取 OpenCV 的头文件路径和库文件路径,并将其传递给编译器。
分析命令各个部分:
gcc
: 这是 GNU Compiler Collection 的命令,用于调用 GNU 编译器进行源代码的编译。test1.cpp
: 这是要编译的源代码文件的名称,后缀.cpp
表示它是一个 C++ 的源代码文件。-o test1
: 这是编译器选项,用于指定生成的可执行文件的名称。在这个例子中,生成的可执行文件将被命名为test1
。pkg-config --cflags --libs opencv
: 这是一个命令替换(command substitution),用于将pkg-config
的输出结果插入到编译命令中。
pkg-config
是一个常用的工具,用于获取已安装的软件包的编译参数。在这里,我们使用pkg-config
来获取 OpenCV 的相关编译参数。--cflags
选项用于获取 OpenCV 的编译器标志(例如,包含头文件的路径)。--libs
选项用于获取 OpenCV 的链接器标志(例如,链接库文件的路径)。opencv
是要查询的软件包名称,pkg-config
将根据这个名称来获取 OpenCV 的相关编译参数。
通过将 pkg-config
的输出结果用反引号包围起来,并在编译命令中使用这个命令替换,我们可以将 OpenCV 的头文件路径和库文件路径传递给编译器,以便正确编译和链接程序。
四、问题解答
问题 1
如果要求打开你硬盘上一个视频文件来播放,请问示例 test1.c 第7行代码如何修改?
**解答:**修改为
VideoCapture capture("videoPath");
只需将0 换为对应的视频路径即可
问题 2
在示例代码 test1.c 第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
解答:
在示例代码中,
Mat
是 OpenCV 中用于表示图像和矩阵的数据结构。它是 OpenCV 库中的一个类,用于存储和操作图像数据。
Mat
类提供了许多方法和操作符,用于访问和修改图像的像素值,执行图像处理操作,以及进行矩阵运算等。在示例代码中,Mat frame;
声明了一个Mat
对象,用于存储从视频中读取的每一帧图像数据。关于
waitKey
函数,它是一个用于等待键盘按键的函数。在这个示例中,waitKey(30)
表示程序将等待30毫秒。这个延时是为了控制视频的播放速度,如果没有延时,视频将以最快的速度播放。如果删除了
waitKey
行,程序将变得非常快速,并几乎立即读取和显示所有的视频帧。这意味着视频将会以非常快的速度播放,并且你可能无法看到每一帧的内容。因此,为了能够以适当的速度播放和显示视频帧,建议保留waitKey
行,并根据需要调整延时的时间。
问题 3
示例代码 test1.c 代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
解答:
要改进示例代码以便能够通过鼠标关闭图像显示窗口,可以通过添加一些逻辑来监听按键事件并在按下特定按键时退出循环。在 OpenCV 中,可以使用
waitKey
函数结合break
语句来实现这个逻辑。
下面是修改后的代码示例,可以通过按下 ESC 键来关闭图像显示窗口并退出循环:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 指定视频文件路径
string videoPath = "path/to/your/video/file.mp4";
// 创建 VideoCapture 对象并打开视频文件
VideoCapture capture(videoPath);
// 检查视频是否成功打开
if (!capture.isOpened())
{
cout << "无法打开视频文件" << endl;
return -1;
}
// 创建窗口
namedWindow("读取视频帧", WINDOW_NORMAL);
// 循环读取视频帧
while (true)
{
Mat frame;
capture >> frame;
// 检查是否到达视频末尾
if (frame.empty())
break;
// 显示视频帧
imshow("读取视频帧", frame);
// 等待按键
int key = waitKey(30);
// 按下 ESC 键退出循环
if (key == 27)
break;
}
// 关闭视频文件
capture.release();
// 销毁窗口
destroyAllWindows();
return 0;
}
在这个修改后的代码中,我们创建了一个窗口并命名为"读取视频帧"(可以根据需要修改窗口名称)。然后,在每次循环中,我们使用 waitKey
函数来等待按键事件,返回按下键的 ASCII 码。如果按下的是 ESC 键(ASCII 码为 27),我们使用 break
语句退出循环,从而关闭图像显示窗口并结束程序。
这样修改后,就可以通过按下 ESC 键来关闭图像显示窗口并正常退出程序,而无需使用 Ctrl+C 强制中断。
五、总结
本实验介绍了使用OpenCV进行图像和视频处理的基础操作。OpenCV是一个功能丰富的开源计算机视觉库,用于处理图像和视频数据,提供了从基础的图像读取、显示和保存到高级的图像处理操作,如滤波、边缘检测和图像分割等。此外,OpenCV也支持视频的读取、播放和保存,能够实时处理视频流。
·
通过三个小实验,我们学习了如何利用OpenCV来显示图片、捕捉并展示摄像头视频流以及录制视频。这些实验不仅帮助理解了代码的具体实现,还展示了OpenCV在实际应用中的强大功能。
·
总结而言,OpenCV是计算机视觉、图像处理和相关字段学习者的宝贵工具。通过实验性的学习和问题解决,可以更扎实地掌握这一工具库的应用,为进一步的深入学习打下良好的基础。
最后感谢大佬友情链接: