1. 图片读取与显示
1.1 图片读取函数imread
示例:读取一张图片并转为灰度图输出。
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat img;
// 单通道灰度输出IMREAD_GRAYSCALE,3通道彩色IMREAD_COLOR
img = imread("D:/Project_Images/ikun.png", IMREAD_GRAYSCALE);
if (img.empty())
{
cout << "no exist!" << endl;
}
imshow("ikun", img);
waitKey();
}
效果如下:
1.2 图像窗口函数nameWindow
使用方法:
cv::namedWindow(winName, flags);
flags:
WINDOW_AUTOSIZE:根据图像自动调整窗口大小,用户不能调
WINDOW_KEEPRATIO:保持图像比例
WINDOW_GUI_EXPANDED:窗口允许添加工具栏和状态栏
示例:以彩图展示图像,并命名窗口名
void test()
{
Mat img;
img = imread("D:/Project_Images/ikun.png", IMREAD_COLOR);
if (img.empty())
{
cout << "no exist!" << endl;
}
// 创建一个名为ikun的窗口,没有这个代码imshow也会自动创建窗口
namedWindow("ikun", WINDOW_AUTOSIZE);
// 打开名为ikun的窗口,若不存在则系统创建,用于显示Img,属于Mat类
imshow("ikun", img);
waitKey();
}
效果:
2. 视频读取与显示
2.1 视频读取
- 虽然视频实际由每一帧的图像组成,但是imread()不能读视频,使用VideoCapture类来读取,需要使用到该类的构造方式。
- 同时使用VideoCapture类读取后需要保存到Mat容器之后才方便对数据处理。
示例:
// 打开视频
void test()
{
system("color F0");
VideoCapture video("D:/Project_images/test1.mp4");
if (video.isOpened())
{
cout << "画面宽度 = " << video.get(CAP_PROP_FRAME_WIDTH) << endl;
cout << "画面高度 = " << video.get(CAP_PROP_FRAME_HEIGHT) << endl;
cout << "帧率 = " << video.get(CAP_PROP_FPS) << endl;
cout << "总帧数 = " << video.get(CAP_PROP_FRAME_COUNT) << endl;
}
else
{
cout << " no exist!" << endl;
}
cv::namedWindow("video player", WINDOW_AUTOSIZE);
while (true)
{
Mat frame;
if (!video.read(frame)) // 逐帧读取
{
break;
}
cv::imshow("video player", frame); // 把帧的图像用imshow显示
if (cv::waitKey(30) == 27) // 每30ms检测,ESC键退出播放
{
break;
}
}
destroyWindow("video player"); // 销毁窗口
video.release(); // 释放对象
}
2.2 调用系统摄像头
示例如下:调用电脑自带摄像头显示实时画面
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
cv::VideoCapture cap(0); // 打开默认摄像头,编号为0,为电脑的摄像头
if (!cap.isOpened()) {
// 检查摄像头是否成功打开
std::cout << "无法打开摄像头" << std::endl;
return -1;
}
else
{
cout << "画面宽度:" << cap.get(CAP_PROP_FRAME_WIDTH) << endl;
cout << "画面高度:" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
cout << "画面帧率:" << cap.get(CAP_PROP_FPS) << endl;
}
// 一定要使用循环才能将视频中的画面全部读取
while (true) {
cv::Mat frame;
cap >> frame; // 从摄像头读取一帧图像,将cap数据传给Mat容器
cv::imshow("Camera video", frame); // 显示图像窗口,每次都是读取图像
if (cv::waitKey(30) == 27) {
// 按下ESC键退出循环
break;
}
}
cap.release(); // 释放摄像头资源
cv::destroyAllWindows(); // 关闭图像窗口
return 0;
}
3. 图片保存
imwrite():保存图像函数
示例:保存处理后的灰度图
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
// 保存图片练习
int main()
{
Mat img;
img = imread("D:/Project_Images/ikun.png", IMREAD_GRAYSCALE);
if (img.empty()) // 一定要有是否存在的判断,防止程序崩溃
{
cout << "no exist!" << endl;
return -1;
}
imwrite("D:/Project_Images/ikun_gray.png",img);
cout << "灰度处理导出成功!" << endl;
waitKey(0);
}
效果如下:
4. 视频保存
VideoWrite()类:是一个类,同样需要使用构造函数。
示例:使用电脑自带摄像头拍摄并保存
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
// 打开电脑摄像头并保存拍摄的视频
int main()
{
VideoCapture video(0); // 创建video 类对象
if (!video.isOpened()) // 打开是否成功
{
cout << "open the camara failed!" << endl;
return -1;
}
VideoWriter writer; // 创建writer的类对象
string fileName = "D:/Project_Images/Live.avi"; // 保存路径和格式,建议.avi
int codec = VideoWriter::fourcc('M', 'J', 'P', 'G'); // 设置编码格式
double fps = 30.0;
int width = video.get(CAP_PROP_FRAME_WIDTH);
int height = video.get(CAP_PROP_FRAME_HEIGHT);
// 视频流的保存方式:路径,编码方式,帧率,长宽
writer.open(fileName, codec, fps, cv::Size(width, height));
if (!writer.isOpened())
{
cout << " open video failed!" << endl;
return -1;
}
while (1)
{
Mat frame;
video >> frame;
if (frame.empty())
{
cout << "something error!" << endl;
break;
}
imshow("Live", frame); // 显示当前捕获的图像帧
writer.write(frame); // 写入
if (waitKey(10) == 27)
{
cout << "拍摄的视频已保存!" << endl;
break;
}
}
video.release();
writer.release(); // 析构所有类资源
destroyAllWindows(); // 销毁窗口资源
return 0;
}