Opencv学习笔记(八)视频流2
来源:互联网 发布:obs直播软件 清晰度 编辑:程序博客网 时间:2024/06/05 21:01
用类封装了下视频的读取(可以是视频文件也可以是图片序列),处理,以及写入文件(可以是视频文件也可以是图片序列)。
代码如下:
#include "opencv2/opencv.hpp"#include <sstream>#include <iomanip>using namespace std;using namespace cv;class FrameProcessor;class FrameProcessor{ public: virtual void process(Mat &input,Mat &ouput);};class VideoProcessor{private: VideoCapture caputure; //写视频流对象 VideoWriter writer; //输出文件名 string Outputfile; int currentIndex; int digits; string extension; FrameProcessor *frameprocessor; //图像处理函数指针 void (*process)(Mat &,Mat &); bool callIt; string WindowNameInput; string WindowNameOutput; //延时 int delay; long fnumber; //第frameToStop停止 long frameToStop; //暂停标志 bool stop; //图像序列作为输入视频流 vector<string> images; //迭代器public: VideoProcessor() : callIt(true),delay(0),fnumber(0),stop(false),digits(0),frameToStop(-1){} //设置图像处理函数 void setFrameProcessor(void (*process)(Mat &,Mat &)){ frameprocessor = 0; this->process = process; CallProcess (); } //打开视频 bool setInput(string filename){ fnumber = 0; //若已打开,释放重新打开 caputure.release (); return caputure.open (filename); } //设置输入视频播放窗口 void displayInput(string wn){ WindowNameInput = wn; namedWindow (WindowNameInput); } //设置输出视频播放窗口 void displayOutput(string wn){ WindowNameOutput = wn; namedWindow (WindowNameOutput); } //销毁窗口 void dontDisplay(){ destroyWindow (WindowNameInput); destroyWindow (WindowNameOutput); WindowNameInput.clear (); WindowNameOutput.clear (); } //启动 void run(){ Mat frame; Mat output; if(!isOpened()) return; stop = false; while(!isStopped()){ //读取下一帧 if(!readNextFrame(frame)) break; if(WindowNameInput.length ()!=0) imshow (WindowNameInput,frame); //处理该帧 if(callIt){ if(process) process(frame,output); else if(frameprocessor) frameprocessor->process (frame,output); } else{ output = frame; } if(Outputfile.length ()){ cvtColor (output,output,CV_GRAY2RGB); writeNextFrame (output); } if(WindowNameOutput.length ()!=0) imshow (WindowNameOutput,output); //按键暂停,继续按键继续 if(delay>=0&&waitKey (delay)>=0) waitKey(0); //到达指定暂停键,退出 if(frameToStop>=0&&getFrameNumber()==frameToStop) stopIt(); } } //暂停键置位 void stopIt(){ stop = true; } //查询暂停标志位 bool isStopped(){ return stop; } //返回视频打开标志 bool isOpened(){ return caputure.isOpened ()||!images.empty (); } //设置延时 void setDelay(int d){ delay = d; } //读取下一帧 bool readNextFrame(Mat &frame){ if(images.size ()==0) return caputure.read (frame); else{ if(itImg!=images.end()){ frame = imread (*itImg); itImg++; return frame.data?1:0; } else return false; } } void CallProcess(){ callIt = true; } void dontCallProcess(){ callIt = false; } //设置停止帧 void stopAtFrameNo(long frame){ frameToStop = frame; } // 获得当前帧的位置 long getFrameNumber(){ long fnumber = static_cast<long>(caputure.get ((CV_CAP_PROP_POS_FRAMES))); return fnumber; } //获得帧大小 Size getFrameSize() { if (images.size()==0) { // 从视频流获得帧大小 int w= static_cast<int>(caputure.get(CV_CAP_PROP_FRAME_WIDTH)); int h= static_cast<int>(caputure.get(CV_CAP_PROP_FRAME_HEIGHT)); return Size(w,h); } else { //从图像获得帧大小 cv::Mat tmp= cv::imread(images[0]); return (tmp.data)?(tmp.size()):(Size(0,0)); } } //获取帧率 double getFrameRate(){ return caputure.get(CV_CAP_PROP_FPS); } vector<string>::const_iterator itImg; bool setInput (const vector<string> &imgs){ fnumber = 0; caputure.release (); images = imgs; itImg = images.begin (); return true; } void setFrameProcessor(FrameProcessor *frameprocessor){ process = 0; this->frameprocessor = frameprocessor; CallProcess (); } //获得编码类型 int getCodec(char codec[4]) { if (images.size()!=0) return -1; union { // 数据结构4-char int value; char code[4]; } returned; //获得编码值 returned.value= static_cast<int>( caputure.get(CV_CAP_PROP_FOURCC)); // get the 4 characters codec[0]= returned.code[0]; codec[1]= returned.code[1]; codec[2]= returned.code[2]; codec[3]= returned.code[3]; return returned.value; } bool setOutput(const string &filename,int codec = 0,double framerate = 0.0,bool isColor = true){ //设置文件名 Outputfile = filename; //清空扩展名 extension.clear (); //设置帧率 if(framerate ==0.0){ framerate = getFrameRate (); } //获取输入原视频的编码方式 char c[4]; if(codec==0){ codec = getCodec(c); } return writer.open(Outputfile, codec, framerate, getFrameSize(), isColor); } //输出视频帧到图片fileme+currentIndex.ext,如filename001.jpg bool setOutput (const string &filename,//路径 const string &ext,//扩展名 int numberOfDigits=3,//数字位数 int startIndex=0 ){//起始索引 if(numberOfDigits<0) return false; Outputfile = filename; extension = ext; digits = numberOfDigits; currentIndex = startIndex; return true; } //写下一帧 void writeNextFrame(Mat &frame){ //如果扩展名不为空,写到图片文件中 if(extension.length ()){ stringstream ss; ss<<Outputfile<<setfill('0')<<setw(digits)<<currentIndex++<<extension; imwrite (ss.str (),frame); } //反之,写到视频文件中 else{ writer.write (frame); } }};//帧处理函数:canny边缘检测void canny(cv::Mat& img, cv::Mat& out) { //灰度变换 if (img.channels()==3) cvtColor(img,out,CV_BGR2GRAY); // canny算子求边缘 Canny(out,out,100,200); //颜色反转,看起来更舒服些 threshold(out,out,128,255,cv::THRESH_BINARY_INV);}int main(int argc, char *argv[]){ VideoProcessor processor; //打开输入视频 processor.setInput ("bike.avi"); processor.displayInput ("Current Frame"); processor.displayOutput ("Output Frame"); //设置每一帧的延时 processor.setDelay (1000./processor.getFrameRate ()); //设置帧处理函数,可以任意 processor.setFrameProcessor (canny ); processor.setOutput ("./bikeout.avi");// processor.setOutput ("bikeout",".jpg"); processor.run (); return 0;}
- Opencv学习笔记(八)视频流2
- opencv学习笔记(八)彩色视频转换成黑白视频
- OpenCV学习笔记2-视频
- opencv学习笔记(八)-IplImage数据结构
- 软件工程视频学习笔记(八)
- 张孝祥java视频学习笔记(八)
- OpenCV学习笔记之八(保存视频,录制视频,cvLoadImage的路径)
- OpenCV笔记(八)
- OpenCV python 学习笔记(八)
- Opencv学习笔记(七)视频流1
- opencv(C++)视频流读入-学习笔记3
- 【opencv学习笔记2】播放AVI视频
- openCV学习笔记(3)-- 写入视频
- opencv学习笔记(二)播放视频
- OpenCV学习笔记(02) :OpenCV拍摄视频并保存
- 【OpenCV学习笔记】【函数学习】八(序列数据结构)
- Opencv学习笔记----读取视频
- OpenCV学习笔记--视频读写
- Exercises 2-7
- SQL编程 行转列
- JavaScript面向对象特性
- Exercises 2-6
- Visual Studio 2008 使用 WinCE 5.0 Emulator
- Opencv学习笔记(八)视频流2
- android 使用timer
- 使用jQuery插件实现添加用户
- 位操作
- [c/c++] C++库资源
- 用jquery实现全选、全不选、反选 //很好用//
- Python_API_File and Directory Access_os.path.expanduser
- java---多态--php的框架---tp
- 数据库(三)数据库基础之数据库语言