OpenCV 4.x API Detailed Explanation and C++ Examples-Image and Video Reading and Saving

Section 2 Image and Video Reading and Saving

In the foregoing, the basic operations of image reading, saving, encoding, decoding and highgui module of the imgcodecs module of the OpenCV library are described in detail. Next, the display operation of the highgui module on images and videos will be described in detail.

1. Image display


cv::imshow : Display the image in the specified window.

void cv::imshow (const String & winname,InputArray mat)

The imshow function displays the image in the specified window. If the window is created with the cv::WINDOW_AUTOSIZE flag, the image is displayed in its original size, but it is still limited by the screen resolution. Otherwise, the image will be scaled to fit the window. The function may scale the image, depending on its depth:

  • If the image is 8-bit unsigned, it is displayed as it is.
  • If the image is a 16-bit unsigned or 32-bit integer, divide the pixel by 256. That is, the value range [0,255 * 256] is mapped to [0,255].
  • If the image is 32-bit or 64-bit floating point, multiply the pixel value by 255. That is, the value range [0,1] is mapped to [0,255].

If a window is created with OpenGL support, cv::imshow also supports ogl::Buffer, ogl::Texture2D, and cuda::GpuMat as input.

If this function is called before the window is created, it is assumed that a new window is created using cv::WINDOW_AUTOSIZE.

If you need to display an image larger than the screen resolution, you need to call namedWindow ("", WINDOW_NORMAL) before imshow.

Note :

This function should be followed by the cv::waitKey function, which displays the image in the specified milliseconds. Otherwise, it will not display the image. For example, waitKey(0) will display the window indefinitely until any key is pressed (suitable for image display). waitKey(25) will display frames for 25 milliseconds, after which the display will be turned off automatically. (If you put it in a loop to read the video, it will display the video frame by frame)

In the windows system, OpenCV also supports the following operations:

  • Press Ctrl + C to copy the image to the clipboard.
  • Pressing Ctrl + S will display a dialog box to save the image.
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 创建窗口
    cv::namedWindow("image",cv::WINDOW_NORMAL);
    cv::Mat src = cv::imread("d:/develop/machine-vision-workbench/resources/images/f1.jpg");
    // 调整窗口大小
    cv::resizeWindow("image",640,480);
    cv::imshow("image",src);
    cv::waitKey();
    cv::destroyAllWindows();
    return 0;
}

2. Video read, display and save


1), cv::VideoCapture : The class to capture video from video files (local or network streams), image sequences, and cameras.

  • cv::VideoCapture()

  • cv::VideoCapture::VideoCapture(const String & filename,int apiPreference = CAP_ANY)

  • cv::VideoCapture::VideoCapture(int index,int apiPreference = CAP_ANY)

The second and third constructors of VideoCapture are frequently used. When filename is a local video file path or network video stream (such as rtsp, rtmp, hls, etc.); the parameter index is the serial number of the local camera device, generally starting from 0.

VideoCapture proposes a few simple and efficient functions:

  • cv::VideoCapture::get : Query the attributes of the video. For details, please refer to cv::VideoCaptureProperties

    virtual double cv::VideoCapture::get(int propId)const

  • cv::VideoCapture::getBackendName : Returns the name of the backend API used (in general, the default is FFMPG)

    String cv::VideoCapture::getBackendName ()const

  • cv::VideoCapture::grab : Grab the next frame of video file or camera device. If it succeeds, it returns true.

    virtual bool cv::VideoCapture::grab()

    The main use of this function is in a multi-camera environment, especially when the cameras do not have hardware synchronization. That is, you call VideoCapture::grab() for each camera, and then call the slower method VideoCapture::retrieve() to decode and get frames from each camera. In this way, the overhead of demosaicing or motion jpeg decompression is eliminated, and the frames retrieved from different cameras will be closer in time.

    In addition, when the connected camera is a multi-head camera (for example, a stereo camera or Kinect device), the correct way to retrieve data from it is to first call VideoCapture::grab(), and then call VideoCapture::retrieve() using different channel parameters Value one or more times.

  • cv::VideoCapture::isOpened : Determine whether the file is ready or whether the camera device is initialized successfully. If it succeeds, it returns true.

  • cv::VideoCapture::open : Open the video file or camera device, the effect is equivalent to the initialization of the VideoCapture constructor passing the relevant parameters

  • **Operator>>:** Grab and return the next frame of image.

  • cv::VideoCapture::read : Capture, decode and return to the next frame of image.

    virtual bool cv::VideoCapture::read (OutputArray image)

  • cv::VideoCapture::release : Close open files or camera equipment.

  • cv::VideoCapture::retrive : Decode and return the captured video frame.

    virtual bool cv::VideoCapture::retrieve (OutputArray image,int flag = 0)

  • cv::VideoCapture::set : Property setting in VideoCapture.

    virtual bool cv::VideoCapture::set(int propId,double value)

    Please refer to propId: cv::VideoCaptureProperties

  • cv::VideoCapture::waitAny : static function, waiting for the ready frame from VideoCapture.

    static bool cv::VideoCapture::waitAny(const std::vector< VideoCapture > & streams,std::vector< int > & readyIndex,int64 timeoutNs = 0)

    The parameter streams is the input stream list; readyIndex is the sequence number of the ready device list; timeoutNs is the timeout period.

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 打开一个网络视频流
    const std::string webstream = "http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8";
    cv::VideoCapture cap(webstream);

    if(!cap.isOpened()){
        cerr << "cannot open rtsp stream.\n";
        exit(0);
    }
    // 查询后端支持的API
    cout << "backend name:" << cap.getBackendName();
    // 获取视频流的帧宽度和高度
    int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
    int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    cout << "width = " << width << ",height = " << height << endl;

    cv::Mat frame;
    int key = -1;
    while(true){
        cap >> frame;

        if(frame.empty()){
            cerr << "cannot grab frame from video stream\n";
            break;
        }
        cv::imshow("video",frame);
        key = cv::waitKey(10);
        if(key == 27){
            break;
        }
    }
    cv::destroyAllWindows();
    cap.release();

    return 0;
}

2) cv::VideoWriter : Write a video or image sequence to a file.

  • VideoWriter ()
  • VideoWriter (const String &filename, int fourcc, double fps, Size frameSize, bool isColor=true)
  • VideoWriter (const String &filename, int apiPreference, int fourcc, double fps, Size frameSize, bool isColor=true)
  • VideoWriter (const String &filename, int fourcc, double fps, const Size &frameSize, const std::vector< int > &params)
  • VideoWriter (const String &filename, int apiPreference, int fourcc, double fps, const Size &frameSize, const std::vector< int > &params)

Among them, the parameter fourcc is the encoding format of the video or image sequence, such as VideoWriter :: fourcc ('P','I','M', '1') is the MPEG-1 codec, VideoWriter :: fourcc ('M ','J','P','G') are sports jpeg codecs, etc.; the parameter fps is the frame rate; the parameter frameSize is the frame size; the parameter isColor is whether to encode according to color images; the second one is often used Constructor.

The cv::VideoCapture::write function implements writing video frames or image sequences to a file.

virtual void cv::VideoWriter::write(InputArray image)

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    // 从本地摄像头创建VideoCapture
    cv::VideoCapture cap(0);
    if(!cap.isOpened()){
        cerr << "cannot open camera.\n";
        exit(0);
    }
    // 获取视频流的帧宽度、高度和帧率
    int width = cap.get(cv::CAP_PROP_FRAME_WIDTH);
    int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
    int rate = cap.get(cv::CAP_PROP_FPS);
    cout << "video info:width = " << width << ",height = " << height << ",frame rate = " << rate << endl;
    // 创建一个MPEG-4编码 视频Writer
    cv::VideoWriter writer("e:/temp/output.mp4",
                           cv::VideoWriter::fourcc('D','I','V','X'),rate,
                           cv::Size(width,height));
    cv::Mat frame;
    int key = -1;
    while(cap.isOpened()){
        cap >> frame;
        if(frame.empty()){
            cout << "cannot grab frame from camera.\n";
            break;
        }
        // TODO:对图像进行各种处理
        // 对图像进行取反,实现底片效果
        cv::imshow("video",frame);
        frame -= 255;
        // 保存视频
        writer.write(frame);
        cv::imshow("video:invert",frame);
        key = cv::waitKey(10);
        if(key == 27){
            break;
        }
    }
    cv::destroyAllWindows();
    cap.release();
    writer.release();
    return 0;
}

Common video format encodings are as follows:

  • CV_FOURCC(‘P’, ‘I’, ‘M’, ‘1’) = MPEG-1 code

  • CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) = motion-jpeg codec

  • CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec

  • CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec

  • CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec

  • CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec

  • CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec

CV_FOURCC('F','L','V', '1') = FLV1 codec MPEG-1 is a video and audio compression format customized for CD disc media; Motion JPEG is a video compression format, where each frame Images are respectively encoded using JPEG; MPEG-4 uses a very narrow bandwidth, compresses and transmits data through frame reconstruction technology, in order to obtain the best image quality with the least amount of data;

For details, please refer to fourcc

Guess you like

Origin blog.csdn.net/wujuxKkoolerter/article/details/112134706