zoukankan      html  css  js  c++  java
  • OpenCV处理视频序列的类

    代码出处,opencv2 cookbook:

    /*------------------------------------------------------------------------------------------*
       This file contains material supporting chapter 10 of the cookbook:  
       Computer Vision Programming using the OpenCV Library. 
       by Robert Laganiere, Packt Publishing, 2011.
    
       This program is free software; permission is hereby granted to use, copy, modify, 
       and distribute this source code, or portions thereof, for any purpose, without fee, 
       subject to the restriction that the copyright notice may not be removed 
       or altered from any source or altered source distribution. 
       The software is released on an as-is basis and without any warranties of any kind. 
       In particular, the software is not guaranteed to be fault-tolerant or free from failure. 
       The author disclaims all warranties with regard to this software, any use, 
       and any consequent failure, is purely the responsibility of the user.
     
       Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
    *------------------------------------------------------------------------------------------*/
    
    #if !defined VPROCESSOR
    #define VPROCESSOR
    
    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    #include <iostream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    
    
    
    #pragma comment(lib,"opencv_core2410d.lib")  
    #pragma comment(lib,"opencv_highgui2410d.lib")  
    #pragma comment(lib,"opencv_imgproc2410d.lib")  
    
    
    
    // The frame processor interface
    class FrameProcessor {
    
      public:
    	// processing method
    	virtual void process(cv:: Mat &input, cv:: Mat &output)= 0;
    };
    
    class VideoProcessor {
    
      private:
    
    	  // the OpenCV video capture object
    	  cv::VideoCapture capture;
    	  // the callback function to be called 
    	  // for the processing of each frame
    	  void (*process)(cv::Mat&, cv::Mat&);
    	  // the pointer to the class implementing 
    	  // the FrameProcessor interface
    	  FrameProcessor *frameProcessor;
    	  // a bool to determine if the 
    	  // process callback will be called .是否使用回调函数的bool变量
    	  bool callIt;
    	  // Input display window name
    	  std::string windowNameInput;
    	  // Output display window name
    	  std::string windowNameOutput;
    	  // delay between each frame processing
    	  int delay;
    	  // number of processed frames 
    	  long fnumber;
    	  // stop at this frame number
    	  long frameToStop;
    	  // to stop the processing
    	  bool stop;
    
    	  // vector of image filename to be used as input
    	  std::vector<std::string> images; 
    	  // image vector iterator
    	  std::vector<std::string>::const_iterator itImg;
    
    	  // the OpenCV video writer object
    	  cv::VideoWriter writer;
    	  // output filename
    	  std::string outputFile;
    
    	  // current index for output images
    	  int currentIndex;
    	  // number of digits in output image filename
    	  int digits;
    	  // extension of output images
    	  std::string extension;
    
    	  // to get the next frame 
    	  // could be: video file; camera; vector of images
    	  bool readNextFrame(cv::Mat& frame)
    	  {
    
    		  if (images.size()==0)
    			  return capture.read(frame);
    		  else {
    
    			  if (itImg != images.end()) 
    			  {
    
    				  frame= cv::imread(*itImg);
    				  itImg++;
    				  return frame.data != 0;
    			  }
    		  }
    	  }
    
    	  // to write the output frame 
    	  // could be: video file or images
    	  void writeNextFrame(cv::Mat& frame)
    	  {
    
    		  if (extension.length()) { // then we write images
    		  
    			  std::stringstream ss;
    		      ss << outputFile << std::setfill('0') << std::setw(digits) << currentIndex++ << extension;
    			  cv::imwrite(ss.str(),frame);
    
    		  } 
    		  else 
    		  { // then write video file
    
    			  writer.write(frame);
    		  }
    	  }
    
      public:
    
    	  // Constructor setting the default values
    	  VideoProcessor() : callIt(false), delay(-1), 
    		  fnumber(0), stop(false), digits(0), frameToStop(-1), 
    	      process(0), frameProcessor(0) {}
    
    	  // set the name of the video file
    	  bool setInput(std::string filename) {
    
    		fnumber= 0;
    		// In case a resource was already 
    		// associated with the VideoCapture instance
    		capture.release();
    		images.clear();
    
    		// Open the video file
    		return capture.open(filename);
    	  }
    
    	  // set the camera ID
    	  bool setInput(int id)
    	  {
    
    		fnumber= 0;
    		// In case a resource was already 
    		// associated with the VideoCapture instance
    		capture.release();
    		images.clear();
    
    		// Open the video file
    		return capture.open(id);
    	  }
    
    	  // set the vector of input images
    	  bool setInput(const std::vector<std::string>& imgs) 
    	  {
    
    		fnumber= 0;
    		// In case a resource was already 
    		// associated with the VideoCapture instance
    		capture.release();
    
    		// the input will be this vector of images
    		images= imgs;
    		itImg= images.begin();
    
    		return true;
    	  }
    
    	  // set the output video file
    	  // by default the same parameters than input video will be used
    	  bool setOutput(const std::string &filename, int codec=0, double framerate=0.0, bool isColor=true) 
    	  {
    
    		  outputFile= filename;
    		  extension.clear();
    		  
    		  if (framerate==0.0) 
    			  framerate= getFrameRate(); // same as input
    
    		  char c[4];
    		  // use same codec as input
    		  if (codec==0) { 
    			  codec= getCodec(c);
    		  }
    
    		  // Open output video
    		  return writer.open(outputFile, // filename
    			  codec, // codec to be used 
    			  framerate,      // frame rate of the video
    			  getFrameSize(), // frame size
    			  isColor);       // color video?
    	  }
    
    	  // set the output as a series of image files
    	  // extension must be ".jpg", ".bmp" ...
    	  bool setOutput(const std::string &filename, // filename prefix
    		  const std::string &ext, // image file extension 
    		  int numberOfDigits=3,   // number of digits
    		  int startIndex=0) 
    		  {     // start index
    
    		  // number of digits must be positive
    		  if (numberOfDigits<0)
    			  return false;
    
    		  // filenames and their common extension
    		  outputFile= filename;
    		  extension= ext;
    
    		  // number of digits in the file numbering scheme
    		  digits= numberOfDigits;
    		  // start numbering at this index
    		  currentIndex= startIndex;
    
    		  return true;
    	  }
    
    	  // set the callback function that will be called for each frame
    	  void setFrameProcessor(void (*frameProcessingCallback)(cv::Mat&, cv::Mat&))
    	  {
    
    		  // invalidate frame processor class instance
    		  frameProcessor= 0;
    		  // this is the frame processor function that will be called
    		  process= frameProcessingCallback;
    		  callProcess();
    	  }
    
    	  // set the instance of the class that implements the FrameProcessor interface
    	  void setFrameProcessor(FrameProcessor* frameProcessorPtr)
    	  {
    
    		  // invalidate callback function
    		  process= 0;
    		  // this is the frame processor instance that will be called
    		  frameProcessor= frameProcessorPtr;
    		  callProcess();
    	  }
    
    	  // stop streaming at this frame number
    	  void stopAtFrameNo(long frame)
    	  {
    
    		  frameToStop= frame;
    	  }
    
    	  // process callback to be called
    	  void callProcess()
    	  {
    
    		  callIt= true;
    	  }
    
    	  // do not call process callback
    	  void dontCallProcess()
    	  {
    
    		  callIt= false;
    	  }
    
    	  // to display the processed frames
    	  void displayInput(std::string wn)
    	  {
    	    
    		  windowNameInput= wn;
    		  cv::namedWindow(windowNameInput);
    	  }
    
    	  // to display the processed frames
    	  void displayOutput(std::string wn)
    	  {
    	    
    		  windowNameOutput= wn;
    		  cv::namedWindow(windowNameOutput);
    	  }
    
    	  // do not display the processed frames
    	  void dontDisplay()
    	  {
    
    		  cv::destroyWindow(windowNameInput);
    		  cv::destroyWindow(windowNameOutput);
    		  windowNameInput.clear();
    		  windowNameOutput.clear();
    	  }
    
    	  // set a delay between each frame
    	  // 0 means wait at each frame
    	  // negative means no delay
    	  void setDelay(int d) 
    	  {
    	  
    		  delay= d;
    	  }
    
    	  // a count is kept of the processed frames
    	  long getNumberOfProcessedFrames()
    	  {
    	  
    		  return fnumber;
    	  }
    
    	  // return the size of the video frame
    	  cv::Size getFrameSize() 
    	  {
    
    		if (images.size()==0) 
    		{
    
    			// get size of from the capture device
    			int w= static_cast<int>(capture.get(CV_CAP_PROP_FRAME_WIDTH));
    			int h= static_cast<int>(capture.get(CV_CAP_PROP_FRAME_HEIGHT));
    
    			return cv::Size(w,h);
    
    		}
    		else
    		{ // if input is vector of images
    
    			cv::Mat tmp= cv::imread(images[0]);
    			if (!tmp.data) return cv::Size(0,0);
    			else return tmp.size();
    		}
    	  }
    
    	  // return the frame number of the next frame
    	  long getFrameNumber()
    	  {
    
    		if (images.size()==0) 
    		{
    
    			// get info of from the capture device
    	 	    long f= static_cast<long>(capture.get(CV_CAP_PROP_POS_FRAMES));
    		    return f; 
    
    		} else { // if input is vector of images
    
    			return static_cast<long>(itImg-images.begin());
    		}
    	  }
    
    	  // return the position in ms
    	  double getPositionMS()
    	  {
    
    		  // undefined for vector of images
    		  if (images.size()!=0) return 0.0;
    
    	 	  double t= capture.get(CV_CAP_PROP_POS_MSEC);
    		  return t; 
    	  }
    
    	  // return the frame rate
    	  double getFrameRate() 
    	  {
    
    		  // undefined for vector of images
    		  if (images.size()!=0) return 0;
    
    	 	  double r= capture.get(CV_CAP_PROP_FPS);
    		  return r; 
    	  }
    
    	  // return the number of frames in video
    	  long getTotalFrameCount() 
    	  {
    
    		  // for vector of images
    		  if (images.size()!=0) return images.size();
    
    	 	  long t= capture.get(CV_CAP_PROP_FRAME_COUNT);
    		  return t; 
    	  }
    
    	  // get the codec of input video
    	  int getCodec(char codec[4])
    	  {
    
    		  // undefined for vector of images
    		  if (images.size()!=0) return -1;
    
    		  union {
    			  int value;
    			  char code[4]; } returned;
    
    		  returned.value= static_cast<int>(capture.get(CV_CAP_PROP_FOURCC));
    
    		  codec[0]= returned.code[0];
    		  codec[1]= returned.code[1];
    		  codec[2]= returned.code[2];
    		  codec[3]= returned.code[3];
    
    		  return returned.value;
    	  }
    	  
    	  // go to this frame number
    	  bool setFrameNumber(long pos)
    	  {
    
    		  // for vector of images
    		  if (images.size()!=0)
    		  {
    
    			  // move to position in vector
    			  itImg= images.begin() + pos;
    			  // is it a valid position?
    			  if (pos < images.size())
    				  return true;
    			  else
    				  return false;
    
    		  }
    		  else
    		  { // if input is a capture device
    
    			return capture.set(CV_CAP_PROP_POS_FRAMES, pos);
    		  }
    	  }
    
    	  // go to this position
    	  bool setPositionMS(double pos)
    	  {
    
    		  // not defined in vector of images
    		  if (images.size()!=0) 
    			  return false;
    		  else 
    		      return capture.set(CV_CAP_PROP_POS_MSEC, pos);
    	  }
    
    	  // go to this position expressed in fraction of total film length
    	  bool setRelativePosition(double pos)
    	  {
    
    		  // for vector of images
    		  if (images.size()!=0)
    		  {
    
    			  // move to position in vector
    			  long posI= static_cast<long>(pos*images.size()+0.5);
    			  itImg= images.begin() + posI;
    			  // is it a valid position?
    			  if (posI < images.size())
    				  return true;
    			  else
    				  return false;
    
    		  } 
    		  else 
    		  { // if input is a capture device
    
    			  return capture.set(CV_CAP_PROP_POS_AVI_RATIO, pos);
    		  }
    	  }
    
    	  // Stop the processing
    	  void stopIt()
    	  {
    
    		  stop= true;
    	  }
    
    	  // Is the process stopped?
    	  bool isStopped()
    	  {
    
    		  return stop;
    	  }
    
    	  // Is a capture device opened?
    	  bool isOpened() 
    	  {
    
    		  return capture.isOpened() || !images.empty();
    	  }
    	  
    	  // to grab (and process) the frames of the sequence
    	  void run()
    	  {
    
    		  // current frame
    		  cv::Mat frame;
    		  // output frame
    		  cv::Mat output;
    
    		  // if no capture device has been set
    		  if (!isOpened())
    			  return;
    
    		  stop= false;
    
    		  while (!isStopped())
    		  {
    
    			  // read next frame if any
    			  if (!readNextFrame(frame))
    				  break;
    
    			  // display input frame
    			  if (windowNameInput.length()!=0) 
    				  cv::imshow(windowNameInput,frame);
    
    		      // calling the process function or method
    			  if (callIt)
    			  {
    				  
    				// process the frame
    				if (process)
    				    process(frame, output);
    				else if (frameProcessor) 
    					frameProcessor->process(frame,output);
    				// increment frame number
    			    fnumber++;
    
    			  } 
    			  else 
    			  {
    
    				output= frame;
    			  }
    
    			  // write output sequence
    			  if (outputFile.length()!=0)
    				  writeNextFrame(output);
    
    			  // display output frame
    			  if (windowNameOutput.length()!=0) 
    				  cv::imshow(windowNameOutput,output);
    			
    			  // introduce a delay
    			  if (delay>=0 && cv::waitKey(delay)>=0)
    				stopIt();
    
    			  // check if we should stop
    			  if (frameToStop>=0 && getFrameNumber()==frameToStop)
    				  stopIt();
    		  }
    	  }
    };
    
    #endif
    


     

    /*------------------------------------------------------------------------------------------*
       This file contains material supporting chapter 10 of the cookbook:  
       Computer Vision Programming using the OpenCV Library. 
       by Robert Laganiere, Packt Publishing, 2011.
    
       This program is free software; permission is hereby granted to use, copy, modify, 
       and distribute this source code, or portions thereof, for any purpose, without fee, 
       subject to the restriction that the copyright notice may not be removed 
       or altered from any source or altered source distribution. 
       The software is released on an as-is basis and without any warranties of any kind. 
       In particular, the software is not guaranteed to be fault-tolerant or free from failure. 
       The author disclaims all warranties with regard to this software, any use, 
       and any consequent failure, is purely the responsibility of the user.
     
       Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
    *------------------------------------------------------------------------------------------*/
    
    
    #include "videoprocessor.h"
    
    void draw(cv::Mat& img, cv::Mat& out) 
    {
    
    	img.copyTo(out);
    	cv::circle(out, cv::Point(100,100),5,cv::Scalar(255,0,0),2);
    }
    
    void canny(cv::Mat& img, cv::Mat& out) {
    
    	// Convert to gray
    	cv::cvtColor(img,out,CV_BGR2GRAY);
    	// Compute Canny edges
    	cv::Canny(out,out,100,200);
    	// Invert the image
    	cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
    }
    
    int main()
    {
    	// Open the video file
        cv::VideoCapture capture("../bike.avi");
    	// check if video successfully opened
    	if (!capture.isOpened())
    		return 1;
    
    	// Get the frame rate
    	double rate= capture.get(CV_CAP_PROP_FPS);
    
    	bool stop(false);
    	cv::Mat frame; // current video frame
    	cv::namedWindow("Extracted Frame");
    
    	// Delay between each frame
    	// corresponds to video frame rate
    	int delay= 1000/rate;
    
    	// for all frames in video
    	while (!stop) {
    
    		// read next frame if any
    		if (!capture.read(frame))
    			break;
    
    		cv::imshow("Extracted Frame",frame);
    
    		// introduce a delay
    		// or press key to stop
    		if (cv::waitKey(delay)>=0)
    				stop= true;
    	}
    
    	// Close the video file
    	capture.release();
    
    	cv::waitKey();
    		
    	// Now using the VideoProcessor class
    
    	// Create instance
    	VideoProcessor processor;
    	// Open video file
    	processor.setInput("../bike.avi");
    	// Declare a window to display the video
    	processor.displayInput("Input Video");
    	processor.displayOutput("Output Video");
    	// Play the video at the original frame rate
    	processor.setDelay(1000./processor.getFrameRate());
    	// Set the frame processor callback function
    	processor.setFrameProcessor(canny);
    	// Start the process
    	processor.run();
    	cv::waitKey();
    	
    	// Second test
    	// Create instance
        //	VideoProcessor processor;
    	// Open video file
    	processor.setInput("../bike.avi");
    
    	// Get basic info about video file
    	cv::Size size= processor.getFrameSize();
    	std::cout << size.width << " " << size.height << std::endl;
    	std::cout << processor.getFrameRate() << std::endl;
    	std::cout << processor.getTotalFrameCount() << std::endl;
    	std::cout << processor.getFrameNumber() << std::endl;
    	std::cout << processor.getPositionMS() << std::endl;
    
    	// No processing
    	processor.dontCallProcess();
    	// Output filename
    //	processor.setOutput("../output/bikeOut",".jpg");
    	char codec[4];
    	processor.setOutput("../output/bike.avi",processor.getCodec(codec),processor.getFrameRate());
    	std::cout << "Codec: " << codec[0] << codec[1] << codec[2] << codec[3] << std::endl;
    
    	// Position the stream at frame 300
        //	processor.setFrameNumber(300);
        //	processor.stopAtFrameNo(120);
    
    	// Declare a window to display the video
    	processor.displayInput("Current Frame");
    	processor.displayOutput("Output Frame");
    
    	// Play the video at the original frame rate
    	processor.setDelay(1000./processor.getFrameRate());
    
    	// Start the process
    	processor.run();
    
    	std::cout << processor.getFrameNumber() << std::endl;
    	std::cout << processor.getPositionMS() << std::endl;
    
    	cv::waitKey();
    }


     

  • 相关阅读:
    Linux下yum安装mysql
    centos下无法使用lsof命令"-bash: lsof: command not found"
    大数据与区块链的联系与区别
    java.lang.NullPointerException报错的几种情况
    算法概述
    区块链简史
    word导出失败问题
    [Python3网络爬虫开发实战] 1.9.5-Scrapyrt的安装
    [Python3网络爬虫开发实战] 1.9.3-Scrapyd-Client的安装
    [Python3网络爬虫开发实战] 1.9.2-Scrapyd的安装
  • 原文地址:https://www.cnblogs.com/wuyida/p/6301402.html
Copyright © 2011-2022 走看看