C++,OpenCV视频操作(9)
  Jk5625xsZPHl 2023年11月02日 64 0

opencv里对视频的编码解码等支持并不是很良好,所以不要希望用opencv 做多媒体开发,opencv是一个强大的计算机视觉库,而不是视频流编码器或者解码器。希望大家不要走入这个误区,可以把这部分简单单独看待。而且生成的视频文件不能大于2GB,而且不能添加音频。如果想搞音视频处理可以使用FFmpeg库。

视频读取

opencv中通过VideoCaptrue类对视频进行读取操作以及调用摄像头,类如下

class CV_EXPORTS_W VideoCapture
{
public:
    VideoCapture();
    explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY);
    explicit VideoCapture(const String& filename, int apiPreference, const std::vector<int>& params);
    explicit VideoCapture(int index, int apiPreference = CAP_ANY);
    explicit VideoCapture(int index, int apiPreference, const std::vector<int>& params);
    virtual ~VideoCapture();
    virtual bool open(const String& filename, int apiPreference = CAP_ANY);
    virtual bool open(const String& filename, int apiPreference, const std::vector<int>& params);
    virtual bool open(int index, int apiPreference = CAP_ANY);
    virtual bool open(int index, int apiPreference, const std::vector<int>& params);
    virtual bool isOpened() const;
    virtual void release();
    virtual bool grab();
    virtual bool retrieve(OutputArray image, int flag = 0);
    virtual VideoCapture& operator >> (CV_OUT Mat& image);
    virtual VideoCapture& operator >> (CV_OUT UMat& image);
    virtual bool read(OutputArray image);
    virtual bool set(int propId, double value);
    virtual double get(int propId) const;
    String getBackendName() const;
    void setExceptionMode(bool enable) { throwOnFail = enable; }
    bool getExceptionMode() { return throwOnFail; }
    bool waitAny(const std::vector<VideoCapture>& streams,CV_OUT std::vector<int>& readyIndex,int64 timeoutNs = 0);
protected:
    Ptr<CvCapture> cap;
    Ptr<IVideoCapture> icap;
    bool throwOnFail;
    friend class internal::VideoCapturePrivateAccessor;
};

打开视频与捕获设备

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main() 
{
	VideoCapture cap = VideoCapture("test.mp4");
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	VideoCapture camera = VideoCapture(0);
	if (!camera.isOpened()) 
	{
		cout << "摄像头打开失败!" << endl;
		return 0;
	}
	return 0;
}

获取视频属性

获得视频有诸多属性,比如:帧率、总帧数、尺寸、格式等

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;


int main() 
{
	VideoCapture cap = VideoCapture("test.mp4");
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	cout << "宽度:" << cap.get(CAP_PROP_FRAME_WIDTH) << endl;
	cout << "高度:" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
	cout << "帧数:" << cap.get(CAP_PROP_FRAME_COUNT) << endl;
	cout << "帧率:" << cap.get(CAP_PROP_FPS) << endl;

	//VideoCapture camera = VideoCapture(0);
	//if (!camera.isOpened()) 
	//{
	//	cout << "摄像头打开失败!" << endl;
	//	return 0;
	//}
	return 0;
}

其他属性获取

enum VideoCaptureProperties {
       CAP_PROP_POS_MSEC       =0, //视频文件的当前位置,单位为毫秒  
       CAP_PROP_POS_FRAMES     =1, //解码/捕获的帧的基于0的索引
       CAP_PROP_POS_AVI_RATIO  =2, //视频文件的相对位置:0=影片开始,1=影片结束
       CAP_PROP_FRAME_WIDTH    =3, //视频宽度
       CAP_PROP_FRAME_HEIGHT   =4, //视频高度
       CAP_PROP_FPS            =5, //帧率
       CAP_PROP_FOURCC         =6, //4个字符的编解码器代码
       CAP_PROP_FRAME_COUNT    =7, //视频文件中的帧数
       CAP_PROP_FORMAT         =8, //视频格式
                                  
       CAP_PROP_MODE           =9, 
       CAP_PROP_BRIGHTNESS    =10, //图像亮度(摄像模式)
       CAP_PROP_CONTRAST      =11, //图像对比度(摄像模式)
       CAP_PROP_SATURATION    =12, //图像饱和度(摄像模式)
       CAP_PROP_HUE           =13, //图像的色调(摄像模式)
       CAP_PROP_GAIN          =14, //图像增益(摄像模式)
       CAP_PROP_EXPOSURE      =15, //曝光(摄像模式)
       CAP_PROP_CONVERT_RGB   =16, //图像是否应该转换为RGB的布尔标记
                                   
       CAP_PROP_WHITE_BALANCE_BLUE_U =17,
       CAP_PROP_RECTIFICATION =18, 
       CAP_PROP_MONOCHROME    =19,
       CAP_PROP_SHARPNESS     =20,
       CAP_PROP_AUTO_EXPOSURE =21, 
       CAP_PROP_GAMMA         =22,
       CAP_PROP_TEMPERATURE   =23,
       CAP_PROP_TRIGGER       =24,
       CAP_PROP_TRIGGER_DELAY =25,
       CAP_PROP_WHITE_BALANCE_RED_V =26,
       CAP_PROP_ZOOM          =27,
       CAP_PROP_FOCUS         =28,
       CAP_PROP_GUID          =29,
       CAP_PROP_ISO_SPEED     =30,
       CAP_PROP_BACKLIGHT     =32,
       CAP_PROP_PAN           =33,
       CAP_PROP_TILT          =34,
       CAP_PROP_ROLL          =35,
       CAP_PROP_IRIS          =36,
       CAP_PROP_SETTINGS      =37, 
       CAP_PROP_BUFFERSIZE    =38,
       CAP_PROP_AUTOFOCUS     =39,
       CAP_PROP_SAR_NUM       =40, 
       CAP_PROP_SAR_DEN       =41, 
       CAP_PROP_BACKEND       =42, 
       CAP_PROP_CHANNEL       =43, 
       CAP_PROP_AUTO_WB       =44, 
       CAP_PROP_WB_TEMPERATURE=45, 
       CAP_PROP_CODEC_PIXEL_FORMAT =46,    
       CAP_PROP_BITRATE       =47, 
       CAP_PROP_ORIENTATION_META=48, 
       CAP_PROP_ORIENTATION_AUTO=49, 
       CAP_PROP_HW_ACCELERATION=50, 
       CAP_PROP_HW_DEVICE      =51, 
       CAP_PROP_HW_ACCELERATION_USE_OPENCL=52, 
       CAP_PROP_OPEN_TIMEOUT_MSEC=53, 
       CAP_PROP_READ_TIMEOUT_MSEC=54, 
       CAP_PROP_STREAM_OPEN_TIME_USEC =55, 
       CAP_PROP_VIDEO_TOTAL_CHANNELS = 56, 
       CAP_PROP_VIDEO_STREAM = 57, 
       CAP_PROP_AUDIO_STREAM = 58, 
       CAP_PROP_AUDIO_POS = 59, 
       CAP_PROP_AUDIO_SHIFT_NSEC = 60, 
       CAP_PROP_AUDIO_DATA_DEPTH = 61, 
       CAP_PROP_AUDIO_SAMPLES_PER_SECOND = 62, 
       CAP_PROP_AUDIO_BASE_INDEX = 63, 
       CAP_PROP_AUDIO_TOTAL_CHANNELS = 64, 
       CAP_PROP_AUDIO_TOTAL_STREAMS = 65, 
       CAP_PROP_AUDIO_SYNCHRONIZE = 66, 
       CAP_PROP_LRF_HAS_KEY_FRAME = 67,
       CAP_PROP_CODEC_EXTRADATA_INDEX = 68,
#ifndef CV_DOXYGEN
       CV__CAP_PROP_LATEST
#endif
     };

视频转图像

视频转图像显示

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;


int main() 
{
	VideoCapture cap = VideoCapture("test.mp4");
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	Mat img;
	while (true) 
	{
		cap >> img;		//flip
		if (img.empty()) 
		{
			break;
		}
		imshow("图像", img);
		waitKey(30);
	}
	cap.release();
	return 0;
}

视频转图像显示

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;


int main() 
{
	VideoCapture cap = VideoCapture("test.mp4");
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	Mat img;
	int index = 1;
	while (true) 
	{
		cap >> img;		//flip
		if (img.empty()) 
		{
			break;
		}
		//imshow("图像", img);
		string name = "mm/img" + to_string(index++) + ".jpg";
		imwrite(name, img);
		waitKey(30);
	}
	cap.release();
	return 0;
}

摄像头转图像

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() 
{
	VideoCapture cap = VideoCapture(0);
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	Mat img;
	int index = 1;
	while (true) 
	{
		cap >> img;		
		if (img.empty()) 
		{
			break;
		}
		imshow("图像", img);
		waitKey(30);
	}
	cap.release();
	return 0;
}

视频保存

opencv中通过VideoWriter类对视频进行读取操作以及调用摄像头,该类的API与VideoCapture类似,该类的主要API除了构造函数外,提供了open、isOpened、release、write和重载操作符<<

class CV_EXPORTS_W VideoWriter
{
public:
    CV_WRAP VideoWriter();
    CV_WRAP VideoWriter(const String& filename, int fourcc, double fps,
                Size frameSize, bool isColor = true);
    CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
                Size frameSize, bool isColor = true);
    CV_WRAP VideoWriter(const String& filename, int fourcc, double fps, const Size& frameSize,
                        const std::vector<int>& params);
    CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
                        const Size& frameSize, const std::vector<int>& params);
    virtual ~VideoWriter();
    CV_WRAP virtual bool open(const String& filename, int fourcc, double fps,
                      Size frameSize, bool isColor = true);
    CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
                      Size frameSize, bool isColor = true);
    CV_WRAP bool open(const String& filename, int fourcc, double fps, const Size& frameSize,
                      const std::vector<int>& params);
    CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
                      const Size& frameSize, const std::vector<int>& params);
    CV_WRAP virtual bool isOpened() const;
    CV_WRAP virtual void release();
    virtual VideoWriter& operator << (const Mat& image);
    virtual VideoWriter& operator << (const UMat& image);
    CV_WRAP virtual void write(InputArray image);
    CV_WRAP virtual bool set(int propId, double value);
    CV_WRAP virtual double get(int propId) const;
    CV_WRAP static int fourcc(char c1, char c2, char c3, char c4);

    CV_WRAP String getBackendName() const;

protected:
    Ptr<CvVideoWriter> writer;
    Ptr<IVideoWriter> iwriter;

    static Ptr<IVideoWriter> create(const String& filename, int fourcc, double fps,
                                    Size frameSize, bool isColor = true);
};

摄像头转视频保存

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() 
{
	VideoCapture cap = VideoCapture(0);
	if(!cap.isOpened())
	{
		cout << "打开失败!" << endl;
		return 0;
	}
	int width = cap.get(CAP_PROP_FRAME_WIDTH);
	int height = cap.get(CAP_PROP_FRAME_HEIGHT);
	VideoWriter save;
	save.open("save.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(width, height), true);
	Mat img;
	while (true) 
	{
		cap >> img;
		imshow("摄像头", img);
		save << img;
		//按ESC退出
		if (waitKey(10) == 27) 
		{
			break;
		}
	}
	cap.release();
	save.release();
	return 0;
}

综合代码

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
class Video 
{
public:
	Video();
	~Video();
	void GetVideo(string fileName = "test.mp4");
	void SaveToVideo(string fileName = "out.avi");
	void SaveToImg(string preName = "mm/img");
	void Camera(string fileName = "录像.avi");


protected:
	VideoCapture cap;
	VideoWriter save;
};
Video::Video()
{

}
Video::~Video()
{
	cap.release();
	save.release();
}
void Video::GetVideo(string fileName)
{
	cap = VideoCapture(fileName);
	if (!cap.isOpened()) 
	{
		cout << "视频获取失败!" << endl;
	}
}

void Video::SaveToVideo(string fileName)
{
	int w = cap.get(CAP_PROP_FRAME_WIDTH);
	int h = cap.get(CAP_PROP_FRAME_HEIGHT);
	int fps = cap.get(CAP_PROP_FPS);
	save.open(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(w, h), true);
	Mat img;
	while (true) 
	{
		cap >> img;
		if (img.empty())
			break;
		save << img;
	}
}

void Video::SaveToImg(string preName)
{
	Mat img;
	int index = 0;
	string name;
	while (true)
	{
		cap >> img;
		if (img.empty())
		{
			break;
		}
		name = preName + to_string(index++) + ".jpg";
		imwrite(name, img);
	}
}

void Video::Camera(string fileName)
{
	cap = VideoCapture(0);
	if (!cap.isOpened()) 
	{
		cout << "摄像头打开失败!" << endl;
		return;
	}
	int w = cap.get(CAP_PROP_FRAME_WIDTH);
	int h = cap.get(CAP_PROP_FRAME_HEIGHT);
	save.open(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(w, h), true);
	Mat img;
	while (true)
	{
		cap >> img;
		imshow("摄像头", img);
		save << img;
		if (waitKey(10) == 27) 
		{
			break;
		}
	}
}


int main()
{
	Video* pvideo = new Video;
	pvideo->GetVideo();
	pvideo->SaveToImg();

	pvideo->GetVideo();
	pvideo->SaveToVideo();

	pvideo->Camera();
	delete pvideo;
	return 0;
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  gBkHYLY8jvYd   2023年12月06日   50   0   0 #includecii++
  gBkHYLY8jvYd   2023年12月10日   18   0   0 #include邻域灰度图像
  gBkHYLY8jvYd   2023年12月10日   22   0   0 #include数组i++
  gBkHYLY8jvYd   2023年12月06日   19   0   0 #includeios数据
  gBkHYLY8jvYd   2023年12月08日   20   0   0 #includecii++
Jk5625xsZPHl