From aaf97a89331b21d4152fbbf26bcae846db44c3d0 Mon Sep 17 00:00:00 2001 From: Nash Date: Sun, 31 Aug 2014 12:11:34 +0700 Subject: added more advanced opencv-qt integration --- opencv-qt-integration-2/ImageApp.cpp | 92 ++++++++++++++++++++++++ opencv-qt-integration-2/ImageApp.h | 39 ++++++++++ opencv-qt-integration-2/ImageApp.pro | 7 ++ opencv-qt-integration-2/README.md | 39 ++++++++++ opencv-qt-integration-2/main.cpp | 10 +++ opencv-qt-integration-2/moc_ImageApp.cpp | 118 +++++++++++++++++++++++++++++++ 6 files changed, 305 insertions(+) create mode 100644 opencv-qt-integration-2/ImageApp.cpp create mode 100644 opencv-qt-integration-2/ImageApp.h create mode 100644 opencv-qt-integration-2/ImageApp.pro create mode 100644 opencv-qt-integration-2/README.md create mode 100644 opencv-qt-integration-2/main.cpp create mode 100644 opencv-qt-integration-2/moc_ImageApp.cpp diff --git a/opencv-qt-integration-2/ImageApp.cpp b/opencv-qt-integration-2/ImageApp.cpp new file mode 100644 index 0000000..5833bd8 --- /dev/null +++ b/opencv-qt-integration-2/ImageApp.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include "ImageApp.h" + +ImageApp::ImageApp() +{ + originalImage = cv::imread("../assets/The_Chapter_House.jpg"); + if (originalImage.data) { + cv::cvtColor(originalImage, originalImage, cv::COLOR_BGR2RGB); + } + setupUi(); + showImage(originalImage); +} + +/** + * Setup the widgets + */ +void ImageApp::setupUi() +{ + imageLabel = new QLabel(); + + originalButton = new QPushButton("Original"); + connect(originalButton, SIGNAL(clicked()), this, SLOT(showOriginalImage())); + + blurButton = new QPushButton("Gaussian Blur"); + connect(blurButton, SIGNAL(clicked()), this, SLOT(doGaussianBlur())); + + cannyButton = new QPushButton("Canny"); + connect(cannyButton, SIGNAL(clicked()), this, SLOT(doCanny())); + + quitButton = new QPushButton("Quit"); + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); + + buttonsLayout = new QVBoxLayout(); + buttonsLayout->addWidget(originalButton); + buttonsLayout->addWidget(blurButton); + buttonsLayout->addWidget(cannyButton); + buttonsLayout->addStretch(); + buttonsLayout->addWidget(quitButton); + + mainLayout = new QHBoxLayout(); + mainLayout->addWidget(imageLabel); + + if (originalImage.data) { + mainLayout->addLayout(buttonsLayout); + } + setLayout(mainLayout); + setWindowTitle("Image Processing with Qt and OpenCV"); +} + +/** + * Redraw original image + */ +void ImageApp::showOriginalImage() +{ + showImage(originalImage); +} + +/** + * Perform Canny edge detection on original image and display the result + */ +void ImageApp::doCanny() +{ + cv::Mat gray; + cv::cvtColor(originalImage, gray, cv::COLOR_RGB2GRAY); + cv::Canny(gray, processedImage, 150, 150); + cv::cvtColor(processedImage, processedImage, cv::COLOR_GRAY2RGB); + showImage(processedImage); +} + +/** + * Perform Gaussian blurring on original image and display the result + */ +void ImageApp::doGaussianBlur() +{ + cv::GaussianBlur(originalImage, processedImage, cv::Size(15, 15), 0, 0); + showImage(processedImage); +} + +/** + * Draw OpenCV matrix using QLabel + */ +void ImageApp::showImage(cv::Mat img) +{ + if (img.data) { + QImage _img(img.data, img.cols, img.rows, QImage::Format_RGB888); + imageLabel->setPixmap(QPixmap::fromImage(_img)); + } else { + imageLabel->setText("Cannot load the input image!"); + } +} diff --git a/opencv-qt-integration-2/ImageApp.h b/opencv-qt-integration-2/ImageApp.h new file mode 100644 index 0000000..bdedb9b --- /dev/null +++ b/opencv-qt-integration-2/ImageApp.h @@ -0,0 +1,39 @@ +#ifndef IMAGEAPP_H +#define IMAGEAPP_H + +#include +#include + +class QLabel; +class QVBoxLayout; +class QHBoxLayout; +class QPushButton; + +class ImageApp : public QWidget +{ + Q_OBJECT + +public: + ImageApp(); + +private slots: + void showOriginalImage(); + void doCanny(); + void doGaussianBlur(); + +private: + void setupUi(); + void showImage(cv::Mat); + + cv::Mat originalImage; + cv::Mat processedImage; + QLabel *imageLabel; + QPushButton *originalButton; + QPushButton *blurButton; + QPushButton *cannyButton; + QPushButton *quitButton; + QVBoxLayout *buttonsLayout; + QHBoxLayout *mainLayout; +}; + +#endif diff --git a/opencv-qt-integration-2/ImageApp.pro b/opencv-qt-integration-2/ImageApp.pro new file mode 100644 index 0000000..8a9bb7d --- /dev/null +++ b/opencv-qt-integration-2/ImageApp.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = ImageApp +QT += core widgets +HEADERS += ImageApp.h +SOURCES += ImageApp.cpp main.cpp +INCLUDEPATH += . /usr/local/include +LIBS += -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs diff --git a/opencv-qt-integration-2/README.md b/opencv-qt-integration-2/README.md new file mode 100644 index 0000000..c6d222b --- /dev/null +++ b/opencv-qt-integration-2/README.md @@ -0,0 +1,39 @@ +OpenCV - Qt Integration +======================= + +This code sample shows you how to do basic image manipulation to an image and display the result using the `QLabel` widget. The code loads `The_Chapter_House.jpg` from the `assets/` directory and provides two buttons to perform some basic manipulation. + +![screenshot](http://i.imgur.com/OPCiEw8.png) + +To compile and run the code, you need to have Qt 5 installed on your computer. The code is successfully tested on the following environment: + + - Mac OS X Mavericks + - Qt 5.3.0 + - OpenCV 3.0.0 + - Python 3.4.1 + +Compiling +--------- + +Open `ImageApp.pro` and modify the variables to match with your system. For example, you might need to modify the paths for the includes and libraries especially if you're on Windows. + + INCLUDEPATH += /usr/local/include + LIBS += -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs + +Change your working directory and compile the code by typing: + + qmake + make + +If everything is ok, it will produce an executable: `ImageApp` (Linux), `ImageApp.exe` (Windows), or `ImageApp.app` (Mac). Run the executable and you will see the GUI like the screenshot above. + +Known Issues +------------ + +In `ImageApp.cpp`, the code using relative path to locate the input image: + + img = cv::imread("../assets/The_Chapter_House.jpg"); + +If the program cannot display the image and shows the "Cannot load the input image!" warning, try to use absolute path instead. For example: + + img = cv::imread("/full/path/to/The_Chapter_House.jpg"); diff --git a/opencv-qt-integration-2/main.cpp b/opencv-qt-integration-2/main.cpp new file mode 100644 index 0000000..208f75c --- /dev/null +++ b/opencv-qt-integration-2/main.cpp @@ -0,0 +1,10 @@ +#include +#include "ImageApp.h" + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + ImageApp imageApp; + imageApp.show(); + app.exec(); +} diff --git a/opencv-qt-integration-2/moc_ImageApp.cpp b/opencv-qt-integration-2/moc_ImageApp.cpp new file mode 100644 index 0000000..7ad3b6b --- /dev/null +++ b/opencv-qt-integration-2/moc_ImageApp.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'ImageApp.h' +** +** Created by: The Qt Meta Object Compiler version 67 (Qt 5.3.0) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "ImageApp.h" +#include +#include +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'ImageApp.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 67 +#error "This file was generated using the moc from 5.3.0. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +struct qt_meta_stringdata_ImageApp_t { + QByteArrayData data[5]; + char stringdata[51]; +}; +#define QT_MOC_LITERAL(idx, ofs, len) \ + Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ + qptrdiff(offsetof(qt_meta_stringdata_ImageApp_t, stringdata) + ofs \ + - idx * sizeof(QByteArrayData)) \ + ) +static const qt_meta_stringdata_ImageApp_t qt_meta_stringdata_ImageApp = { + { +QT_MOC_LITERAL(0, 0, 8), +QT_MOC_LITERAL(1, 9, 17), +QT_MOC_LITERAL(2, 27, 0), +QT_MOC_LITERAL(3, 28, 7), +QT_MOC_LITERAL(4, 36, 14) + }, + "ImageApp\0showOriginalImage\0\0doCanny\0" + "doGaussianBlur" +}; +#undef QT_MOC_LITERAL + +static const uint qt_meta_data_ImageApp[] = { + + // content: + 7, // revision + 0, // classname + 0, 0, // classinfo + 3, 14, // methods + 0, 0, // properties + 0, 0, // enums/sets + 0, 0, // constructors + 0, // flags + 0, // signalCount + + // slots: name, argc, parameters, tag, flags + 1, 0, 29, 2, 0x08 /* Private */, + 3, 0, 30, 2, 0x08 /* Private */, + 4, 0, 31, 2, 0x08 /* Private */, + + // slots: parameters + QMetaType::Void, + QMetaType::Void, + QMetaType::Void, + + 0 // eod +}; + +void ImageApp::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) +{ + if (_c == QMetaObject::InvokeMetaMethod) { + ImageApp *_t = static_cast(_o); + switch (_id) { + case 0: _t->showOriginalImage(); break; + case 1: _t->doCanny(); break; + case 2: _t->doGaussianBlur(); break; + default: ; + } + } + Q_UNUSED(_a); +} + +const QMetaObject ImageApp::staticMetaObject = { + { &QWidget::staticMetaObject, qt_meta_stringdata_ImageApp.data, + qt_meta_data_ImageApp, qt_static_metacall, 0, 0} +}; + + +const QMetaObject *ImageApp::metaObject() const +{ + return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; +} + +void *ImageApp::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_ImageApp.stringdata)) + return static_cast(const_cast< ImageApp*>(this)); + return QWidget::qt_metacast(_clname); +} + +int ImageApp::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QWidget::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + if (_id < 3) + qt_static_metacall(this, _c, _id, _a); + _id -= 3; + } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) { + if (_id < 3) + *reinterpret_cast(_a[0]) = -1; + _id -= 3; + } + return _id; +} +QT_END_MOC_NAMESPACE -- cgit v1.2.3