1. 程式人生 > >【學習筆記】Learning OpenCV3——Ch8 working with video

【學習筆記】Learning OpenCV3——Ch8 working with video

  Reading Video with the cv::VideoCapture Object
  
  物件建立的三種方法:
  
  // 1. Input filename
  
  cv::VideoCapture::VideoCapture(
  
  const string& filename
  
  );
  
  // 2. Video capture device id
  
  cv::VideoCapture::VideoCapture(
  
  int device
  
  );
  
  // 3.
  
  cv::VideoCapture::VideoCapture();
  
  建構函式的第一種:
  
  在第一種方法中,傳入視訊路徑,建立物件後,需要加入視訊是否成功開啟:
  
  // e.g.
  
  cv::VideoCapture cap("1.mp4");
  
  if (!cap.isOpen(www.quwanyule157.com)) {
  
  std::cout << "Failed to open the video" << std::endl;
  
  視訊打不開的常見原因:
  
  視訊路徑錯誤
  
  視訊編碼格式未知
  
  後一種原因的解決方案:
  
  you will need to have the appropriate library already residing on your computer in order to successfully read the video file.
  
  建構函式的第二種:
  
  通常為裝置的代號,整型
  
  小tip:
  
  cv::VideoCapture cap(-1);
  
  1
  
  可開啟一個視窗供以選擇捕獲視訊的裝置
  
  建構函式的第三種:
  
  cv::VideoCapture cap;
  
  cap.open("video.avi");
  
  1
  
  2
  
  讀取視訊幀資料
  
  // 1. read function
  
  bool cv::VideoCapture::read(
  
  cv::OutputArray image yongshiyule178.com/// Image into which to read data, return true for read frame successfully, false for failue
  
  );
  
  // 2. >> operator
  
  cv::VideoCapture& cv:www.wanmeiyuele.cn:VideoCapture::operator>>( cv::Mat& image // Image into which to read data
  
  );
  
  // NOTE:
  
  // << return a reference to the original object, should check the return array is not empty
  
  // 3. grab && retrieve function
  
  bool cv::VideoCapture::grab(www.mhylpt.com/ void ); // is designed simply to get it onto the computer as quickly as possible
  
  bool cv::VideoCapture::retrieve(
  
  cv::OutputArray image, // Image into which to read data
  
  int channel = 0 // Used for multihead devices
  
  );
  
  // NOTE:
  
  // can read images from mutiple cameras
  
  // more general
  
  設定&獲取視訊屬性
  
  double cv::VideoCapture::get(
  
  int propid //www.mcyllpt.com Property identifier (see Table 8-4)
  
  );
  
  bool cv::VideoCapture::set(
  
  int propid,
  
  double value // Value to which to set the property
  
  //Example 8-1. Unpacking a four-character code to identify a video codec
  
  cv::VideoCapture cap( "my_video.avi" );
  
  unsigned f = (unsigned)cap.get( cv::CAP_PROP_FOURCC );
  
  char fourcc[] = {
  
  (char) f, // First character is lowest bits
  
  (char)(f >> 8), // Next character is bits 8-15
  
  (char)(f >> 16), // Next character is bits 16-23
  
  (char)(f >> 24), // Last character is bits 24-31
  
  '\0' // and don't forget to terminate
  
  Reading Video with the cv::VideoCapture Object
  
  兩種構造方式:
  
  // 1. an uninitialized video object
  
  cv::VideoWriter::VideoWriter();
  
  // 2. an initialized video object
  
  cv::VideoWriter::VideoWriter(
  
  const string& filename, // output filename
  
  int fourcc, // codec, use CV_FOURCC(www.michenggw.com/) macro
  
  double fps, // Frame rate (stored in output file)
  
  cv::Size frame_size, // Size of individual images
  
  bool is_color = true // if false, you can pass gray frames
  
  );
  
  // e.g.
  
  Don’t forget that you are providing characters (single quotes), not strings (double quotes).
  
  同cv::VideoCapture,也有cv::VideoWriter::isOpened()方法暗示是否可以寫視訊,如果返回false,可能存在以下幾點原因:
  
  沒有寫許可權
  
  編碼格式不可用
  
  NOTES:
  
  The codecs available to you depend on your operating system installation and the additional libraries you have installed.
  
  For portable code, it is especially important to be able to gracefully handle the case in which the desired codec is not available on any particular machine.
  
  寫入視訊的兩個函式:
  
  // 1. write function
  
  cv::VideoWriter::write(
  
  const Mat& image // Image to write as next frame
  
  );
  
  /*
  
  NOTES:
  
  - This image must have the same size as the size you gave to the writer when you configured it in the first place. - If you told the writer that the frames would be in color, this must also be a three-channel image.
  
  */
  
  // 2. << Operator
  
  my_video_writer << my_frame;
  
  /*
  
  NOTE:
  
  once you have your video writer open, you can write images to the video stream in the same manner you would write to cout or a file ofstream object
  
  簡單例項
  
  #include<opencv2/opencv.hpp>
  
  #include<iostream>
  
  using namespace cv;
  
  int main() {
  
  // params & input path && output path configure
  
  int caseVideo = 6;
  
  char pathInVideo[200], pathOutVideo[200];
  
  sprintf(pathInVideo, "%d.avi", caseVideo);
  
  sprintf(pathOutVideo, "%d_output.avi", caseVideo);
  
  // read video
  
  cv::VideoCapture cap(pathInVideo);
  
  if (!cap.isOpened()) {
  
  std::cerr << "Failed to open the video" << std::endl;
  
  return -1;
  
  }
  
  int frameLength = cap.get(CAP_PROP_FRAME_COUNT);
  
  // params for writting output video
  
  cv::VideoWriter outputVideo;
  
  cv::Size sWH = cv::Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
  
  (int)cap.get(CAP_PROP_FRAME_HEIGHT));
  
  if (!outputVideo.open(pathOutVideo, cv::VideoWriter::fourcc('M', 'P', '4', '2'), cap.get(CAP_PROP_FPS), sWH)) {
  
  std::cerr << "Failed to write video" << std::endl;
  
  return -1;
  
  }
  
  // gauss filter frame by frame
  
  for (int i = 0; i < frameLength; i++) {
  
  std::cout << "Process the " << i << " frame" << std::endl;
  
  cv::Mat inputImg, outputImg;
  
  cap.read(inputImg);
  
  if (!inputImg.empty()) {
  
  cv::GaussianBlur(inputImg, outputImg, cv::Size(25, 25), 0.0, 0.0);
  
  outputVideo.write(outputImg);
  
  }
  
  }
  
  // release cap && outputVideo
  
  cap.release();
  
  outputVideo.release();