OpenCV實戰(一)Qt+OpenCV實戰

前言

  本文主要介紹了用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 );
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章