• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

C/C++开发,opencv和qt结合播放视频

武飞扬头像
py_free-物联智能
帮助2

目录

一、qt_ui创建

        1.1 ui设置

         1.2 ui及代码输出保存

二、创建工程

        2.1 工程目录及编译设置

        2.2 源码设计

三、编译及测试

        3.1 程序编译

        3.2 程序运行


        首先声明,这是一个OpenCV 3学习文档的案例,但是说明有些过于省略,只有一些简短的代码描述,本人在学习验证过程中将其记录下来分享给大家。

一、qt_ui创建

        1.1 ui设置

        本文采用qt5.8_msvc2015_64版本,

学新通

        进入qt的bin目录,打开qt_ui设计工具designer.exe

学新通

         创建一个Widget窗体,即对象QWidget,命名为QMoviePlayer。

学新通

         随后创建一个QFrame对象,对象名为frame,该对象可以随意在窗体QMoviePlayer拉出一个合适的长宽比显示框,该显示框用来显示视频使用。

学新通

         完成设置后,保存该UI,例如QMoviePlayer.ui

学新通

         1.2 ui及代码输出保存

        本人的QMoviePlayer.ui文件的xml内容如下:

  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <ui version="4.0">
  3.  
    <class>QMoviePlayer</class>
  4.  
    <widget class="QWidget" name="QMoviePlayer">
  5.  
    <property name="geometry">
  6.  
    <rect>
  7.  
    <x>0</x>
  8.  
    <y>0</y>
  9.  
    <width>600</width>
  10.  
    <height>303</height>
  11.  
    </rect>
  12.  
    </property>
  13.  
    <property name="windowTitle">
  14.  
    <string>Form</string>
  15.  
    </property>
  16.  
    <widget class="QFrame" name="frame">
  17.  
    <property name="geometry">
  18.  
    <rect>
  19.  
    <x>0</x>
  20.  
    <y>0</y>
  21.  
    <width>601</width>
  22.  
    <height>241</height>
  23.  
    </rect>
  24.  
    </property>
  25.  
    <property name="frameShape">
  26.  
    <enum>QFrame::StyledPanel</enum>
  27.  
    </property>
  28.  
    <property name="frameShadow">
  29.  
    <enum>QFrame::Raised</enum>
  30.  
    </property>
  31.  
    </widget>
  32.  
    </widget>
  33.  
    <resources/>
  34.  
    <connections/>
  35.  
    </ui>

        点击窗体菜单,进入查看代码,保存该代码文件为ui_QMoviePlayer.h,或新创建一个头文件将该内容直接复制到头文件中保存。

学新通

         本人的ui_QMoviePlayer.h的代码内容如下。

  1.  
    /********************************************************************************
  2.  
    ** Form generated from reading UI file 'QMoviePlayerp15136.ui'
  3.  
    **
  4.  
    ** Created by: Qt User Interface Compiler version 5.8.0
  5.  
    **
  6.  
    ** WARNING! All changes made in this file will be lost when recompiling UI file!
  7.  
    ********************************************************************************/
  8.  
     
  9.  
    #ifndef QMOVIEPLAYERP15136_H
  10.  
    #define QMOVIEPLAYERP15136_H
  11.  
     
  12.  
    #include <QtCore/QVariant>
  13.  
    #include <QtWidgets/QAction>
  14.  
    #include <QtWidgets/QApplication>
  15.  
    #include <QtWidgets/QButtonGroup>
  16.  
    #include <QtWidgets/QFrame>
  17.  
    #include <QtWidgets/QHeaderView>
  18.  
    #include <QtWidgets/QWidget>
  19.  
     
  20.  
    QT_BEGIN_NAMESPACE
  21.  
     
  22.  
    class Ui_QMoviePlayer
  23.  
    {
  24.  
    public:
  25.  
    QFrame *frame;
  26.  
     
  27.  
    void setupUi(QWidget *QMoviePlayer)
  28.  
    {
  29.  
    if (QMoviePlayer->objectName().isEmpty())
  30.  
    QMoviePlayer->setObjectName(QStringLiteral("QMoviePlayer"));
  31.  
    QMoviePlayer->resize(600, 303);
  32.  
    frame = new QFrame(QMoviePlayer);
  33.  
    frame->setObjectName(QStringLiteral("frame"));
  34.  
    frame->setGeometry(QRect(0, 0, 601, 241));
  35.  
    frame->setFrameShape(QFrame::StyledPanel);
  36.  
    frame->setFrameShadow(QFrame::Raised);
  37.  
     
  38.  
    retranslateUi(QMoviePlayer);
  39.  
     
  40.  
    QMetaObject::connectSlotsByName(QMoviePlayer);
  41.  
    } // setupUi
  42.  
     
  43.  
    void retranslateUi(QWidget *QMoviePlayer)
  44.  
    {
  45.  
    QMoviePlayer->setWindowTitle(QApplication::translate("QMoviePlayer", "Form", Q_NULLPTR));
  46.  
    } // retranslateUi
  47.  
     
  48.  
    };
  49.  
     
  50.  
    namespace Ui {
  51.  
    class QMoviePlayer: public Ui_QMoviePlayer {};
  52.  
    } // namespace Ui
  53.  
     
  54.  
    QT_END_NAMESPACE
  55.  
     
  56.  
    #endif // QMOVIEPLAYERP15136_H

二、创建工程

        2.1 工程目录及编译设置

        创建一个opencv_qt目录的工程文件,工程组织如下:

  1.  
    opencv_qt
  2.  
    bin
  3.  
    build_vc
  4.  
    src
  5.  
    main.cpp
  6.  
    ui_QMoviePlayer.h
  7.  
    QMoviePlayer.h
  8.  
    QMoviePlayer.cpp
  9.  
    QMoviePlayer.ui
  10.  
    CMakeLists.txt #cmake工程
  11.  
    vcbuild_2015.bat #编译命令

        ui_QMoviePlayer.h和QMoviePlayer.ui就是前面采用designer.exe实现的ui及代码头文件。

  1.  
    # CMake 最低版本号要求
  2.  
    cmake_minimum_required (VERSION 3.1.0)
  3.  
    # 项目信息
  4.  
    set(proname "opencv_qt")
  5.  
    project(${proname} VERSION 1.0.0 LANGUAGES CXX)
  6.  
     
  7.  
    if(WIN32)
  8.  
    message(STATUS "windows compiling...")
  9.  
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
  10.  
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
  11.  
    add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
  12.  
    add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
  13.  
    add_definitions(
  14.  
    -D_PLATFORM_IS_WINDOWS_
  15.  
    -D_CRT_SECURE_NO_WARNINGS
  16.  
    -D_WINSOCK_DEPRECATED_NO_WARNINGS
  17.  
    # -DZLIB_WINAPI
  18.  
    -DUNICODE
  19.  
    -D_UNICODE
  20.  
    # -DQT_DLL
  21.  
    # -DQT_CORE_LIB
  22.  
    # -DQT_GUI_LIB
  23.  
    # -DQT_WIDGETS_LIB
  24.  
    # -D CMAKE_CXX_FLAGS="/utf-8"
  25.  
    )
  26.  
     
  27.  
    else(WIN32)
  28.  
    message(STATUS "linux compiling...")
  29.  
    # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c 11 -I/usr/include -L/lib/x86_64-linux-gnu -lpthread -pthread -lm -lrt -ldl -lz -luuid ") #qt需要-fPIC编译指定
  30.  
    add_definitions(
  31.  
    -D_PLATFORM_IS_LINUX_
  32.  
    "-g"
  33.  
    # "-std=gnu 0x"
  34.  
    "-std=c 11"
  35.  
    "-O2"
  36.  
    # "-pipe"
  37.  
    "-Wno-invalid-source-encoding"
  38.  
    "-Wdeprecated-declarations"
  39.  
    "-W"
  40.  
    "-fPIC"
  41.  
    "-Wall"
  42.  
    # "-Werror"
  43.  
    # "-Wshadow"
  44.  
    # "-Wformat"
  45.  
    # "-Wpointer-arith"
  46.  
    "-D_REENTRANT"
  47.  
    # "-D_USE_FAST_MACRO"
  48.  
    # "-Wno-long-long"
  49.  
    # "-Wuninitialized"
  50.  
    # "-D_POSIX_PTHREAD_SEMANTICS"
  51.  
    # "-Wno-unused-parameter"
  52.  
    "-fexceptions"
  53.  
    "-DQT_NO_DEBUG"
  54.  
    "-DDQT_QML_DEBUG"
  55.  
    )
  56.  
    endif(WIN32)
  57.  
     
  58.  
    set(CMAKE_CXX_STANDARD 11)
  59.  
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
  60.  
     
  61.  
    if(CMAKE_VERSION VERSION_LESS "3.7.0")
  62.  
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
  63.  
    endif()
  64.  
     
  65.  
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
  66.  
    # 创建 EXECUTABLE_OUTPUT_PATH 指向的文件夹
  67.  
    execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${EXECUTABLE_OUTPUT_PATH})
  68.  
     
  69.  
    set(PROJECT_CUR_DIR .)
  70.  
     
  71.  
    if(WIN32)
  72.  
    set(QTDIR "D:/workForSoftware/Qt/Qt5.8.0/5.8/msvc2015_64")
  73.  
    else(WIN32)
  74.  
    set(QTDIR "/opt/qt-5.8_static")
  75.  
    endif(WIN32)
  76.  
    message("QTDIR = ${QTDIR}")
  77.  
    set(Qt5_DIR "${QTDIR}/lib/cmake/Qt5")
  78.  
    message("Qt5_DIR = ${Qt5_DIR}")
  79.  
     
  80.  
    set(CMAKE_AUTOMOC ON)
  81.  
    # set(CMAKE_AUTORCC ON)
  82.  
    set(CMAKE_AUTOUIC ON)
  83.  
    #查找需要的Qt库文件,最好每一个库都要写,Qt也会根据依赖关系自动添加
  84.  
    find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
  85.  
    cmake_policy(SET CMP0020 NEW)
  86.  
     
  87.  
    set(CMAKE_INCLUDE_CURRENT_DIR ON) #包含编译目录
  88.  
     
  89.  
    FILE(GLOB srcfile ${PROJECT_CUR_DIR}/src/*.h ${PROJECT_CUR_DIR}/src/*.cpp ) #加载文件夹下的所有源码文件
  90.  
    LIST(APPEND code_file ${srcfile} ) #变量合并
  91.  
     
  92.  
    include_directories(
  93.  
    "${PROJECT_CUR_DIR}"
  94.  
    "${PROJECT_CUR_DIR}/src"
  95.  
    "${PROJECT_CUR_DIR}/../../opencv_vc/include"
  96.  
    "${QTDIR}/include"
  97.  
    "${QTDIR}/include/QtCore"
  98.  
    "${QTDIR}/include/QtGui"
  99.  
    "${QTDIR}/include/QtWidgets"
  100.  
    )
  101.  
     
  102.  
    #link 目录
  103.  
    link_directories(
  104.  
    "${QTDIR}/lib"
  105.  
    "${PROJECT_CUR_DIR}/../../opencv_VC/x64/vc14/lib"
  106.  
    )
  107.  
     
  108.  
    message("RESOURCES = ${RESOURCES}")
  109.  
     
  110.  
    add_executable(${proname} ${code_file} ${RESOURCES} ${RC_FILE} )
  111.  
     
  112.  
    # 链接指定
  113.  
    set(link_lib
  114.  
    Qt5::Core Qt5::Gui Qt5::Widgets
  115.  
    )
  116.  
    if(WIN32)
  117.  
    if (CMAKE_BUILD_TYPE STREQUAL "release")
  118.  
    set(link_lib_opencv
  119.  
    opencv_img_hash460.lib opencv_world460.lib
  120.  
    )
  121.  
    else()
  122.  
    set(link_lib_opencv
  123.  
    opencv_img_hash460d.lib opencv_world460d.lib
  124.  
    )
  125.  
    endif()
  126.  
    endif(WIN32)
  127.  
     
  128.  
    target_link_libraries(${proname}
  129.  
    ${link_lib}
  130.  
    ${link_lib_opencv}
  131.  
    )
  132.  
     
  133.  
    #去除 CMD 窗口
  134.  
    if(WIN32)
  135.  
    message("CMAKE_BUILD_TYPE =${CMAKE_BUILD_TYPE}")
  136.  
    if (CMAKE_BUILD_TYPE STREQUAL "release")
  137.  
    if(MSVC)
  138.  
    set_target_properties(${proname} PROPERTIES
  139.  
    WIN32_EXECUTABLE YES
  140.  
    LINK_FLAGS "/ENTRY:mainCRTStartup"
  141.  
    )
  142.  
    elseif(CMAKE_COMPILER_IS_GNUCXX)
  143.  
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
  144.  
    else()
  145.  
    message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
  146.  
    endif(MSVC)
  147.  
    endif()
  148.  
     
  149.  
    endif(WIN32)

        vcbuild_2015.bat是为了编译方便创建的一个脚本,读者也可以按该脚本命令手动编译。

  1.  
    md build_vc
  2.  
    cd ./build_vc
  3.  
    @REM 单独编译时可能需要独立设置环境变量
  4.  
    if [%vccompilerversion%] EQU [] ( set vccompilerversion="Visual Studio 14 2015 Win64" )
  5.  
     
  6.  
    @REM 工程配置
  7.  
    cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=debug
  8.  
    @REM 编译
  9.  
    cmake --build . --config debug
  10.  
     
  11.  
    @REM 工程配置
  12.  
    cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=release
  13.  
    @REM 编译
  14.  
    cmake --build . --config release
  15.  
     
  16.  
    cd ..

        2.2 源码设计

        下来看看源码如何实现视频读取与播放的。

        QMoviePlayer.h内容如下,该头文件定义了一个窗口类型,该窗口显示部分来自于前面的UI设计“Ui::QMoviePlayer ui”,定义了“cv::VideoCapture m_cap”用来捕获视频内容:

  1.  
    #ifndef _QMOVIEPLAYER_H_
  2.  
    #define _QMOVIEPLAYER_H_
  3.  
     
  4.  
    #include "ui_QMoviePlayer.h"
  5.  
    #include <QtWidgets/QWidget>
  6.  
    #include <QImage>
  7.  
     
  8.  
    #include <opencv2/opencv.hpp>
  9.  
    #include <string>
  10.  
    using namespace std;
  11.  
     
  12.  
    QT_BEGIN_NAMESPACE
  13.  
    class QPaintEvent;
  14.  
    class QTimer;
  15.  
    QT_END_NAMESPACE
  16.  
     
  17.  
    class QMoviePlayer : public QWidget
  18.  
    {
  19.  
    Q_OBJECT
  20.  
    public:
  21.  
    QMoviePlayer(QWidget *parent = NULL);
  22.  
    virtual ~QMoviePlayer(){;}
  23.  
    bool open( string file );
  24.  
    public slots:
  25.  
    void nextFrame();
  26.  
     
  27.  
    private:
  28.  
    void paintEvent( QPaintEvent* q);
  29.  
    void _copyImage( void);
  30.  
    private:
  31.  
    Ui::QMoviePlayer ui; //ui界面
  32.  
    cv::VideoCapture m_cap; //opencv的视频读取及捕获图像实现
  33.  
    QImage m_qt_img;
  34.  
    cv::Mat m_cv_img; //图像缓存矩阵
  35.  
    QTimer* m_timer;
  36.  
    };
  37.  
     
  38.  
    #endif //_QMOVIEPLAYER_H_

        QMoviePlayer.cpp内容如下,open函数用于打开一个视频文件,并通过QTimer对象来定期读取帧图像数据,nextFrame用于读取图像数据并更新到窗口显示;_copyImage函数是opencv与QT结合的关键,它将opencv捕获的图像m_cv_img转换为qt的图像m_qt_img,这样才能将图片按qt方式刷新到窗口显示:

  1.  
    #include "QMoviePlayer.h"
  2.  
     
  3.  
    #include <QPainter>
  4.  
    #include <QTimer>
  5.  
     
  6.  
    QMoviePlayer::QMoviePlayer(QWidget *parent)
  7.  
    : QWidget(parent)
  8.  
    {
  9.  
    ui.setupUi( this );
  10.  
    }
  11.  
     
  12.  
    bool QMoviePlayer::open( string file)
  13.  
    {
  14.  
    if( !m_cap.open( file)) return false;
  15.  
    // If we opened the file, set up everything now:
  16.  
    //
  17.  
    m_cap.read( m_cv_img );
  18.  
    m_qt_img = QImage(
  19.  
    QSize( m_cv_img.cols,m_cv_img.rows),
  20.  
    QImage::Format_RGB888
  21.  
    );
  22.  
    ui.frame->setMinimumSize( m_qt_img.width(),m_qt_img.height());
  23.  
    ui.frame->setMaximumSize( m_qt_img.width(),m_qt_img.height());
  24.  
    _copyImage();
  25.  
     
  26.  
    m_timer = new QTimer( this );
  27.  
    connect(m_timer, SIGNAL( timeout()), this, SLOT( nextFrame()) );
  28.  
    m_timer->start( 1000.0 / m_cap.get( cv::CAP_PROP_FPS));
  29.  
    return true;
  30.  
    }
  31.  
     
  32.  
    void QMoviePlayer::nextFrame()
  33.  
    {
  34.  
    // Nothing to do if capture object is not open
  35.  
    //
  36.  
    if( !m_cap.isOpened()) return;
  37.  
    m_cap.read(m_cv_img);
  38.  
    if(m_cv_img.empty()) return;
  39.  
    _copyImage();
  40.  
    this->update();
  41.  
    }
  42.  
     
  43.  
    void QMoviePlayer::paintEvent( QPaintEvent* e )
  44.  
    {
  45.  
    QPainter painter( this );
  46.  
    painter.drawImage( QPoint( ui.frame->x(),ui.frame->y()),m_qt_img);
  47.  
    }
  48.  
     
  49.  
    void QMoviePlayer::_copyImage( void)
  50.  
    {
  51.  
    // Copy the image data into the Qt QImage
  52.  
    //
  53.  
    cv::Mat cv_header_to_qt_image(
  54.  
    cv::Size(
  55.  
    m_qt_img.width(),
  56.  
    m_qt_img.height()
  57.  
    ),
  58.  
    CV_8UC3,
  59.  
    m_qt_img.bits()
  60.  
    );
  61.  
    cv::cvtColor(m_cv_img,cv_header_to_qt_image, cv::COLOR_BGR2RGB);
  62.  
    }

        main.cpp文件内容如下,就是qt程序启动后,调用前面定义的QMoviePlayer对象,读取视频文件(argv[1])及刷新显示:

  1.  
    #include <QApplication>
  2.  
    #include <QMoviePlayer.h>
  3.  
     
  4.  
    int main( int argc, char* argv[])
  5.  
    {
  6.  
    QApplication app( argc, argv);
  7.  
    QMoviePlayer mp;
  8.  
    mp.open( argv[1]);
  9.  
    mp.show();
  10.  
    return app.exec();
  11.  
    }

三、编译及测试

        3.1 程序编译

        进入opencv_qt目录

        运行vcbuild_2015.bat,执行大致如下(本文是直接在vscode命令窗口执行):

学新通

        3.2 程序运行

         进入opencv_qt\bin\Debug,启动命令窗口运行是缺失qt动态库的,因此将qt动态库拷贝到该目录下运行,注意debug和release的区别,为了方便,本文把需要运行的视频文件也拷贝到了该目录下,如下图:

学新通

         启动命令窗口,并运行opencv_qt.exe

学新通

         程序启动,加载视频进行播放,如果不能正常播放,可以通过日志输出信息进行定位排查。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfgaiig
系列文章
更多 icon
同类精品
更多 icon
继续加载