Day 2-OpenCV基础-2

原文:https://courses.learnopencv.com/courses/227056/lectures/3541926
代码:https://courses.learnopencv.com/courses/227056/lectures/3804002

对原文进行了不全面的重点笔记摘录

OpenCV基础-2

在图片上作画

能够画如下的形状或文字
- Line
- Circle
- Ellipse
- Rectangle
- Text

下面是伪代码

cv::line ( image, starting point , end point , color , line thickness, line type)
cv:: circle ( image, center, radius, color of border, line thickness / fill type, line type)
cv:: ellipse ( image, center, axes lengths, rotation degree of ellipse, starting angle , ending angle, color, line thickness / fill type, line type)
cv:: rectangle ( image, upper left corner vertex, lower right corner vertex, line thickness / fill type, line type)
cv :: putText ( image, text, starting point of text, font type, font scale, color, linetype )

linetype 参数用来控制渲染质量,比如设置为CV_AA,(anti-alias),就可以画出消除锯齿的线

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;

int main(void) {
    Mat image = imread("mark.jpg");
    // Draw a line
    // We are making a copy of image because we don't want to draw all the shapes on one image
    Mat imageLine = image.clone();
    line(imageLine, Point(322, 179), Point(400, 183), Scalar(0, 255, 0), 1, CV_AA);
    imshow("line", imageLine);
    imwrite("imageLine.jpg", imageLine)
    waitKey(0);
    return 0;
}

处理鼠标事件

我们能够使用OpenCV检测诸如左键、右键或者鼠标在窗口上的位置等鼠标事件。为了达到目的,我们需要创建一个命名窗口并且为它指定一个回调函数,我们将在下面的代码中展示。

选择圆心并拖动半径,按c清除图像,ESC退出

C++ [ HighGui - Mouse ] [ highguiMouse.cpp ]

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <vector>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
/*This program shows how highgui enables us to take mouse inputs. 
In this code we use mouse input to draw a circle on an image. 
The mouse is dragged from the center to one of the points on the
circumference. ‘c’ can be pressed to remove the drawn circles. */
// Points to store the center of the circle and a point on the 
circumference
Point center, circumference;
// Source image
Mat source;
/*drawCircle the callback function is called when there is a mouse event 
like left click ( indicated by EVENT_LBUTTONDOWN ). The coordinates 
relative to the namedWindow is captured by this function in the 
variables (x,y). The function records the points of the circle’s center 
and a point on the circumference, hence allowing us to draw the desired 
circle on the image.*/
// function which will be called on mouse input
void drawCircle(int action, int x, int y, int flags, void *userdata)
{
  // Action to be taken when left mouse button is pressed
  if( action == EVENT_LBUTTONDOWN )
  {
      center = Point(x,y);
      // Mark the center
      circle(source, center, 1, Scalar(255,255,0), 2, CV_AA );
  }
  // Action to be taken when left mouse button is released
  else if( action == EVENT_LBUTTONUP)
  {
      circumference = Point(x,y);
      // Calculate radius of the circle
      float radius = sqrt(pow(center.x-circumference.x,2)+
        pow(center.y-circumference.y,2));
      // Draw the circle
      circle(source, center, radius, Scalar(0,255,0), 2, CV_AA );
      imshow("Window", source);
  }
}
int main()
{
  source = imread("boy.jpg",1);
  // Make a dummy image, will be useful to clear the drawing
  Mat dummy = source.clone();
  namedWindow("Window");
  // highgui function called when mouse events occur
  setMouseCallback("Window", drawCircle);
  int k=0;
  // loop until escape character is pressed
  while(k!=27)
  {
      imshow("Window", source );
      putText(source,"Choose center, and drag, Press ESC to exit and c to clear" ,Point(10,30), FONT_HERSHEY_SIMPLEX, 0.7, Scalar(255,255,255), 2 );d
      k= waitKey(20) & 0xFF;
      if(k== 99)
          // Another way of cloning
          dummy.copyTo(source);
  }
  return 0;
}

读写、显示视频

这一节讲述OpenCV中对视频的操作。
一个视频其实就是一段快速切换的图片,其中明显的问题就是图片切换移动得多快?我们用帧每秒(fps)来衡量这样的速度。一般来说25帧每秒,是人肉眼能够分辨的极限。
OpenCV为我们提供了方便的操作接口。

1. 读取视频

第一步我们需要创建一个VideoCapture对象,它的参数可以是WebCam摄像头的设备编号或者是视频文件名
当只有一个摄像头时,使用参数‘0’来使用唯一的那个摄像头,有多个摄像头时,可以使用编号1,2等来使用不同的设备。

VideoCapture cap("chaplin.mp4");

2. 显示视频

读取了视频之后,我们可以一帧一帧的来展示视频。我们可以利用显示图片的方法来显示我们视频的一帧,我们使用imshow()函数。

在显示图片的情况下,我们在imshow()之后使用waitKey(num)来暂停,参数为‘0’。在视频中,通常使用比num>0大的数,来延迟num毫秒。

在使用webcam的时候,使用waitKey(1)是合适的,因为显示的帧速率会被webcam所限制。

在从视频文件中读取时,使用waitKey(1)可能也是合适的,因为这样可以延迟一秒来使得线程空出来进行我们想要的处理。

在极少的情况下我们要回放视频会设置特定的帧速率。
C++ [ Reading a video file ] [ videoRead.cpp ]

//In the following code, we will use the VideoCapture Object to 
//read a video file and display it.
//Include opencv header files
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(){
//In this block,we create a video capture object and 
//read a input video file.
// Create a VideoCapture object and open the input file
// If the input is the web camera, pass 0 instead of the video file name
  VideoCapture cap("chaplin.mp4"); 
   // Check if camera opened successfully and read a frame from the object cap
  if(!cap.isOpened()){
    cout << "Error opening video stream or file" << endl;
    return -1;
  }

//Read and display video frames until video is completed or 
//user quits by pressing ESC
  while(1){
    Mat frame;
    // Capture frame-by-frame
    cap >> frame;

    // If the frame is empty, break immediately
    if (frame.empty())
      break;
    // Display the resulting frame
    imshow( "Frame", frame ); 
    // Press ESC on keyboard to exit
    char c=(char)waitKey(25);
    if(c==27)
      break;
  }

  // When everything done, release the video capture object
  cap.release();
  // Closes all the frames
  destroyAllWindows();

  return 0;
}

3. 写视频

当完成对视频的处理后,需要把视频存储起来。
对图片的存储,可以使用cv2.imwrite()。
对视频的处理,我们需要先创建一个VideoWriter 对象,然后指定1. 带有格式的名字; 2. FourCC编码,3. FPS(帧每秒)4. 帧大小

// Define the codec and create VideoWriter object.The output is stored in 'outcpp.avi' file.
// Define the fps to be equal to 10. Also frame size is passed.
VideoWriter video("outcpp.avi",CV_FOURCC('M','J','P','G'),10, Size(frame_width,frame_height));

C++ [ Writing to a video file ] [ videoWrite.cpp ]

// Include opencv header files
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
/*
In the following code, we will use the VideoCapture Object to read a video
from the webcam, display the feed from webcam and save it by using a
VideoWriter Object.
*/
int main(){
  // Create a VideoCapture object and open the input file
  // If the input is the web camera, pass 0 instead of the video file name
  VideoCapture cap(0); 

  // Check if camera opened successfully
  if(!cap.isOpened()){
    cout << "Error opening video stream or file" << endl;
    return -1;
  }

  //In this block of code, we obtain the system dependent 
  //frame width and height.
  // Default resolutions of the frame are obtained. 
  // The default resolutions are system dependent.
  int frame_width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
  int frame_height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);

  //We create the videoWriter object ‘video’, name the output file as 
  //‘outcpp.avi’ and define the 4 FOURCC code. We also specify the ‘fps’ 
  //value and the dimensions of the system dependent frame.
  // Define the codec and create VideoWriter object.The output is stored 
  // in 'outcpp.avi' file.
  VideoWriter video("outcpp.avi",CV_FOURCC('M','J','P','G'),10, Size(frame_width,frame_height));

  //Read and save the feed from webcam until ESC is pressed .
  while(1){
    Mat frame;
    // Capture frame-by-frame
    cap >> frame;

    // If the frame is empty, break immediately
    if (frame.empty())
      break;
    // Write the frame into the file 'outcpp.avi'
    video.write(frame);
    // Display the resulting frame
    imshow( "Frame", frame );
    // Press ESC on keyboard to exit
    char c=(char)waitKey(25);
    if(c==27)
      break;
  }

  // When everything done, release the video capture object
  cap.release();
  video.release();
  // Closes all the frames
  destroyAllWindows();

  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值