在Qt5.2上配置opencv2.9
我們的作業環境是在win10
使用的IDE為 Qt Creator (Community) / Qt 5.2
使用opencv249版 也可用2411、或者opencv3
動機是 覺得 Qt 和opencv的媒合性很高
是很有潛力的技術
而且可以寫 視窗介面 是 還不錯的 一個 C++ 框架
成品效果
最主要是用來和影像處理來做結合
讓使用者更能體會到 user friendly
XDD所以可以學習一下
還沒下載Qt的
附上連結給大家
https://download.qt.io/archive/qt/5.2/5.2.0/
5.2只支援到 Microsoft Visual Studio 2012
如果要到2013 就升到5.3喔
最新5.7有支援 vs2015
不過經過測試發現最穩定的是5.2這版
【第一階段 - 新增Qt專案】
首先開啟 Qt 之後
New 一個 新的 project
Application --> Qt Console Application
【第二階段 - 配置opencv】
到 .pro 區塊 去配置opencv
【配置】
還有一步就是動態涵式庫
記得要加入剛剛設定的編譯資料夾中或者在環境設定中加入連結喔~~
法一、
C:\OpenCV_2_4_9\build\x86\vc12\bin資料夾底下的dll檔複製至剛剛設定的編譯資料夾,如F:\cv_Qt\build-Qt_opencv_webcam-Desktop_Qt_5_2_0_MSVC2012_OpenGL_64bit-Debug。
法二、
電腦->內容->進階系統設定->環境變數中的Path加入
C:\OpenCV_2_4_9\build\x86\vc11\bin連結。
【第三階段 - 視窗的拖拉設計】
捨麼c++竟然也可以進行視窗的配置
沒錯 在 Qt Creator 的強大之下
開發者可根據自己的需求去進行視窗設置
【第四階段 - 按鈕觸發事件撰寫】
右鍵 --> 跳到信號槽
可以選擇 clicked 事件
首先是 mainwindow.h
如果你懶的話
預設就叫做 mainwindow
mainwindow.h
openCV打開視頻文件
創建一個cv::VideoCapture類的實體,
然後在迴圈中照一定的時間間隔
讀取每一frame影像即可實現視頻文件的讀取。
cv::VideoCapture類提供一個方法是open( ),可以打開一個video或者webcam來獲取視頻流
我們為了實現點擊相應的按鍵打開文件或攝像頭,可以在槽函數中實現該過程,代碼如下。
mainwindow.cpp
Mat類型轉換為QImage類型
在上述代碼中,我們看到有個Mat2QImage函數,
可將openCV的Mat轉換為QImage型態,以便在Qt下顯示視頻圖像。
其中需要將cv::Mat的BGR通道順序變換為QImage的RGB順序,
可以使用cv::cvtColor函數實現,
以上是對兩種圖像類型的data部分的格式進行調整,
下一步只需要明確Mat的頭結構裡的變量與QImage的頭結構裡的變量的
對應關係即可實現轉換,有如下對應關係
QImage Mat 指標
uchar* bits()
uchar* data
寬度int width() int cols
高度int height() int rows
步長int bytesPerLine() cols * channels()
格式
Format_Indexed8 8UC1, GRAY,灰度圖
Format_RGB888 8UC3, BGR ,3通道真彩色(需要使用cvtColor調換順序) Format_ARGB32 8UC4, BGRA,4通道真彩色(需要使用cvtColor調換順序)
使用的IDE為 Qt Creator (Community) / Qt 5.2
使用opencv249版 也可用2411、或者opencv3
動機是 覺得 Qt 和opencv的媒合性很高
是很有潛力的技術
而且可以寫 視窗介面 是 還不錯的 一個 C++ 框架
成品效果
最主要是用來和影像處理來做結合
讓使用者更能體會到 user friendly
XDD所以可以學習一下
還沒下載Qt的
附上連結給大家
https://download.qt.io/archive/qt/5.2/5.2.0/
5.2只支援到 Microsoft Visual Studio 2012
如果要到2013 就升到5.3喔
最新5.7有支援 vs2015
不過經過測試發現最穩定的是5.2這版
【第一階段 - 新增Qt專案】
首先開啟 Qt 之後
New 一個 新的 project
Application --> Qt Console Application
【第二階段 - 配置opencv】
到 .pro 區塊 去配置opencv
【配置】
#-------------------------------------------------
#
# Project created by QtCreator 2016-07-25T03:23:43
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Qt_opencv_webcam
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:\opencv249\opencv\build\include
C:\opencv249\opencv\build\include\opencv
C:\opencv249\opencv\build\include\opencv2
CONFIG(debug,debug|release)
{
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_core249d.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_highgui249d.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_imgproc249d.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_objdetect249d.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_contrib249d.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_ml249d.lib
}
CONFIG(release,debug|release)
{
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_core249.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_highgui249.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_imgproc249.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_objdetect249.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_contrib249.lib
LIBS += C:\opencv249\opencv\build\x64\vc12\lib\opencv_ml249.lib
}
還有一步就是動態涵式庫
記得要加入剛剛設定的編譯資料夾中或者在環境設定中加入連結喔~~
法一、
C:\OpenCV_2_4_9\build\x86\vc12\bin資料夾底下的dll檔複製至剛剛設定的編譯資料夾,如F:\cv_Qt\build-Qt_opencv_webcam-Desktop_Qt_5_2_0_MSVC2012_OpenGL_64bit-Debug。
法二、
電腦->內容->進階系統設定->環境變數中的Path加入
C:\OpenCV_2_4_9\build\x86\vc11\bin連結。
【第三階段 - 視窗的拖拉設計】
捨麼c++竟然也可以進行視窗的配置
沒錯 在 Qt Creator 的強大之下
開發者可根據自己的需求去進行視窗設置
【第四階段 - 按鈕觸發事件撰寫】
右鍵 --> 跳到信號槽
可以選擇 clicked 事件
首先是 mainwindow.h
如果你懶的話
預設就叫做 mainwindow
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QFileDialog>
#include <QTimer>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include"opencv2/opencv.hpp"
using namespace cv;
using namespace std;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void nextFrame();
void on_pushButton_clicked(); // open file
void on_pushButton_2_clicked(); // open webcam
void on_pushButton_3_clicked(); // process
void on_pushButton_4_clicked(); //
void on_pushButton_5_clicked();
private:
Ui::MainWindow *ui;
Mat frame;
VideoCapture capture;
QImage image , image1;
QTimer *timer;
double rate;//fps
VideoWriter writer;
};
#endif // MAINWINDOW_H
openCV打開視頻文件
創建一個cv::VideoCapture類的實體,
然後在迴圈中照一定的時間間隔
讀取每一frame影像即可實現視頻文件的讀取。
cv::VideoCapture類提供一個方法是open( ),可以打開一個video或者webcam來獲取視頻流
我們為了實現點擊相應的按鍵打開文件或攝像頭,可以在槽函數中實現該過程,代碼如下。
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
QImage Mat2QImage(cv::Mat cvImg) // opencv 轉 QImage 的方法
{
QImage qImg;
if(cvImg.channels()==3) //3 channels color image
{
//首先因為opencv的Mat容器盛載的通道順序為B->G->R
//在Qt中使用的是QImage通道順序是R->G->B因此我們須將opencv的Mat通道反敘(轉換)
cv::cvtColor(cvImg,cvImg,CV_BGR2RGB);
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols, cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
else if(cvImg.channels()==1) //grayscale image
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_Indexed8);
}
else
{
qImg =QImage((const unsigned char*)(cvImg.data),
cvImg.cols,cvImg.rows,
cvImg.cols*cvImg.channels(),
QImage::Format_RGB888);
}
return qImg;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->setScaledContents(true);
//fit video to label area
//capture.open(0); //open the default camera
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
//capture >> frame;
if (!frame.empty())
{
image = Mat2QImage(frame);
ui->label->setPixmap(QPixmap::fromImage(image));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::nextFrame()
{
capture>>frame;
if(!frame.empty())
{
image = Mat2QImage(frame);
ui->label->setPixmap(QPixmap::fromImage(image));
}
}
void MainWindow::on_pushButton_clicked()
{
if (capture.isOpened())
capture.release(); //decide if capture is already opened; if so,close it
QString filename =QFileDialog::getOpenFileName(this,tr("Open Video File"),".",tr("Video Files(*.avi *.mp4 *.flv *.mkv)"));
capture.open(filename.toLocal8Bit().data());
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
if (!frame.empty())
{
image = Mat2QImage(frame);
ui->label->setPixmap(QPixmap::fromImage(image));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
}
void MainWindow::on_pushButton_2_clicked()
{
if (capture.isOpened())
capture.release(); //decide if capture is already opened; if so,close it
capture.open(0); //open the default camera
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
if (!frame.empty())
{
image = Mat2QImage(frame);
ui->label->setPixmap(QPixmap::fromImage(image));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
}
void MainWindow::on_pushButton_3_clicked()
{
//if (capture.isOpened())
// capture.release(); //decide if capture is already opened; if so,close it
//if (capture.isOpened())
//{
Mat cannyImg ;
if (capture.isOpened())
capture.release(); //decide if capture is already opened; if so,close it
//capture.open(0); //open the default camera
if (capture.isOpened())
{
rate= capture.get(CV_CAP_PROP_FPS);
capture >> frame;
Canny(frame, cannyImg, 0, 30, 3);
//image = Mat2QImage(cannyImg);
if (!frame.empty())
{
Canny(frame, cannyImg, 0, 30, 3);
image = Mat2QImage(cannyImg);
ui->label->setPixmap(QPixmap::fromImage(image));
timer = new QTimer(this);
timer->setInterval(1000/rate); //set timer match with FPS
connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
timer->start();
}
}
//ui->label->setPixmap(QPixmap::fromImage(image));
//ui->label->resize(ui->label->pixmap()->size());
//namedWindow("Canny");
//imshow("Canny", cannyImg);
}
void MainWindow::on_pushButton_4_clicked()
{
writer.open("F:/cv_Qt/myrec.avi",CV_FOURCC('P','I','M','1'), /*capture.get(CV_CAP_PROP_FPS)*/30, cv::Size(frame.cols, frame.rows),true);
int t=300;
while(t--)
{
writer.write(frame);
} //record 100 frames
ui->pushButton_4->setDisabled(true);
//if successfully start videoWriter, disable the button
}
void MainWindow::on_pushButton_5_clicked()
{
writer.release();
}
Mat類型轉換為QImage類型
在上述代碼中,我們看到有個Mat2QImage函數,
可將openCV的Mat轉換為QImage型態,以便在Qt下顯示視頻圖像。
其中需要將cv::Mat的BGR通道順序變換為QImage的RGB順序,
可以使用cv::cvtColor函數實現,
以上是對兩種圖像類型的data部分的格式進行調整,
下一步只需要明確Mat的頭結構裡的變量與QImage的頭結構裡的變量的
對應關係即可實現轉換,有如下對應關係
QImage Mat 指標
uchar* bits()
uchar* data
寬度int width() int cols
高度int height() int rows
步長int bytesPerLine() cols * channels()
格式
Format_Indexed8 8UC1, GRAY,灰度圖
Format_RGB888 8UC3, BGR ,3通道真彩色(需要使用cvtColor調換順序) Format_ARGB32 8UC4, BGRA,4通道真彩色(需要使用cvtColor調換順序)
留言
張貼留言