opencv读写常用操作

本文详细介绍了OpenCV中的Mat数据类型,包括Mat类的构造方法、不同数据类型的转换示例,以及图像读写、格式化打印和视频处理的基础操作。重点讲解了如何将CV_32F转换为CV_8U,以及使用VideoCapture和VideoWriter处理视频文件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Mat数据类型

1.1 Mat介绍

Mat类的声明在头文件opencv2\core\core.hpp中。

构造Mat对象,需要四个基本元素:行数,列数,通道数及其数据类型,Mat类的构造函数如下:

Mat(int rows, int cols, int type)
  • rows代表行数,即图像的高度
  • cols代表列数,即图像的宽度
  • type代表类型,包括通道数及其数据类型
    • CV_8UC(n): 8U=1字节的uchar类型
    • CV_32SC(n): 32S=4字节的Short类型
    • CV_32FC(n): 32F=4字节的float类型
    • C(n)代表通道数

1.2 打印Mat数据

使用OpenCV提供的format()函数:

static inline
Ptr<Formatted> format(InputArray mtx, int fmt)

其中mtx为Mat数据,fmt为所支持的打印风格,其参数如下:

  • Formatter::FMT_C:C风格打印(常用)
  • Formatter::FMT_NUMPY: numpy风格打印
  • Formatter::FMT_CSV: 逗号打印
  • Formatter::FMT_PYTHON:python打印
#include <stdio.h>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
 
int main()
{ 
    Mat M(2, 2, CV_32FC1, Scalar(0.3));
    Mat out;
    M.convertTo(out, CV_8U, 255);
    cout << "L= (C)" << endl << format(out, Formatter::FMT_C) << endl << endl;
    cout << "L= (numpy)" << endl << format(M, Formatter::FMT_NUMPY) << endl << endl;
    cout << "L= (CSV)" << endl << format(M, Formatter::FMT_CSV) << endl << endl;
    cout << "L= (,)" << endl << format(M, Formatter::FMT_CSV) << endl << endl;
    cout << "L= (python)" << endl << format(M, Formatter::FMT_PYTHON) << endl << endl;
    return 0;
}

 1.3 CV_32F转CV_8U

对于图像分割任务,输出常常是一个范围为【0,1】的浮点数类型的Mask,为了保存输出结果且避免错误,需要将去数据类型转换为CV_8U,此时可以通过opencv提供的函数convertTo完成数据类型的转换。

void cv::Mat::convertTo	(OutputArray 	m,
    int 	rtype,
    double 	alpha = 1,
    double 	beta = 0 
)	

// converts an array to another data type with optional scaling and shift.
  •  rtype:为需要转换的数据类型
  • alpha:为需要对元素进行的缩放值
  • beta:为平移值

Mat A; // CV_32F and range [0, 1]
Mat B;

A.convertTo(B, CV_8U, 255);

2. 图像读写

2.1. 读取图像

函数的语法格式:

retval = cv2.imread(filename, [flags])
  • flags为读取标记,用于控制读取文件的类型。

  •  IMREAD_GRAYSCALE:该模式下读取得到的图像为单通道灰度图像,得到data的维度为【height,width】
  • IMREAD_COLOR:(default)彩色图像模式,得到data的维度为【height,width,channel】

2.2. 显示图像

函数语法格式:

None = cv2.namedWindow(winname) cv2.imshow(winname, Mat)

在实际使用中,可以先通过函数namedWindow创建一个窗口,再通过imshow引用该窗口来显示图像

也可以不创建窗口,直接使用imshow引用一个并不存在的窗口,显示指定图像。

2.3. 保存图像

函数语法格式:

retval = cv2.imread(filename, mat, [params])
  • params是保存类型参数,可选。

3. 视频读写

OpenCV提供cv2.VideoCapture类和cv2.VideoWriter类来支持各种类型的视频文件。

在不同操作系统中,它们支持的文件类型有所不同,但是各种操作系统中均支持AVI格式的视频文件。

3.1  VideoCapture类

1. 初始化

cv2.VideoCapture()用于打开摄像头并完成摄像头的初始化工作。

捕获对象 = cv2.VideoCapture("摄像头ID号")

  • "摄像头ID号":摄像头的ID号码
  • 捕获对象:返回值为VideoCapture类的对象

2. open()函数和isOpened()函数

用来检测是否初始化成功

retval = cv2.VideoCapture().isOpened()

  • retval = True,表示成功
  • retval = False,表示失败

3. 捕获帧数据

摄像头初始化成功后,就可以从摄像头中捕获帧信息。

retval, frame = cv2.VideoCapture.read()

  • image:返回捕获得到的帧数据
  • retval:捕获成功为True,失败为False

4. 释放

在不需要摄像头时,关闭摄像头。

None = cv2.VideoCapture.release()

5. 属性设置

用于获取或更改VideoCapture类对象的属性。

retval = cv2.VideoCapture.get(propid) cv2.VideoCapture.set(propid, value)

  • propid:表示类对象的属性
  1. cv2.CAP_PROP_FRAME_WIDTH
  2. cv2.CAP_PROP_FRAME_HEIGHT
  3. cv2.CAP_PROP_FPS:帧率
  4. cv2.CAP_PROP_FRAME_COUNT:总帧数
  5. cv2.CAP_PROP_POS_MSEC:视频当前位置

3.2 VideoWriter

VideoWriter类可以将图片序列化保存成视频文件,也可以修改视频的各种属性,还可以完成对视频类型的转换。

1. 构造函数

cv2.VideoWriter(filename, fourcc, fps, frameSize, [isColor])

  • fourcc表示视频编解码类型。通过VideoWriter_fourcc()来指定视频编码格式
    • "I420":表示未压缩的YUV颜色编码格式,色度子采样为4:2:0.该编码格式具有较好的兼容性,但产生的文件较大,文件扩展名为".avi"
    • "xvid"::表示MPEG-4编码类型。视频大小约占平均大小,生成文件的扩展名为".avi"
    • "THEO":表示Ogg Vorbis编码类型,文件扩展名为".ogv"
    • "FLVI":表示Flash视频,生成为文件扩展名为".flv"

2. write函数

cv2.VideoWriter.write(image)

3. 释放对象

cv2.VideoWriter.release()

 3.3 python和C++的实现例子

  • python实现
import numpy as np
import cv2

cap = cv2.VideoCapture(0)

fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = cap.get(cv2.CAP_PROP_FPS)
frame_size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
out = cv2.VideoWriter('test.avi',fourcc, fps, frame_size,True)

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:

        cv2.imshow('frame',frame)
        out.write(frame)
        
        if cv2.waitKey(10) & 0xFF == ord('q'):
            break
    else:
        break

cap.release()
out.release()
cv2.destroyAllWindows()
  • C++实现
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int, char**)
{
    Mat src;
    // use default camera as video source
    VideoCapture cap(0);
    // check if we succeeded
    if (!cap.isOpened()) {
        cerr << "ERROR! Unable to open camera\n";
        return -1;
    }
    // get one frame from camera to know frame size and type
    cap >> src;
    // check if we succeeded
    if (src.empty()) {
        cerr << "ERROR! blank frame grabbed\n";
        return -1;
    }
    bool isColor = (src.type() == CV_8UC3);
    //--- INITIALIZE VIDEOWRITER
    VideoWriter writer;
    int codec = VideoWriter::fourcc('M', 'J', 'P', 'G');  // select desired codec (must be available at runtime)
    double fps = 25.0;                          // framerate of the created video stream
    string filename = "./live.avi";             // name of the output video file
    writer.open(filename, codec, fps, src.size(), isColor);
    // check if we succeeded
    if (!writer.isOpened()) {
        cerr << "Could not open the output video file for write\n";
        return -1;
    }
    //--- GRAB AND WRITE LOOP
    cout << "Writing videofile: " << filename << endl
         << "Press any key to terminate" << endl;
    for (;;)
    {
        // check if we succeeded
        if (!cap.read(src)) {
            cerr << "ERROR! blank frame grabbed\n";
            break;
        }
        // encode the frame into the videofile stream
        writer.write(src);
        // show live and wait for a key with timeout long enough to show images
        imshow("Live", src);
        if (waitKey(5) >= 0)
            break;
    }
    // the videofile will be closed and released automatically in VideoWriter destructor
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值