前言
本文将介绍使用OpenCV从摄像头逐帧读取图片并保存到本地的C++和Python实现。主要涉及的技术点包括:打开摄像头、逐帧读取图像、显示图像、保存图像、按键事件处理等。
完整代码见文末
1. 打开摄像头
在OpenCV中,可以使用VideoCapture类来打开摄像头。其中,0表示默认打开第一个摄像头,1表示第二个,以此类推。如果参数是字符串类型,则表示打开相应路径下的视频文件。打开摄像头的代码如下所示:
C++实现:
VideoCapture cap(0); // 打开摄像头
if(!cap.isOpened()) // 检查摄像头是否成功打开
{
cerr << "Failed to open camera" << endl;
return -1;
}
Python实现:
cap = cv2.VideoCapture(0) # 打开摄像头
if not cap.isOpened(): # 检查摄像头是否成功打开
print("Failed to open camera")
exit()
2. 逐帧读取图像
使用VideoCapture类的read方法可以逐帧读取图像。该方法会返回两个值:第一个值为True表示成功读取到一帧图像,False则表示读取失败;第二个值为读取到的图像。读取图像的代码如下所示:
C++实现:
Mat frame;
cap >> frame; // 逐帧读取摄像头图像
Python实现:
ret, frame = cap.read() # 逐帧读取图像
3. 显示图像
使用OpenCV中的imshow方法可以显示图像。需要传入两个参数:第一个参数为窗口名称,第二个参数为要显示的图像。代码如下所示:
C++和Python实现:
imshow("video", frame);
4. 保存图像
使用OpenCV中的imwrite方法可以将图像保存到本地。需要传入两个参数:第一个参数为文件名,第二个参数为要保存的图像。代码如下所示:
C++实现:
imwrite(filename, frame);
Python实现:
cv2.imwrite(filename, frame)
5. 按键事件处理
使用OpenCV中的waitKey方法可获取键盘输入。该方法返回按键的ASCII码值。如果没有按键输入,则返回-1。代码如下所示:
C++和Python实现:
char key = waitKey(30);
在本文实现的例子中,按键s表示保存当前帧图像,ESC键表示退出程序。代码如下:
C++实现:
if(key == 's') // 保存图像
{
sprintf(filename, "image%d.jpg", count++);
imwrite(filename, frame);
cout << "Saved " << filename << endl;
}
else if(key == 27) // 退出
{
break;
}
Python实现:
key = cv2.waitKey(30)
if key == ord('s'): # 保存图像
filename = f"image{count}.jpg"
cv2.imwrite(filename, frame)
print(f"Saved {filename}")
count += 1
elif key == 27: # 退出
break
代码实现都类似,只是语法略有不同。完整代码如下所示:
6. 完整代码实现
C++实现:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
// 打开默认的摄像头
VideoCapture cap(0);
// 检查视频流是否打开
if (!cap.isOpened()) {
cerr << "ERROR: Unable to open the camera" << endl;
return -1;
}
// 定义一个计数器
int count = 0;
// 循环读取摄像头图像
while (true) {
// 获取一帧图像
Mat frame;
cap >> frame;
imshow("Frame", frame);
// 按下“s”键保存图像
char c = (char) waitKey(25);
if (c == 's') {
stringstream ss;
ss << "frame-" << count << ".png";
imwrite(ss.str(), frame);
cout << "Saved " << ss.str() << endl;
count++;
}
// 按下ESC键退出
if (c == 27) {
break;
}
}
// 释放视频流
cap.release();
// 关闭所有窗口
destroyAllWindows();
return 0;
}
Python实现:
import cv2
# 打开默认的摄像头
cap = cv2.VideoCapture(0)
# 定义计数器
count = 0
# 循环读取摄像头图像
while True:
# 获取一帧图像
ret, frame = cap.read()
# 显示出来
cv2.imshow("Frame", frame)
# 按下s键保存图像
if cv2.waitKey(1) & 0xFF == ord('s'):
filename = f"frame-{count}.png"
cv2.imwrite(filename, frame)
print(f"Saved {filename}")
count += 1
# 按下ESC键退出
if cv2.waitKey(1) & 0xFF == 27:
break
# 释放视频流
cap.release()
# 关闭所有窗口
cv2.destroyAllWindows()
7. 总结
在这篇文章中,我们介绍了如何使用OpenCV从摄像头逐帧读取图像,并将每帧图像保存到本地。我们提供了C++和Python两种不同的实现方式。这些代码是处理,录制和处理基于图像的数据的开端。OpenCV的框架可帮助开发人员使此过程变得更加容易。
参考资料:
[1] OpenCV官方文档:https://docs.opencv.org/4.5.3/d8/dfe/classcv_1_1VideoCapture.html
[2] OpenCV官方文档:https://docs.opencv.org/4.5.3/d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba3