Tabla de contenido
1.1 configuración de interfaz de usuario
1.2 Guardar interfaz de usuario y salida de código
2.1 Directorio del proyecto y configuración de compilación
En primer lugar, permítanme decirles que este es un caso del documento de aprendizaje de OpenCV 3, pero la descripción está un poco omitida, solo hay algunas descripciones de código breves, lo grabaré y lo compartiré con todos durante el proceso de aprendizaje y verificación. .
1. creación de qt_ui
1.1 configuración de interfaz de usuario
Este artículo utiliza la versión qt5.8_msvc2015_64.
Ingrese al directorio bin de qt y abra la herramienta de diseño qt_ui designer.exe
Cree un formulario de widget, el objeto QWidget, denominado QMoviePlayer.
Luego cree un objeto QFrame llamado marco. Este objeto se puede usar para abrir un cuadro de visualización de relación de aspecto adecuada en el formulario QMoviePlayer. Este cuadro de visualización se usa para mostrar videos.
Después de completar la configuración, guarde la interfaz de usuario, por ejemplo QMoviePlayer.ui
1.2 Guardar interfaz de usuario y salida de código
El contenido xml de mi archivo QMoviePlayer.ui es el siguiente:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QMoviePlayer</class>
<widget class="QWidget" name="QMoviePlayer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>303</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>601</width>
<height>241</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Haga clic en el menú del formulario, ingrese Ver código, guarde el archivo de código como ui_QMoviePlayer.h o cree un nuevo archivo de encabezado y copie el contenido directamente en el archivo de encabezado y guárdelo.
El contenido del código de mi ui_QMoviePlayer.h es el siguiente.
/********************************************************************************
** Form generated from reading UI file 'QMoviePlayerp15136.ui'
**
** Created by: Qt User Interface Compiler version 5.8.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef QMOVIEPLAYERP15136_H
#define QMOVIEPLAYERP15136_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QFrame>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_QMoviePlayer
{
public:
QFrame *frame;
void setupUi(QWidget *QMoviePlayer)
{
if (QMoviePlayer->objectName().isEmpty())
QMoviePlayer->setObjectName(QStringLiteral("QMoviePlayer"));
QMoviePlayer->resize(600, 303);
frame = new QFrame(QMoviePlayer);
frame->setObjectName(QStringLiteral("frame"));
frame->setGeometry(QRect(0, 0, 601, 241));
frame->setFrameShape(QFrame::StyledPanel);
frame->setFrameShadow(QFrame::Raised);
retranslateUi(QMoviePlayer);
QMetaObject::connectSlotsByName(QMoviePlayer);
} // setupUi
void retranslateUi(QWidget *QMoviePlayer)
{
QMoviePlayer->setWindowTitle(QApplication::translate("QMoviePlayer", "Form", Q_NULLPTR));
} // retranslateUi
};
namespace Ui {
class QMoviePlayer: public Ui_QMoviePlayer {};
} // namespace Ui
QT_END_NAMESPACE
#endif // QMOVIEPLAYERP15136_H
2. Crear proyecto
2.1 Directorio del proyecto y configuración de compilación
Cree un archivo de proyecto en el directorio opencv_qt, la organización del proyecto es la siguiente:
opencv_qt
bin
build_vc
src
main.cpp
ui_QMoviePlayer.h
QMoviePlayer.h
QMoviePlayer.cpp
QMoviePlayer.ui
CMakeLists.txt #cmake工程
vcbuild_2015.bat #编译命令
ui_QMoviePlayer.h y QMoviePlayer.ui son los archivos de encabezado de código y de interfaz de usuario implementados previamente con Designer.exe.
El contenido del archivo CMakeLists.txt es el siguiente. Hay rastros de win/linux en este artículo. Sin embargo, este artículo solo implementa el método de compilación win basado en vc2015 + qt_vc2015 + opencv_vc. Este artículo no ha sido probado en Linux. Los lectores interesados pueden hacer clic en este módulo Implementación de soporte de ajuste (para casos de llamada y compilación de la biblioteca opencv Linux, consulte otras publicaciones de blog en esta columna). El enlace qt utiliza una biblioteca dinámica. La biblioteca opencv compilada en base a vc2015 está precompilada en este artículo ( Desarrollo de C/C++, instalación de opencv y aplicación bajo instalación win_c++ opencv Library_py_free-IoT Intelligent Blog-CSDN Blog ).
# CMake 最低版本号要求
cmake_minimum_required (VERSION 3.1.0)
# 项目信息
set(proname "opencv_qt")
project(${proname} VERSION 1.0.0 LANGUAGES CXX)
if(WIN32)
message(STATUS "windows compiling...")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
add_definitions(
-D_PLATFORM_IS_WINDOWS_
-D_CRT_SECURE_NO_WARNINGS
-D_WINSOCK_DEPRECATED_NO_WARNINGS
# -DZLIB_WINAPI
-DUNICODE
-D_UNICODE
# -DQT_DLL
# -DQT_CORE_LIB
# -DQT_GUI_LIB
# -DQT_WIDGETS_LIB
# -D CMAKE_CXX_FLAGS="/utf-8"
)
else(WIN32)
message(STATUS "linux compiling...")
# 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编译指定
add_definitions(
-D_PLATFORM_IS_LINUX_
"-g"
# "-std=gnu++0x"
"-std=c++11"
"-O2"
# "-pipe"
"-Wno-invalid-source-encoding"
"-Wdeprecated-declarations"
"-W"
"-fPIC"
"-Wall"
# "-Werror"
# "-Wshadow"
# "-Wformat"
# "-Wpointer-arith"
"-D_REENTRANT"
# "-D_USE_FAST_MACRO"
# "-Wno-long-long"
# "-Wuninitialized"
# "-D_POSIX_PTHREAD_SEMANTICS"
# "-Wno-unused-parameter"
"-fexceptions"
"-DQT_NO_DEBUG"
"-DDQT_QML_DEBUG"
)
endif(WIN32)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 创建 EXECUTABLE_OUTPUT_PATH 指向的文件夹
execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${EXECUTABLE_OUTPUT_PATH})
set(PROJECT_CUR_DIR .)
if(WIN32)
set(QTDIR "D:/workForSoftware/Qt/Qt5.8.0/5.8/msvc2015_64")
else(WIN32)
set(QTDIR "/opt/qt-5.8_static")
endif(WIN32)
message("QTDIR = ${QTDIR}")
set(Qt5_DIR "${QTDIR}/lib/cmake/Qt5")
message("Qt5_DIR = ${Qt5_DIR}")
set(CMAKE_AUTOMOC ON)
# set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
#查找需要的Qt库文件,最好每一个库都要写,Qt也会根据依赖关系自动添加
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
cmake_policy(SET CMP0020 NEW)
set(CMAKE_INCLUDE_CURRENT_DIR ON) #包含编译目录
FILE(GLOB srcfile ${PROJECT_CUR_DIR}/src/*.h ${PROJECT_CUR_DIR}/src/*.cpp ) #加载文件夹下的所有源码文件
LIST(APPEND code_file ${srcfile} ) #变量合并
include_directories(
"${PROJECT_CUR_DIR}"
"${PROJECT_CUR_DIR}/src"
"${PROJECT_CUR_DIR}/../../opencv_vc/include"
"${QTDIR}/include"
"${QTDIR}/include/QtCore"
"${QTDIR}/include/QtGui"
"${QTDIR}/include/QtWidgets"
)
#link 目录
link_directories(
"${QTDIR}/lib"
"${PROJECT_CUR_DIR}/../../opencv_VC/x64/vc14/lib"
)
message("RESOURCES = ${RESOURCES}")
add_executable(${proname} ${code_file} ${RESOURCES} ${RC_FILE} )
# 链接指定
set(link_lib
Qt5::Core Qt5::Gui Qt5::Widgets
)
if(WIN32)
if (CMAKE_BUILD_TYPE STREQUAL "release")
set(link_lib_opencv
opencv_img_hash460.lib opencv_world460.lib
)
else()
set(link_lib_opencv
opencv_img_hash460d.lib opencv_world460d.lib
)
endif()
endif(WIN32)
target_link_libraries(${proname}
${link_lib}
${link_lib_opencv}
)
#去除 CMD 窗口
if(WIN32)
message("CMAKE_BUILD_TYPE =${CMAKE_BUILD_TYPE}")
if (CMAKE_BUILD_TYPE STREQUAL "release")
if(MSVC)
set_target_properties(${proname} PROPERTIES
WIN32_EXECUTABLE YES
LINK_FLAGS "/ENTRY:mainCRTStartup"
)
elseif(CMAKE_COMPILER_IS_GNUCXX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
else()
message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
endif(MSVC)
endif()
endif(WIN32)
vcbuild_2015.bat es un script creado para facilitar la compilación. Los lectores también pueden compilar manualmente de acuerdo con el comando del script.
md build_vc
cd ./build_vc
@REM 单独编译时可能需要独立设置环境变量
if [%vccompilerversion%] EQU [] ( set vccompilerversion="Visual Studio 14 2015 Win64" )
@REM 工程配置
cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=debug
@REM 编译
cmake --build . --config debug
@REM 工程配置
cmake -G %vccompilerversion% .. -DCMAKE_BUILD_TYPE=release
@REM 编译
cmake --build . --config release
cd ..
2.2 Diseño del código fuente
Echemos un vistazo a cómo el código fuente implementa la lectura y reproducción de videos.
El contenido de QMoviePlayer.h es el siguiente. Este archivo de encabezado define un tipo de ventana. La parte de visualización de la ventana proviene del diseño de interfaz de usuario anterior "Ui::QMoviePlayer ui" y define "cv::VideoCapture m_cap" para capturar contenido de video:
#ifndef _QMOVIEPLAYER_H_
#define _QMOVIEPLAYER_H_
#include "ui_QMoviePlayer.h"
#include <QtWidgets/QWidget>
#include <QImage>
#include <opencv2/opencv.hpp>
#include <string>
using namespace std;
QT_BEGIN_NAMESPACE
class QPaintEvent;
class QTimer;
QT_END_NAMESPACE
class QMoviePlayer : public QWidget
{
Q_OBJECT
public:
QMoviePlayer(QWidget *parent = NULL);
virtual ~QMoviePlayer(){;}
bool open( string file );
public slots:
void nextFrame();
private:
void paintEvent( QPaintEvent* q);
void _copyImage( void);
private:
Ui::QMoviePlayer ui; //ui界面
cv::VideoCapture m_cap; //opencv的视频读取及捕获图像实现
QImage m_qt_img;
cv::Mat m_cv_img; //图像缓存矩阵
QTimer* m_timer;
};
#endif //_QMOVIEPLAYER_H_
El contenido de QMoviePlayer.cpp es el siguiente. La función abrir se usa para abrir un archivo de video y leer periódicamente los datos de la imagen del cuadro a través del objeto QTimer. nextFrame se usa para leer los datos de la imagen y actualizarlos en la visualización de la ventana; la función _copyImage es La clave para combinar opencv y QT convierte la imagen m_cv_img capturada por opencv en la imagen m_qt_img de qt, de modo que la imagen se pueda actualizar en la ventana en modo qt:
#include "QMoviePlayer.h"
#include <QPainter>
#include <QTimer>
QMoviePlayer::QMoviePlayer(QWidget *parent)
: QWidget(parent)
{
ui.setupUi( this );
}
bool QMoviePlayer::open( string file)
{
if( !m_cap.open( file)) return false;
// If we opened the file, set up everything now:
//
m_cap.read( m_cv_img );
m_qt_img = QImage(
QSize( m_cv_img.cols,m_cv_img.rows),
QImage::Format_RGB888
);
ui.frame->setMinimumSize( m_qt_img.width(),m_qt_img.height());
ui.frame->setMaximumSize( m_qt_img.width(),m_qt_img.height());
_copyImage();
m_timer = new QTimer( this );
connect(m_timer, SIGNAL( timeout()), this, SLOT( nextFrame()) );
m_timer->start( 1000.0 / m_cap.get( cv::CAP_PROP_FPS));
return true;
}
void QMoviePlayer::nextFrame()
{
// Nothing to do if capture object is not open
//
if( !m_cap.isOpened()) return;
m_cap.read(m_cv_img);
if(m_cv_img.empty()) return;
_copyImage();
this->update();
}
void QMoviePlayer::paintEvent( QPaintEvent* e )
{
QPainter painter( this );
painter.drawImage( QPoint( ui.frame->x(),ui.frame->y()),m_qt_img);
}
void QMoviePlayer::_copyImage( void)
{
// Copy the image data into the Qt QImage
//
cv::Mat cv_header_to_qt_image(
cv::Size(
m_qt_img.width(),
m_qt_img.height()
),
CV_8UC3,
m_qt_img.bits()
);
cv::cvtColor(m_cv_img,cv_header_to_qt_image, cv::COLOR_BGR2RGB);
}
El contenido del archivo main.cpp es el siguiente: después de iniciar el programa qt, se llama al objeto QMoviePlayer definido anteriormente, se lee el archivo de video (argv [1]) y se actualiza la pantalla:
#include <QApplication>
#include <QMoviePlayer.h>
int main( int argc, char* argv[])
{
QApplication app( argc, argv);
QMoviePlayer mp;
mp.open( argv[1]);
mp.show();
return app.exec();
}
3. Compilación y prueba.
3.1 Compilación del programa
Ingrese al directorio opencv_qt
Ejecute vcbuild_2015.bat, la ejecución es aproximadamente la siguiente (este artículo se ejecuta directamente en la ventana de comando vscode):
3.2 Programa en ejecución
Ingrese opencv_qt\bin\Debug e inicie la ventana de comandos. Falta la biblioteca dinámica qt. Por lo tanto, copie la biblioteca dinámica qt en este directorio y ejecútela. Preste atención a la diferencia entre depuración y lanzamiento. Para mayor comodidad, este artículo también copia los archivos de video que deben ejecutarse en este directorio, como se muestra a continuación:
Inicie la ventana de comandos y ejecute opencv_qt.exe
El programa se inicia y el video se carga para su reproducción. Si el video no se puede reproducir normalmente, la información de salida del registro se puede usar para posicionamiento y solución de problemas.