前言
本文主要介紹了用Qt創建OpenCV工程實例。相關代碼和工程點此下載。後續的相關內容也會更具這個Demo進行展開,這裏簡單介紹一下這個Demo。
操作流程
創建Qt工程
在Qt中新建一個QWidgets工程
在工程中導入OpenCV的鏈接庫
其中CVLIB爲筆者的OpenCV庫對應的環境變量
INCLUDEPATH += \
$$(CVLIB)/include
DEPENDPATH += \
$$(CVLIB)/lib
win32:CONFIG(debug, debug|release):{
LIBS += -L$$(CVLIB)/lib/ -lopencv_aruco410d\
-lopencv_bgsegm410d \
-lopencv_bioinspired410d\
-lopencv_calib3d410d\
-lopencv_ccalib410d\
-lopencv_core410d\
-lopencv_cudaarithm410d\
-lopencv_cudabgsegm410d\
-lopencv_cudacodec410d\
-lopencv_cudafeatures2d410d\
-lopencv_cudafilters410d\
-lopencv_cudaimgproc410d\
-lopencv_cudalegacy410d\
-lopencv_cudaobjdetect410d\
-lopencv_cudaoptflow410d\
-lopencv_cudastereo410d\
-lopencv_cudawarping410d\
-lopencv_cudev410d\
-lopencv_datasets410d\
-lopencv_dnn410d\
-lopencv_dnn_objdetect410d\
-lopencv_dpm410d\
-lopencv_face410d\
-lopencv_features2d410d\
-lopencv_flann410d\
-lopencv_fuzzy410d\
-lopencv_gapi410d\
-lopencv_hdf410d\
-lopencv_hfs410d\
-lopencv_highgui410d\
-lopencv_imgcodecs410d\
-lopencv_imgproc410d\
-lopencv_img_hash410d\
-lopencv_line_descriptor410d\
-lopencv_ml410d\
-lopencv_objdetect410d\
-lopencv_optflow410d\
-lopencv_phase_unwrapping410d\
-lopencv_photo410d\
-lopencv_plot410d\
-lopencv_quality410d\
-lopencv_reg410d\
-lopencv_rgbd410d\
-lopencv_saliency410d\
-lopencv_shape410d\
-lopencv_stereo410d\
-lopencv_stitching410d\
-lopencv_structured_light410d\
-lopencv_superres410d\
-lopencv_surface_matching410d\
-lopencv_text410d\
-lopencv_tracking410d\
-lopencv_video410d\
-lopencv_videoio410d\
-lopencv_videostab410d\
-lopencv_xfeatures2d410d\
-lopencv_ximgproc410d\
-lopencv_xobjdetect410d\
-lopencv_xphoto410d
}else:{
LIBS +=-L$$(CVLIB)/lib \
-lopencv_aruco410 \
-lopencv_bgsegm410 \
-lopencv_bioinspired410 \
-lopencv_calib3d410\
-lopencv_ccalib410\
-lopencv_core410\
-lopencv_cudaarithm410\
-lopencv_cudabgsegm410\
-lopencv_cudacodec410\
-lopencv_cudafeatures2d410\
-lopencv_cudafilters410\
-lopencv_cudaimgproc410\
-lopencv_cudalegacy410\
-lopencv_cudaobjdetect410\
-lopencv_cudaoptflow410\
-lopencv_cudastereo410\
-lopencv_cudawarping410\
-lopencv_cudev410\
-lopencv_datasets410\
-lopencv_dnn410\
-lopencv_dnn_objdetect410\
-lopencv_dpm410\
-lopencv_face410\
-lopencv_features2d410\
-lopencv_flann410\
-lopencv_fuzzy410\
-lopencv_gapi410\
-lopencv_hdf410\
-lopencv_hfs410\
-lopencv_highgui410\
-lopencv_imgcodecs410\
-lopencv_imgproc410\
-lopencv_img_hash410\
-lopencv_line_descriptor410\
-lopencv_ml410\
-lopencv_objdetect410\
-lopencv_optflow410\
-lopencv_phase_unwrapping410\
-lopencv_photo410\
-lopencv_plot410\
-lopencv_quality410\
-lopencv_reg410\
-lopencv_rgbd410\
-lopencv_saliency410\
-lopencv_shape410\
-lopencv_stereo410\
-lopencv_stitching410\
-lopencv_structured_light410\
-lopencv_superres410\
-lopencv_surface_matching410\
-lopencv_text410\
-lopencv_tracking410\
-lopencv_video410\
-lopencv_videoio410\
-lopencv_videostab410\
-lopencv_xfeatures2d410\
-lopencv_ximgproc410\
-lopencv_xobjdetect410\
-lopencv_xphoto410
}
實現簡單的功能
Qt程序的發佈
初學者發佈Qt程序多使用winployqt,即在生成exe的文件下,使用winployqt xxx.exe。如此便可以將程序打包發佈
QPixmap與cv::Mat互轉
因爲要藉助和研究OpenCV的特性,爲了在Qt中使用,因此這裏需要轉化QPixmap和cv::Mat
//@file imgfile.h
#ifndef IMGFILE_H
#define IMGFILE_H
#include <opencv2/opencv.hpp>
#include <QImage>
#include <QPixmap>
QImage cvMatToQImage( const cv::Mat &inMat );
cv::Mat QImageToCvMat( const QImage &inImage, bool inCloneImageData = true );
QPixmap cvMatToQPixmap( const cv::Mat &inMat );
cv::Mat QPixmapToCvMat( const QPixmap &inPixmap, bool inCloneImageData = true );
#endif // IMGFILE_H
@file imgfile.cpp
#include "imgfile.h"
#include <QDebug>
QImage cvMatToQImage( const cv::Mat &inMat )
{
switch ( inMat.type() )
{
// 8-bit, 4 channel
case CV_8UC4:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_ARGB32 );
return image;
}
// 8-bit, 3 channel
case CV_8UC3:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_RGB888 );
return image.rgbSwapped();
}
// 8-bit, 1 channel
case CV_8UC1:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_Grayscale8 );//Format_Alpha8 and Format_Grayscale8 were added in Qt 5.5
return image;
}
default:
qWarning() << "CVS::cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type();
break;
}
return QImage();
}
QPixmap cvMatToQPixmap( const cv::Mat &inMat )
{
return QPixmap::fromImage( cvMatToQImage( inMat ) );
}
//將QImage轉化爲Mat
cv::Mat QImageToCvMat( const QImage &inImage, bool inCloneImageData )
{
switch ( inImage.format() )
{
// 8-bit, 4 channel
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
{
cv::Mat mat( inImage.height(), inImage.width(),
CV_8UC4,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);
return (inCloneImageData ? mat.clone() : mat);
}
// 8-bit, 3 channel
case QImage::Format_RGB32:
case QImage::Format_RGB888:
{
if ( !inCloneImageData )
{
qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";
}
QImage swapped = inImage;
if ( inImage.format() == QImage::Format_RGB32 )
{
swapped = swapped.convertToFormat( QImage::Format_RGB888 );
}
swapped = swapped.rgbSwapped();
return cv::Mat( swapped.height(), swapped.width(),
CV_8UC3,
const_cast<uchar*>(swapped.bits()),
static_cast<size_t>(swapped.bytesPerLine())
).clone();
}
// 8-bit, 1 channel
case QImage::Format_Indexed8:
{
cv::Mat mat( inImage.height(), inImage.width(),
CV_8UC1,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);
return (inCloneImageData ? mat.clone() : mat);
}
default:
qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
break;
}
return cv::Mat();
}
cv::Mat QPixmapToCvMat( const QPixmap &inPixmap, bool inCloneImageData )
{
return QImageToCvMat( inPixmap.toImage(), inCloneImageData );
}