最近在学习Qt和OpenCV,于是萌生了使用Qt和OpenCV做一个Demo项目,用于OpenCV图像处理的想法。
周末抽时间做了一个,效果还可以,分享一下。
Code地址,
https://gitlab.com/zhuge20100104/cpp_practice/-/tree/master/cv_demo/02_filters
CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(02_filters LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_BINARY_DIR /home/fredric/code/cpp_practice/cv_demo/02_filters/build)
add_definitions(-g)
#add_definitions(-DQT_QML_DEBUG)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
find_package(Qt5 COMPONENTS Core Quick QuickControls2 REQUIRED)
add_executable(${PROJECT_NAME} "main.cpp" "util.cpp" "cv_image_item.cpp" "qml.qrc")
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2 ${CONAN_LIBS})
conanfile.txt
[requires]
zlib/1.2.12
libpng/1.5.2
opencv/4.5.5
[generators]
cmake
cv_image_item.h
#ifndef _FREDRIC_CV_IMAGE_ITEM_H_
#define _FREDRIC_CV_IMAGE_ITEM_H_
#include <QtQuick/QQuickPaintedItem>
#include <QtGui/QPixmap>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
class CVImageItem: public QQuickPaintedItem {
Q_OBJECT
Q_PROPERTY(cv::Mat mat READ mat)
public:
CVImageItem(QQuickItem* parent=0);
void paint(QPainter* painter) override;
Q_INVOKABLE void setSource(QString const& filePath);
Q_INVOKABLE void medianMat(cv::Mat const& srcMat);
Q_INVOKABLE void gaussianMat(cv::Mat const& srcMat);
Q_INVOKABLE void bilateralMat(cv::Mat const& srcMat);
cv::Mat mat() const;
private:
cv::Mat m_mat;
QString sourcePath;
};
#endif
cv_image_item.cpp
#include "cv_image_item.h"
#include "util.h"
#include <iostream>
#include <QtGui/QPainter>
CVImageItem::CVImageItem(QQuickItem* parent):
QQuickPaintedItem(parent){
}
void CVImageItem::paint(QPainter* painter) {
painter->setRenderHints(QPainter::Antialiasing, true);
std::cout << "paint" << std::endl;
QPoint top_left((int)x(), (int)y());
QSize size(width(), height());
QRect rect(top_left, size);
std::cout << "x:" << x() << ", y:" << y() << std::endl;
std::cout << "w:" << width() << ", h:" << height() << std::endl;
painter->drawPixmap(rect, util::matToPixmap(size,m_mat));
}
void CVImageItem::setSource(QString const& filePath) {
QString temp = filePath;
sourcePath = temp.remove("file://");
std::cout << sourcePath.toStdString() << std::endl;
util::readImage(sourcePath,m_mat);
update();
}
cv::Mat CVImageItem::mat() const {
return m_mat;
}
void CVImageItem::medianMat(cv::Mat const& srcMat) {
std::cout <<"median Mat" << std::endl;
cv::Mat temp = srcMat;
cv::medianBlur(temp, m_mat, 15);
update();
}
void CVImageItem::gaussianMat(cv::Mat const& srcMat) {
std::cout <<"gaussian Mat" << std::endl;
cv::Mat temp = srcMat;
cv::GaussianBlur(temp, m_mat, cv::Size(15, 15), 0);
update();
}
void CVImageItem::bilateralMat(cv::Mat const& srcMat) {
std::cout <<"bilateral Mat" << std::endl;
cv::Mat temp = srcMat;
cv::bilateralFilter(temp, m_mat, 15, 95, 45);
update();
}
main.cpp
#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlDebuggingEnabler>
#include "cv_image_item.h"
int main(int argc, char *argv[])
{
QQmlDebuggingEnabler enabler;
qmlRegisterType<CVImageItem>("cvimages", 1, 0, "CVImageItem");
qRegisterMetaType<cv::Mat>("cv::Mat");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);
return app.exec();
}
PaintItem.qml
import QtQuick 2.12
import QtQuick.Controls 2.4
import cvimages 1.0
Column {
property alias text: label.text
property alias image: img
Label {
id:label
text: "Simple"
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: parent.width
height: 10
}
Rectangle {
border.width: 2
border.color: "gray"
id: content
width: 600
height: 380
CVImageItem
{
anchors.fill: parent
id: img
}
}
}
main.qml
import QtQuick 2.12
import Qt.labs.platform 1.1
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.2
ApplicationWindow
{
visible: true
title: qsTr("OpenCV图像处理助手")
color:"#FFFFFF"
x:0
y:0
width: 1400; height: 1300
menuBar: MenuBar
{
Menu
{
title: qsTr("文件")
MenuItem
{
text: qsTr("打开文件")
icon.name: "document-open"
onTriggered:
{
fileOpenDialog.open()
}
}
MenuItem
{
text: qsTr("更新Mat")
icon.source: "images/process.svg"
onTriggered:
{
medianImage.image.medianMat(srcImage.image.mat)
gaussianImage.image.gaussianMat(srcImage.image.mat)
bilateralImage.image.bilateralMat(srcImage.image.mat)
}
}
MenuSeparator {}
MenuItem
{
text: qsTr("退出")
onTriggered: Qt.quit()
}
}
}
FileDialog {
id: fileOpenDialog
title: "Select an image file"
folder: shortcuts.documents
nameFilters: [
"Image Files (*.png *.jpeg *.jpg *.webp)"
]
onAccepted: {
srcImage.image.setSource(fileOpenDialog.fileUrl)
}
}
PaintItem {
id: srcImage
text: "Source Image"
x: 0
y: 0
}
PaintItem {
id: medianImage
text: "Median Image"
x: 650
y: 0
}
PaintItem {
id: gaussianImage
text: "Gaussian Image"
x: 0
y: 440
}
PaintItem {
id: bilateralImage
text: "Bilateral Image"
x: 650
y: 440
}
}
程序执行的效果如下,