FFmpeg读取摄像头用OpenCV显示

Environment

Ubuntu 16.04
GCC 5.4
CMake 3.9.6
OpenCV 3.3.1

Source code

#include 
#include 

extern "C" {
#include 
#include "avformat.h"
#include "avdevice.h"
}


int main(int argc, char *argv[]) {
    // Init
    avcodec_register_all();
    avdevice_register_all();

    AVFormatContext *formatContext = avformat_alloc_context();      // Format I/O context. Allocate an AVFormatContext.主要存储视音频封装格式中包含的信息
    AVInputFormat   *inputFormat = av_find_input_format("v4l2");    // or "video4linux2", 存储输入视音频使用的封装格式,每种视音频封装格式都对应一个AVInputFormat结构。

    if(inputFormat == nullptr) return -1;

    // Open an input stream and read the header.
    if(avformat_open_input(&formatContext, "/dev/video0", inputFormat, nullptr) < 0) return -2;
    if(avformat_find_stream_info(formatContext, nullptr) < 0) return -3;

    // Print detailed information about the input or output format.
    av_dump_format(formatContext, 0, "/dev/video0", 0);

    // 寻找视频流和对应的解码器(输入可能不止一个流,这里包含音频等流)
    int videoStreamIndex = 0;
    AVCodec *codec;
    if((videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0)) < 0) return -4;

    // 获取对应视频流的解码相关信息
    AVCodecContext  *codecContext = formatContext->streams[videoStreamIndex]->codec;
    // Initialize the AVCodecContext to use the given AVCodec.
    if(avcodec_open2(codecContext, codec, nullptr) < 0) return -5;

    // 分配空间存储图像数据
    AVFrame *frame = av_frame_alloc();
    AVPicture picture{};
    avpicture_alloc(&picture, AV_PIX_FMT_BGR24, codecContext->width, codecContext->height);

    int unfinished;
    AVPacket packet{};
    struct SwsContext * img_convert_ctx = nullptr;
    while(av_read_frame(formatContext, &packet) >= 0)
    {
        if(packet.stream_index == videoStreamIndex) {
            // Decode the video frame: packet => frame
            avcodec_decode_video2(codecContext, frame, &unfinished, &packet);

            if(unfinished) {
                // Convert to BGR24.
                img_convert_ctx = sws_getCachedContext(
                        img_convert_ctx,
                        codecContext->width, codecContext->height, codecContext->pix_fmt,
                        codecContext->width, codecContext->height, AV_PIX_FMT_BGR24,
                        SWS_BICUBIC, nullptr, nullptr, nullptr);
                sws_scale(img_convert_ctx,
                          reinterpret_cast<const uint8_t *const *>(frame->data), frame->linesize,
                          0, codecContext->height,
                          picture.data, picture.linesize);

                // Use OpenCV to display the picture.
                cv::Mat img(frame->height, frame->width, CV_8UC3, picture.data[0]);
                cv::imshow("display",img);
                cv::waitKey(10);
            }

            av_free_packet(&packet);
        }
    }

    // Destroy
    sws_freeContext(img_convert_ctx);
    av_free_packet(&packet);
    avcodec_close(codecContext);
    av_free(frame);
    avpicture_free(&picture);
    avformat_close_input(&formatContext);
    return 0;
}

结构体、函数和函数参数说明在对应的头文件中说明都比较信息。直接看头文件即可。

更多图像处理和视觉处理算法:zMatrix

你可能感兴趣的:(计算机视觉)