本文主要针对开发人脸识别demo时图像较为卡顿做出探索,利用GPU实现图像信息的处理!
在进行图像处理或者人脸识别是需要给电脑安装opencv环境,可参考其他文章进行配置;
.pro文件
QT += core gui opengl
# 必须添加opengl模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
#若将D:/opencv/install/install/include添加到环境变量,下面INCLUDEPATH这三行可以不写
INCLUDEPATH += F:/Opencv/build/install/include/opencv \
F:/Opencv/build/install/include/opencv2 \
F:/Opencv/build/install/include
LIBS += -L F:/Opencv/build/install/x64/mingw/lib/libopencv_*.a
INCLUDEPATH+=../cqtopencvviewergl
SOURCES += \
cqtopencvviewergl/cqtopencvviewergl.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
cqtopencvviewergl/cqtopencvviewergl.h \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
cqtopencvviewergl.h
#ifndef CQTOPENCVVIEWERGL_H
#define CQTOPENCVVIEWERGL_H
#include
#include
#include
#include
#include
class CQtOpenCVViewerGl : public QOpenGLWidget, protected QOpenGLFunctions_2_0
{
Q_OBJECT
public:
explicit CQtOpenCVViewerGl(QWidget *parent = 0);
signals:
void imageSizeChanged( int outW, int outH ); /// Used to resize the image outside the widget
public slots:
bool showImage(const cv::Mat& image); /// Used to set the image to be viewed
protected:
void initializeGL(); /// OpenGL initialization
void paintGL(); /// OpenGL Rendering
void resizeGL(int width, int height); /// Widget Resize Event
void updateScene();
void renderImage();
private:
QImage mRenderQtImg; /// Qt image to be rendered
QImage mResizedImg;
cv::Mat mOrigImage; /// original OpenCV image to be shown
QColor mBgColor; /// Background color
float mImgRatio; /// height/width ratio
int mRenderWidth;
int mRenderHeight;
int mRenderPosX;
int mRenderPosY;
void recalculatePosition();
std::mutex drawMutex;
};
#endif // CQTOPENCVVIEWERGL_H
cqtopencvviewergl.cpp
#include "cqtopencvviewergl.h"
CQtOpenCVViewerGl::CQtOpenCVViewerGl(QWidget *parent) :
QOpenGLWidget(parent)
{
mBgColor = QColor::fromRgb(150, 150, 150);
}
void CQtOpenCVViewerGl::initializeGL()
{
makeCurrent();
initializeOpenGLFunctions();
float r = ((float)mBgColor.darker().red())/255.0f;
float g = ((float)mBgColor.darker().green())/255.0f;
float b = ((float)mBgColor.darker().blue())/255.0f;
glClearColor(r,g,b,1.0f);
}
void CQtOpenCVViewerGl::resizeGL(int width, int height)
{
makeCurrent();
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, -height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
recalculatePosition();
emit imageSizeChanged(mRenderWidth, mRenderHeight);
updateScene();
}
void CQtOpenCVViewerGl::updateScene()
{
if (this->isVisible()) update();
}
void CQtOpenCVViewerGl::paintGL()
{
makeCurrent();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderImage();
}
void CQtOpenCVViewerGl::renderImage()
{
drawMutex.lock();
makeCurrent();
glClear(GL_COLOR_BUFFER_BIT);
if (!mRenderQtImg.isNull())
{
glLoadIdentity();
glPushMatrix();
{
if (mResizedImg.width() <= 0)
{
if (mRenderWidth == mRenderQtImg.width() && mRenderHeight == mRenderQtImg.height())
mResizedImg = mRenderQtImg;
else
mResizedImg = mRenderQtImg.scaled(QSize(mRenderWidth, mRenderHeight),
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
}
// ---> Centering image in draw area
glRasterPos2i(mRenderPosX, mRenderPosY);
glPixelZoom(1, -1);
glDrawPixels(mResizedImg.width(), mResizedImg.height(), GL_RGBA, GL_UNSIGNED_BYTE, mResizedImg.bits());
}
glPopMatrix();
// end
glFlush();
}
drawMutex.unlock();
}
void CQtOpenCVViewerGl::recalculatePosition()
{
mImgRatio = (float)mOrigImage.cols/(float)mOrigImage.rows;
mRenderWidth = this->size().width();
mRenderHeight = floor(mRenderWidth / mImgRatio);
if (mRenderHeight > this->size().height())
{
mRenderHeight = this->size().height();
mRenderWidth = floor(mRenderHeight * mImgRatio);
}
mRenderPosX = floor((this->size().width() - mRenderWidth) / 2);
mRenderPosY = -floor((this->size().height() - mRenderHeight) / 2);
mResizedImg = QImage();
}
bool CQtOpenCVViewerGl::showImage(const cv::Mat& image)
{
drawMutex.lock();
if (image.channels() == 3)
cvtColor(image, mOrigImage, CV_BGR2RGBA);
else if (image.channels() == 1)
cvtColor(image, mOrigImage, CV_GRAY2RGBA);
else if (image.channels() == 4)
mOrigImage = image;
else return false;
mRenderQtImg = QImage((const unsigned char*)(mOrigImage.data),
mOrigImage.cols, mOrigImage.rows,
mOrigImage.step1(), QImage::Format_RGB32);
recalculatePosition();
updateScene();
drawMutex.unlock();
return true;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_actionStart_triggered();
void on_action_Vertical_Mirror_triggered(bool checked);
void on_action_Horizontal_Mirror_triggered(bool checked);
private:
cv::VideoCapture mCapture;
Ui::MainWindow *ui;
protected:
void timerEvent(QTimerEvent *event);
private:
bool mFlipVert;
bool mFlipHoriz;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mFlipVert=false;
mFlipHoriz=false;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionStart_triggered()
{
if( !mCapture.isOpened() )
if( !mCapture.open( 0 ) )
return;
startTimer(0);
}
void MainWindow::timerEvent(QTimerEvent *event)
{
cv::Mat image;
mCapture >> image;
if( mFlipVert && mFlipHoriz )
cv::flip( image,image, -1);
else if( mFlipVert )
cv::flip( image,image, 0);
else if( mFlipHoriz )
cv::flip( image,image, 1);
// Do what you want with the image :-)
// Show the image
ui->openCVviewer->showImage( image );
}
void MainWindow::on_action_Vertical_Mirror_triggered(bool checked)
{
mFlipVert = checked;
}
void MainWindow::on_action_Horizontal_Mirror_triggered(bool checked)
{
mFlipHoriz = checked;
}
点赞+收藏 你就是最棒!❤❤❤