opencv学习笔记(3):图像和视频的读取(C++)

我们知道,OpenCV是一个计算机视觉的开源库,它最基本也最重要的功能肯定是对图像和视频的处理。这个章节学习基本的图像和视频的读取。

1. 图像读取与保存:

1.1 图像读取:

在OpenCV中,使用cv::imread()函数来读取和加载图像,该函数的形式如下。

cpp 复制代码
Mat cv::imread(const String & filename, int flags = IMREAD_COLOR)

可以看到,imread()函数的定义非常简单,其解析如下。

返回值Mat 类型:返回读取的图像,读取图像失败时返回一个空的矩阵对象(Mat::data == NULL)。

参数filename:读取图像的文件名,可以使用相对路径或者绝对路径,但必须带完整的文件扩展名(图像格式后缀)。

参数flags:一个读取标记,用于选择读取图像的方式,默认值为IMREAD_COLOR,flags值的设定与用什么颜色格式读取图像有关。

下面举例

(确保你已经配置好了opencv环境)

cpp 复制代码
//使用VS时的头文件
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

//使用Qt时的头文件
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;


void test01()
{
    // 1.读取图像
    // cv::imread 功能是加载图像文件成为一个Mat对象。
    Mat image = imread("C:/Users/27844/Desktop/icon.jpg",IMREAD_GRAYSCALE);
    if (image.empty())
    {
        cout << "图片为空!" << endl;
        return;
    }

    // 2.显示图像
    // cv::namedWindow的功能是创建一个OpenCV窗口,它是由OpenCV自动创建与释放,用户无需销毁它。
    namedWindow("window", WINDOW_AUTOSIZE);

    imshow("window", image);

    // waitKey(0); 等待键盘输入,不加这句,窗口会一闪而逝
    waitKey(0);
}

下面为代码中用到的函数做解释:

  • **imshow():**用来显示图像的函数。函数定义为cv::imshow ( const String & winname, InputArray mat )。参数const String & winname为显示的窗口名,可以使用cv::namedWindow()函数创建窗口,如不创建,imshow()函数将自动创建;参数InputArray mat为待显示的图像。需要注意的是,imshow()函数之后必须有waitKey()函数,否则显示窗口将一闪而过,不会驻留屏幕。inputArray这个接口类可以是Mat、Mat_<T>、Mat_<T, m, n>、vector<T>、vector<vector<T>>、vector<Mat>,也就意味着函数的参数类型是InputArray型时,把上述几种类型作为参数都可以。另外,OutputArrayOfArrays、InputOutputArray、InputOutputArrayOfArrays都是OutputArray的别名。
  • waitKey(): OpenCV中的内置函数,语句waitKey(0)表示"暂停程序,等待一个按键输入",也就是说,当程序执行到waitKey(0)时暂停运行,只有当用户按下一个按键时,它才会继续运行。参数中的 0 表示等待时间,0表示无限等待。

1.2 图像保存:

同图像读取类似,OpenCV中使用cv::imwrite()函数实现将图像保存到指定的文件,该函数定义如下。

cpp 复制代码
bool cv::imwrite(const String & filename,
InputArray img,
const std::vector<int> & params = std::vector<int>() );

imwrite()函数的参数解析如下。

  • const String & filename:需要保存图像的文件名,要保存图像为哪种格式,就带什么扩展名。
  • InputArray img:要保存的图像。
  • const Std::Vector <int> & params:表示为特定格式保存的参数编码。

举例:

cpp 复制代码
    Mat image(2,2,CV_8UC3,Scalar(0,255,255));
    cout<<"矩阵元素"<<endl<<image<<endl;
    //   将图像保存
    if(imwrite("D:/test.jpg",image))
    {
        cout<<"图片保存成功!"<<endl;
    }
    else
    {
        cout<<"图片保存失败!"<<endl;
    }

2. 视频读取与保存:

2.1视频的读取:

opencv使用 cv::VideoCapture类来读取视频。

视频是由一帧一帧的画面构成,读取视频的过程就是一帧一帧地读取视频帧,读一帧,放到一个Mat对象里面,然后在进行显示。

视频的读取操作步骤如下:

(1)创建cv::VideoCapture的对象。

(2)验证视频读取是否成功。

(3)验证完成,开始读取视频。

VideoCapture对象的创建方式有三种,如下面代码所示:

cpp 复制代码
    // VideoCapture对象创建
    // (1)从文件读取视频
    VideoCapture capture("");

    // (2)从视频捕捉设备读取
    //  这种情况下,可以给出一个标识符,用于表示想要访问的视频捕捉设备,及其与操作系统的握手方式。
    //  对于视频捕捉设备而言,这个标识符就是一个标识数字------如果只有一台视频捕捉设备,那么就是0,
    //  如果系统中有多台视频捕捉设备,那么增加标识数字的值即可。
    VideoCapture capture2(0);

    // (3)仅创建一个捕获对象,而不提供任何关于打开的信息。
    // 对象创建以后通过成员函数open()来设定打开的信息。open()操作也有以下两种方式。
    VideoCapture cap;
    cap.open( "my_video.avi"); //第一种方式打开视频文件
    cap.open(0); //第二种方式打开视频捕捉设备

    // 打开视频后,需要将视频帧读取到cv::Mat矩阵中,共有两种方式,一种是read()操作,另一种是>>操    
    // 作。示例如下。
    cv::Mat frame;
    cap.read(frame); //读取方式一
    cap >> frame; //读取方式二

示例代码:

cpp 复制代码
//(1)创建cv::VideoCapture的对象。

cv::VideoCapture capture("D:/images/test1.mp4");
//参数类型为const string&,即从文件中读取,若设置为0则读取视频捕捉设备。

//(2)验证视频读取是否成功。

if (!capture.isOpened())
{
    std::cout << "Vidoe open failed!" << std::endl;
    return -1;
}
//(3)验证完成,开始读取视频。

cv::Mat frame;
capture >> frame;

2.2视频的保存:

opencv一般使用 cv::VideoWirter类来保存视频。视频的保存也是一帧一帧来保存的。

(VideoWirter与VideoCapture一般配合使用,类似于文件的读写操作)

cv::VideoWriter类的对象的创建有两种方式,第一种是使用构造函数,第二种是使用open()函数,具体示例如下。

第一种方式:

cpp 复制代码
     cv::VideoWriter out(
     const string& filename, // 输出文件名
     int fourcc, // 编码形式,使用 CV_FOURCC()宏
     double fps, // 输出视频帧率
     cv::Size frame_size, // 单帧图像的大小
     bool is_color = true // 如果是false,则可传入灰度图像,true为彩色图像
);

第二种方式:

cpp 复制代码
     cv::VideoWriter out;
     out.open(
     "my_video.mpg", //输出文件名
     CV_FOURCC('D','I','V','X'), // MPEG-4 编码
     30.0, // 输出视频帧率 
     cv::Size( 640, 480 ), // 单帧图像分辨率为 640像素×480像素
     true // 只可传入彩色图像,false为灰度图像
);

其中需要注意的是FOURCC编码形式,操作时常用以下函数把4个字符连接起来形成一个FOURCC 码,形式为cv::VideoWriter::fourcc(char c1,char c2,char c3,char c4)。

常用的格式有如下几种。

CV_FOURCC('P','I','M','1') = MPEG-1 codec。
CV_FOURCC('M','J','P','G') = motion-jpeg codec。
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec。
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec。
CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec。

向创建的cv::VideoWriter对象写入图像也有两种方式,即write()操作和<<操作,示例如下。

cpp 复制代码
cv::VideoWriter::write(
    const Mat& image // 写入图像作为下一帧
);
out << frame;

示例:

cpp 复制代码
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;

void function()
{
VideoCapture video("C:/Users/27844/Desktop/video1.mp4");

    if(!video.isOpened())
    {
        cout<<"video open false"<<endl;
        return;
    }
    Mat img;
    namedWindow("video test");
    int frame_num = video.get(CAP_PROP_FRAME_COUNT);
    cout<<"this video frame conut:"<<frame_num<<endl;

    // 1.5.2 VideoWriter对象创建
    // cv::VideoWriter类用于写入视频,该类使用起来比cv::VideoCapture类稍微复杂一些。
    // (1)构造函数
    VideoWriter out("C:/Users/27844/Desktop/out.mp4",
                      VideoWriter::fourcc('D','I','V','X'),
                      video.get(CAP_PROP_FPS),
                      Size(video.get(CAP_PROP_FRAME_WIDTH),video.get(CAP_PROP_FRAME_HEIGHT)),
                      true
                      );
    while(1)
    {
        video.read(img);
        if(img.empty())
        {
            cout<<"over"<<endl;
            return;
        }
        //显示帧图像
        imshow("video test",img);
        if (waitKey(10) == 'q') break;
        //保存图像
        out<<img;
    }


}
相关推荐
love530love18 小时前
【笔记】Intel oneAPI 开发环境配置
人工智能·windows·笔记·oneapi·onednn·deep neural
HansenPole82518 小时前
元编程笔记
笔记·网络协议·rpc
charlie11451419118 小时前
Git团队协作完全入门指南(上)
笔记·git·学习·教程·工程
自己的九又四分之三站台18 小时前
OpenCV介绍
人工智能·opencv·计算机视觉
迷茫的启明星18 小时前
Git命令学习
git·学习
全栈陈序员19 小时前
说说你对 Vue 的理解
前端·javascript·vue.js·学习·前端框架
im_AMBER19 小时前
Leetcode 85 【滑动窗口(不定长)】最多 K 个重复元素的最长子数组
c++·笔记·学习·算法·leetcode·哈希算法
-suiyuan-19 小时前
sqli-labs靶场3~4笔记
笔记
nwsuaf_huasir19 小时前
overleaf在线编译latex怎办编译中文
学习