├── .gitignore ├── README.md ├── imViewer.pro ├── screenshots ├── Snipaste_2019-05-30_15-32-42.png ├── Snipaste_2019-05-30_15-33-15.png └── Snipaste_2019-05-30_15-33-28.png └── src ├── dialog ├── dialog_exp_transform.cpp ├── dialog_exp_transform.h ├── dialog_exp_transform.ui ├── dialog_gaussianblur.cpp ├── dialog_gaussianblur.h ├── dialog_linear_gray.cpp ├── dialog_linear_gray.h ├── dialog_linear_gray.ui ├── dialog_log_grey.cpp ├── dialog_log_grey.h ├── dialog_log_grey.ui ├── dialog_power_grey.cpp ├── dialog_power_grey.h ├── dialog_power_grey.ui ├── dialog_stretch_transform.cpp ├── dialog_stretch_transform.h ├── dialog_stretch_transform.ui ├── dialog_two_threshold_transform.cpp ├── dialog_two_threshold_transform.h ├── dialog_two_threshold_transform.ui └── gaussianblurdialog.ui ├── main.cpp ├── mainwindow ├── graphicsview.cpp ├── graphicsview.h ├── mainwindow.cpp ├── mainwindow.h └── mainwindow.ui ├── res ├── Line_Chart_72px.png ├── Open_folder_full_48px_1186194_easyicon.net.png ├── about.svg ├── blur_on_72px.png ├── brightness.svg ├── chinese.png ├── clear.svg ├── cn.qm ├── cn.ts ├── default.qrc ├── english.png ├── frame_1.png ├── frame_2.png ├── frame_3.png ├── fun_exp.png ├── histogram.png ├── horizontal.png ├── left.png ├── lineGrey.gif ├── line_graphic_72p.png ├── log.png ├── logo_1.png ├── logo_2.png ├── metal.png ├── open.svg ├── quill_72px.png ├── restore.png ├── right.png ├── save.svg ├── temperature_72px.png ├── vertical.png └── zoom.png ├── src.pro └── utils ├── gaussianblur.cpp ├── gaussianblur.h ├── histogram.cpp ├── histogram.h ├── medianfilter.cpp ├── medianfilter.h ├── qcustomplot.cpp ├── qcustomplot.h ├── tools.cpp └── tools.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.pro.user* 2 | .git* 3 | .git.*/ 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageQt 2 | 3 | Image viewer powered by Qt 5.8.0 4 | 5 | [QPhoto](https://github.com/seahime/QPhoto)是该项目的重制版,当前完成度还很低。 6 | 7 | > 友情提示:该项目为作者本科时的课程作业,代码比较乱,参考需慎重。 8 | 9 | 10 | ## 功能(按完成时间排序) 11 | 12 | 1. 基本的图像查看 13 | 2. 图像缩放、旋转、翻转 14 | 3. 灰度图像 15 | 4. 调节色温 16 | 5. 调节亮度 17 | 6. 添加相框 18 | 7. 金属纹理 19 | 8. 语言切换(中/英)支持(已删除) 20 | 9. 直方图(包括灰度直方图和各通道直方图) 21 | 10. 线性灰度变换 22 | 11. 函数图像绘制 23 | 12. 指数灰度变换 24 | 13. 幂次灰度变换 25 | 14. 对数灰度变换 26 | 15. 拉伸灰度变换 27 | 16. 简单平滑 28 | 17. 高斯平滑 29 | 18. 中值滤波 30 | 19. Laplace锐化 31 | 20. Sobel边缘检测 32 | 33 | ## 截图 34 | 35 | ![1](./screenshots/Snipaste_2019-05-30_15-32-42.png) 36 | 37 | ![2](./screenshots/Snipaste_2019-05-30_15-33-15.png) 38 | 39 | ![3](./screenshots/Snipaste_2019-05-30_15-33-28.png) 40 | 41 | -------------------------------------------------------------------------------- /imViewer.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-03-20T14:23:41 4 | # 5 | #------------------------------------------------- 6 | 7 | TEMPLATE = subdirs 8 | 9 | SUBDIRS += src 10 | 11 | 12 | #QT += core gui concurrent 13 | 14 | #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport 15 | 16 | #TARGET = imViewer 17 | #TEMPLATE = app 18 | #CONFIG += C++11 19 | 20 | # The following define makes your compiler emit warnings if you use 21 | # any feature of Qt which as been marked as deprecated (the exact warnings 22 | # depend on your compiler). Please consult the documentation of the 23 | # deprecated API in order to know how to port your code away from it. 24 | #DEFINES += QT_DEPRECATED_WARNINGS 25 | 26 | # You can also make your code fail to compile if you use deprecated APIs. 27 | # In order to do so, uncomment the following line. 28 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 29 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 30 | 31 | 32 | #SOURCES += main.cpp\ 33 | # mainwindow.cpp \ 34 | # tools.cpp \ 35 | # dialog_gaussianblur.cpp \ 36 | # histogram.cpp \ 37 | # dialog_linear_gray.cpp \ 38 | # qcustomplot.cpp \ 39 | # dialog_log_grey.cpp \ 40 | # dialog_power_grey.cpp \ 41 | # dialog_exp_transform.cpp \ 42 | # dialog_two_threshold_transform.cpp \ 43 | # dialog_stretch_transform.cpp \ 44 | # gaussianblur.cpp \ 45 | # medianfilter.cpp \ 46 | # graphicsview.cpp 47 | 48 | #HEADERS += mainwindow.h \ 49 | # tools.h \ 50 | # dialog_gaussianblur.h \ 51 | # histogram.h \ 52 | # dialog_linear_gray.h \ 53 | # qcustomplot.h \ 54 | # dialog_log_grey.h \ 55 | # dialog_power_grey.h \ 56 | # dialog_exp_transform.h \ 57 | # dialog_two_threshold_transform.h \ 58 | # dialog_stretch_transform.h \ 59 | # gaussianblur.h \ 60 | # medianfilter.h \ 61 | # graphicsview.h 62 | 63 | #FORMS += mainwindow.ui \ 64 | # gaussianblurdialog.ui \ 65 | # dialog_linear_gray.ui \ 66 | # dialog_log_grey.ui \ 67 | # dialog_power_grey.ui \ 68 | # dialog_exp_transform.ui \ 69 | # dialog_two_threshold_transform.ui \ 70 | # dialog_stretch_transform.ui 71 | 72 | #RESOURCES += \ 73 | # default.qrc 74 | 75 | #TRANSLATIONS += cn.ts 76 | 77 | #DISTFILES += 78 | -------------------------------------------------------------------------------- /screenshots/Snipaste_2019-05-30_15-32-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/screenshots/Snipaste_2019-05-30_15-32-42.png -------------------------------------------------------------------------------- /screenshots/Snipaste_2019-05-30_15-33-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/screenshots/Snipaste_2019-05-30_15-33-15.png -------------------------------------------------------------------------------- /screenshots/Snipaste_2019-05-30_15-33-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/screenshots/Snipaste_2019-05-30_15-33-28.png -------------------------------------------------------------------------------- /src/dialog/dialog_exp_transform.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_exp_transform.h" 2 | #include "ui_dialog_exp_transform.h" 3 | 4 | DialogExpTransform::DialogExpTransform(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogExpTransform) 7 | { 8 | ui->setupUi(this); 9 | 10 | paintFunctionImage(ui->bDoubleSpinBox->value(), ui->cDoubleSpinBox->value(), ui->aDoubleSpinBox->value()); 11 | } 12 | 13 | DialogExpTransform::~DialogExpTransform() 14 | { 15 | delete ui; 16 | } 17 | 18 | void DialogExpTransform::on_buttonBox_accepted() 19 | { 20 | emit sendData(ui->bDoubleSpinBox->value(), ui->cDoubleSpinBox->value(), ui->aDoubleSpinBox->value()); 21 | 22 | } 23 | 24 | void DialogExpTransform::paintFunctionImage(double b, double c, double a) 25 | { 26 | // generate some data: 27 | QVector x(1001), y(1001); // initialize with entries 0..100 28 | for (int i=0; i<1001; ++i) 29 | { 30 | x[i] = i/50.0 - 10; 31 | y[i] = qPow(b, c*(x[i]-a)); 32 | } 33 | // create graph and assign data to it: 34 | ui->customPlot->addGraph(); 35 | ui->customPlot->graph(0)->setData(x, y); 36 | // give the axes some labels: 37 | ui->customPlot->xAxis->setLabel("x"); 38 | ui->customPlot->yAxis->setLabel("y"); 39 | // set axes ranges, so we see all data: 40 | ui->customPlot->xAxis->setRange(-10, 10); 41 | ui->customPlot->yAxis->setRange(-10, 10); 42 | ui->customPlot->replot(); 43 | } 44 | 45 | void DialogExpTransform::on_bDoubleSpinBox_valueChanged(double arg1) 46 | { 47 | paintFunctionImage(arg1, ui->cDoubleSpinBox->value(), ui->aDoubleSpinBox->value()); 48 | } 49 | 50 | void DialogExpTransform::on_cDoubleSpinBox_valueChanged(double arg1) 51 | { 52 | paintFunctionImage(ui->bDoubleSpinBox->value(), arg1, ui->aDoubleSpinBox->value()); 53 | } 54 | 55 | void DialogExpTransform::on_aDoubleSpinBox_valueChanged(double arg1) 56 | { 57 | paintFunctionImage(ui->bDoubleSpinBox->value(), ui->cDoubleSpinBox->value(), arg1); 58 | } 59 | -------------------------------------------------------------------------------- /src/dialog/dialog_exp_transform.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_EXP_TRANSFORM_H 2 | #define DIALOG_EXP_TRANSFORM_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class DialogExpTransform; 8 | } 9 | 10 | class DialogExpTransform : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogExpTransform(QWidget *parent = nullptr); 16 | ~DialogExpTransform(); 17 | 18 | private: 19 | Ui::DialogExpTransform *ui; 20 | 21 | void paintFunctionImage(double b, double c, double a); 22 | 23 | signals: 24 | void sendData(double, double, double); 25 | 26 | private slots: 27 | void on_buttonBox_accepted(); 28 | void on_bDoubleSpinBox_valueChanged(double arg1); 29 | void on_cDoubleSpinBox_valueChanged(double arg1); 30 | void on_aDoubleSpinBox_valueChanged(double arg1); 31 | }; 32 | 33 | #endif // DIALOG_EXP_TRANSFORM_H 34 | -------------------------------------------------------------------------------- /src/dialog/dialog_exp_transform.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogExpTransform 4 | 5 | 6 | 7 | 0 8 | 0 9 | 565 10 | 356 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | <html><head/><body><p><span style=" font-size:12pt;">变换函数:</span></p></body></html> 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | :/img/src/fun_exp.png 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | <html><head/><body><p><span style=" font-size:14pt;">b = </span></p></body></html> 50 | 51 | 52 | 53 | 54 | 55 | 56 | 10.000000000000000 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | <html><head/><body><p><span style=" font-size:14pt;">c = </span></p></body></html> 68 | 69 | 70 | 71 | 72 | 73 | 74 | -2.000000000000000 75 | 76 | 77 | 2.000000000000000 78 | 79 | 80 | 0.100000000000000 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | <html><head/><body><p><span style=" font-size:14pt;">a = </span></p></body></html> 92 | 93 | 94 | 95 | 96 | 97 | 98 | -50.000000000000000 99 | 100 | 101 | 50.000000000000000 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | Qt::Vertical 111 | 112 | 113 | 114 | 20 115 | 40 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | Qt::Horizontal 133 | 134 | 135 | 136 | 40 137 | 20 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | Qt::Horizontal 146 | 147 | 148 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | QCustomPlot 161 | QWidget 162 |
qcustomplot.h
163 | 1 164 |
165 |
166 | 167 | 168 | 169 | buttonBox 170 | accepted() 171 | DialogExpTransform 172 | accept() 173 | 174 | 175 | 248 176 | 254 177 | 178 | 179 | 157 180 | 274 181 | 182 | 183 | 184 | 185 | buttonBox 186 | rejected() 187 | DialogExpTransform 188 | reject() 189 | 190 | 191 | 316 192 | 260 193 | 194 | 195 | 286 196 | 274 197 | 198 | 199 | 200 | 201 |
202 | -------------------------------------------------------------------------------- /src/dialog/dialog_gaussianblur.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_gaussianblur.h" 2 | #include "ui_gaussianblurdialog.h" 3 | 4 | GaussianBlurDialog::GaussianBlurDialog(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::GaussianBlurDialog) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | GaussianBlurDialog::~GaussianBlurDialog() 12 | { 13 | delete ui; 14 | } 15 | 16 | void GaussianBlurDialog::on_buttonBox_accepted() 17 | { 18 | emit sendData(ui->radiusSpinBox->value(), ui->sigmaSpinBox->value()); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/dialog/dialog_gaussianblur.h: -------------------------------------------------------------------------------- 1 | #ifndef GAUSSIANBLURDIALOG_H 2 | #define GAUSSIANBLURDIALOG_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class GaussianBlurDialog; 8 | } 9 | 10 | class GaussianBlurDialog : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit GaussianBlurDialog(QWidget *parent = 0); 16 | ~GaussianBlurDialog(); 17 | 18 | private: 19 | Ui::GaussianBlurDialog *ui; 20 | 21 | signals: 22 | void sendData(int, double); 23 | 24 | private slots: 25 | void on_buttonBox_accepted(); 26 | }; 27 | 28 | #endif // GAUSSIANBLURDIALOG_H 29 | -------------------------------------------------------------------------------- /src/dialog/dialog_linear_gray.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_linear_gray.h" 2 | #include "ui_dialog_linear_gray.h" 3 | 4 | LinearGrayDialog::LinearGrayDialog(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::LinearGrayDialog) 7 | { 8 | ui->setupUi(this); 9 | 10 | // QPixmap pixmap; 11 | // pixmap.load(":/img/src/lineGrey.gif"); 12 | // ui->label->setPixmap(pixmap); 13 | 14 | paintFunctionImage(ui->aDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 15 | 16 | } 17 | 18 | /****************************************************************************** 19 | * 绘制线性变换函数的图像 20 | * y = __a*x + __b 21 | * ***************************************************************************/ 22 | void LinearGrayDialog::paintFunctionImage(double __a, double __b) 23 | { 24 | // generate some data: 25 | QVector x(1001), y(1001); // initialize with entries 0..100 26 | for (int i=0; i<1001; ++i) 27 | { 28 | x[i] = i/50.0 - 10; // x goes from -10 to 10 29 | y[i] = x[i]*__a + __b; // let's plot a quadratic function 30 | } 31 | // create graph and assign data to it: 32 | ui->customPlot->addGraph(); 33 | ui->customPlot->graph(0)->setData(x, y); 34 | // give the axes some labels: 35 | ui->customPlot->xAxis->setLabel("x"); 36 | ui->customPlot->yAxis->setLabel("y"); 37 | // set axes ranges, so we see all data: 38 | ui->customPlot->xAxis->setRange(-10, 10); 39 | ui->customPlot->yAxis->setRange(-10, 10); 40 | ui->customPlot->replot(); 41 | } 42 | 43 | LinearGrayDialog::~LinearGrayDialog() 44 | { 45 | delete ui; 46 | } 47 | 48 | 49 | void LinearGrayDialog::on_buttonBox_accepted() 50 | { 51 | emit sendData(ui->aDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 52 | } 53 | 54 | void LinearGrayDialog::on_aDoubleSpinBox_valueChanged(double arg1) 55 | { 56 | paintFunctionImage(arg1, ui->bDoubleSpinBox->value()); 57 | } 58 | 59 | void LinearGrayDialog::on_bDoubleSpinBox_valueChanged(double arg1) 60 | { 61 | paintFunctionImage(ui->aDoubleSpinBox->value(), arg1); 62 | } 63 | -------------------------------------------------------------------------------- /src/dialog/dialog_linear_gray.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_LINEAR_GRAY_H 2 | #define DIALOG_LINEAR_GRAY_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Ui { 9 | class LinearGrayDialog; 10 | } 11 | 12 | class LinearGrayDialog : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit LinearGrayDialog(QWidget *parent = nullptr); 18 | ~LinearGrayDialog(); 19 | 20 | private: 21 | Ui::LinearGrayDialog *ui; 22 | 23 | void paintFunctionImage(double _a, double _b); 24 | 25 | signals: 26 | void sendData(double a, double b); 27 | private slots: 28 | void on_buttonBox_accepted(); 29 | void on_aDoubleSpinBox_valueChanged(double arg1); 30 | void on_bDoubleSpinBox_valueChanged(double arg1); 31 | }; 32 | 33 | #endif // DIALOG_LINEAR_GRAY_H 34 | -------------------------------------------------------------------------------- /src/dialog/dialog_linear_gray.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | LinearGrayDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 574 10 | 322 11 | 12 | 13 | 14 | Linear Gray Level Transformation 15 | 16 | 17 | 18 | 19 | 380 20 | 280 21 | 181 22 | 32 23 | 24 | 25 | 26 | 27 | 28 | 29 | Qt::Horizontal 30 | 31 | 32 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 33 | 34 | 35 | 36 | 37 | 38 | 260 39 | 10 40 | 301 41 | 261 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 10 52 | 10 53 | 241 54 | 261 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | <html><head/><body><p><span style=" font-size:11pt;">Transformation function:</span></p></body></html> 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | font: 75 14pt "Roboto"; 73 | 74 | 75 | y = 76 | 77 | 78 | 79 | 80 | 81 | 82 | -10.000000000000000 83 | 84 | 85 | 10.000000000000000 86 | 87 | 88 | 0.010000000000000 89 | 90 | 91 | 1.200000000000000 92 | 93 | 94 | 95 | 96 | 97 | 98 | font: 75 14pt "Roboto"; 99 | 100 | 101 | x + 102 | 103 | 104 | 105 | 106 | 107 | 108 | -100.000000000000000 109 | 110 | 111 | 100.000000000000000 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Qt::Vertical 123 | 124 | 125 | 126 | 20 127 | 40 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 139 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 140 | p, li { white-space: pre-wrap; } 141 | </style></head><body style=" font-family:'Roboto'; font-size:10pt; font-weight:400; font-style:normal;"> 142 | <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt; color:#c80932;">NOTE!</span><span style=" font-size:11pt;"> </span></p> 143 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The function you choose here will be used for grayscale linear transformation.</span></p></body></html> 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | QCustomPlot 153 | QWidget 154 |
qcustomplot.h
155 | 1 156 |
157 |
158 | 159 | 160 | 161 | buttonBox 162 | accepted() 163 | LinearGrayDialog 164 | accept() 165 | 166 | 167 | 248 168 | 254 169 | 170 | 171 | 157 172 | 274 173 | 174 | 175 | 176 | 177 | buttonBox 178 | rejected() 179 | LinearGrayDialog 180 | reject() 181 | 182 | 183 | 316 184 | 260 185 | 186 | 187 | 286 188 | 274 189 | 190 | 191 | 192 | 193 |
194 | -------------------------------------------------------------------------------- /src/dialog/dialog_log_grey.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_log_grey.h" 2 | #include "ui_dialog_log_grey.h" 3 | 4 | DialogLogGrey::DialogLogGrey(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogLogGrey) 7 | { 8 | ui->setupUi(this); 9 | 10 | QPixmap pixmap; 11 | pixmap.load(":/img/src/log.png"); 12 | 13 | ui->funLabel->setPixmap(pixmap); 14 | setWindowTitle(tr("Grey Level Logarithm Transformation")); 15 | 16 | paintFunctionImage(ui->aDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 17 | } 18 | 19 | DialogLogGrey::~DialogLogGrey() 20 | { 21 | delete ui; 22 | } 23 | 24 | void DialogLogGrey::on_buttonBox_accepted() 25 | { 26 | emit sendData(ui->aDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 27 | } 28 | 29 | /****************************************************************************** 30 | * 绘制变换函数的图像 31 | * y = __a*x + __b 32 | * ***************************************************************************/ 33 | void DialogLogGrey::paintFunctionImage(double __a, double __b) 34 | { 35 | // generate some data: 36 | QVector x(1001), y(1001); // initialize with entries 0..100 37 | for (int i=0; i<1001; ++i) 38 | { 39 | x[i] = i/50.0; // x goes from 0 to 20 40 | y[i] = qLn(__b + x[i])/qLn(__a); 41 | } 42 | // create graph and assign data to it: 43 | ui->customPlot->addGraph(); 44 | ui->customPlot->graph(0)->setData(x, y); 45 | // give the axes some labels: 46 | ui->customPlot->xAxis->setLabel("x"); 47 | ui->customPlot->yAxis->setLabel("y"); 48 | // set axes ranges, so we see all data: 49 | ui->customPlot->xAxis->setRange(0, 20); 50 | ui->customPlot->yAxis->setRange(-10, 10); 51 | ui->customPlot->replot(); 52 | } 53 | 54 | void DialogLogGrey::on_aDoubleSpinBox_valueChanged(double arg1) 55 | { 56 | paintFunctionImage(arg1, ui->bDoubleSpinBox->value()); 57 | } 58 | 59 | void DialogLogGrey::on_bDoubleSpinBox_valueChanged(double arg1) 60 | { 61 | paintFunctionImage(ui->aDoubleSpinBox->value(), arg1); 62 | } 63 | -------------------------------------------------------------------------------- /src/dialog/dialog_log_grey.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_LOG_GREY_H 2 | #define DIALOG_LOG_GREY_H 3 | 4 | #include 5 | #include 6 | 7 | namespace Ui { 8 | class DialogLogGrey; 9 | } 10 | 11 | class DialogLogGrey : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DialogLogGrey(QWidget *parent = 0); 17 | ~DialogLogGrey(); 18 | 19 | private: 20 | Ui::DialogLogGrey *ui; 21 | 22 | void paintFunctionImage(double __a, double __b); 23 | 24 | signals: 25 | void sendData(double a, double b); 26 | private slots: 27 | void on_buttonBox_accepted(); 28 | void on_aDoubleSpinBox_valueChanged(double arg1); 29 | void on_bDoubleSpinBox_valueChanged(double arg1); 30 | }; 31 | 32 | #endif // DIALOG_LOG_GREY_H 33 | -------------------------------------------------------------------------------- /src/dialog/dialog_log_grey.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogLogGrey 4 | 5 | 6 | 7 | 0 8 | 0 9 | 594 10 | 352 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Dialog 21 | 22 | 23 | 24 | 25 | 6 26 | 6 27 | 581 28 | 341 29 | 30 | 31 | 32 | 33 | QLayout::SetMaximumSize 34 | 35 | 36 | 1 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Qt::Vertical 46 | 47 | 48 | 49 | 20 50 | 40 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">a = </span></p></body></html> 73 | 74 | 75 | 76 | 77 | 78 | 79 | 0.100000000000000 80 | 81 | 82 | 2.720000000000000 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | <html><head/><body><p><span style=" font-size:11pt; font-weight:600;">b = </span></p></body></html> 100 | 101 | 102 | 103 | 104 | 105 | 106 | 0.000000000000000 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | Qt::Vertical 121 | 122 | 123 | 124 | 20 125 | 40 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | Qt::Horizontal 143 | 144 | 145 | 146 | 40 147 | 20 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | Qt::Horizontal 156 | 157 | 158 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | QCustomPlot 170 | QWidget 171 |
qcustomplot.h
172 | 1 173 |
174 |
175 | 176 | 177 | 178 | buttonBox 179 | accepted() 180 | DialogLogGrey 181 | accept() 182 | 183 | 184 | 248 185 | 254 186 | 187 | 188 | 157 189 | 274 190 | 191 | 192 | 193 | 194 | buttonBox 195 | rejected() 196 | DialogLogGrey 197 | reject() 198 | 199 | 200 | 316 201 | 260 202 | 203 | 204 | 286 205 | 274 206 | 207 | 208 | 209 | 210 |
211 | -------------------------------------------------------------------------------- /src/dialog/dialog_power_grey.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_power_grey.h" 2 | #include "ui_dialog_power_grey.h" 3 | 4 | DialogPowerGrey::DialogPowerGrey(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogPowerGrey) 7 | { 8 | ui->setupUi(this); 9 | 10 | paintFunctionImage(ui->cDoubleSpinBox->value(), ui->rDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 11 | } 12 | 13 | DialogPowerGrey::~DialogPowerGrey() 14 | { 15 | delete ui; 16 | } 17 | 18 | void DialogPowerGrey::on_buttonBox_accepted() 19 | { 20 | emit sendData(ui->cDoubleSpinBox->value(), ui->rDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 21 | } 22 | 23 | void DialogPowerGrey::paintFunctionImage(double c, double r, double b) 24 | { 25 | // generate some data: 26 | QVector x(1001), y(1001); // initialize with entries 0..100 27 | for (int i=0; i<1001; ++i) 28 | { 29 | x[i] = i/50.0 - 10; // x goes from 0 to 20 30 | y[i] = c*qPow(x[i], r) + b; 31 | } 32 | // create graph and assign data to it: 33 | ui->customPlot->addGraph(); 34 | ui->customPlot->graph(0)->setData(x, y); 35 | // give the axes some labels: 36 | ui->customPlot->xAxis->setLabel("x"); 37 | ui->customPlot->yAxis->setLabel("y"); 38 | // set axes ranges, so we see all data: 39 | ui->customPlot->xAxis->setRange(-10, 10); 40 | ui->customPlot->yAxis->setRange(-10, 10); 41 | ui->customPlot->replot(); 42 | } 43 | 44 | void DialogPowerGrey::on_cDoubleSpinBox_valueChanged(double c) 45 | { 46 | paintFunctionImage(c, ui->rDoubleSpinBox->value(), ui->bDoubleSpinBox->value()); 47 | } 48 | 49 | 50 | 51 | 52 | void DialogPowerGrey::on_rDoubleSpinBox_valueChanged(double r) 53 | { 54 | paintFunctionImage(ui->cDoubleSpinBox->value(), r, ui->bDoubleSpinBox->value()); 55 | } 56 | 57 | void DialogPowerGrey::on_bDoubleSpinBox_valueChanged(double b) 58 | { 59 | paintFunctionImage(ui->cDoubleSpinBox->value(), ui->rDoubleSpinBox->value(), b); 60 | } 61 | -------------------------------------------------------------------------------- /src/dialog/dialog_power_grey.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_POWER_GREY_H 2 | #define DIALOG_POWER_GREY_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class DialogPowerGrey; 8 | } 9 | 10 | class DialogPowerGrey : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogPowerGrey(QWidget *parent = 0); 16 | ~DialogPowerGrey(); 17 | 18 | private: 19 | Ui::DialogPowerGrey *ui; 20 | 21 | void paintFunctionImage(double c, double r, double b); 22 | 23 | 24 | signals: 25 | void sendData(double, double, double); 26 | private slots: 27 | void on_buttonBox_accepted(); 28 | void on_cDoubleSpinBox_valueChanged(double arg1); 29 | void on_rDoubleSpinBox_valueChanged(double arg1); 30 | void on_bDoubleSpinBox_valueChanged(double arg1); 31 | }; 32 | 33 | #endif // DIALOG_POWER_GREY_H 34 | -------------------------------------------------------------------------------- /src/dialog/dialog_power_grey.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogPowerGrey 4 | 5 | 6 | 7 | 0 8 | 0 9 | 646 10 | 382 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | <html><head/><body><p><span style=" font-size:16pt;">变换函数:y = cx</span><span style=" font-size:16pt; vertical-align:super;">r </span><span style=" font-size:16pt;">+ b</span></p></body></html> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">c = </span></p></body></html> 38 | 39 | 40 | 41 | 42 | 43 | 44 | 0.010000000000000 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">r = </span></p></body></html> 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">b = </span></p></body></html> 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Qt::Vertical 82 | 83 | 84 | 85 | 20 86 | 40 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Qt::Horizontal 106 | 107 | 108 | 109 | 40 110 | 20 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Qt::Horizontal 119 | 120 | 121 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | QCustomPlot 134 | QWidget 135 |
qcustomplot.h
136 | 1 137 |
138 |
139 | 140 | 141 | 142 | buttonBox 143 | accepted() 144 | DialogPowerGrey 145 | accept() 146 | 147 | 148 | 248 149 | 254 150 | 151 | 152 | 157 153 | 274 154 | 155 | 156 | 157 | 158 | buttonBox 159 | rejected() 160 | DialogPowerGrey 161 | reject() 162 | 163 | 164 | 316 165 | 260 166 | 167 | 168 | 286 169 | 274 170 | 171 | 172 | 173 | 174 |
175 | -------------------------------------------------------------------------------- /src/dialog/dialog_stretch_transform.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_stretch_transform.h" 2 | #include "ui_dialog_stretch_transform.h" 3 | 4 | DialogStretchTransform::DialogStretchTransform(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogStretchTransform) 7 | { 8 | ui->setupUi(this); 9 | 10 | calK(); 11 | paintFunctionImage(); 12 | } 13 | 14 | DialogStretchTransform::~DialogStretchTransform() 15 | { 16 | delete ui; 17 | } 18 | 19 | void DialogStretchTransform::calK() 20 | { 21 | x1 = ui->x1->value(); 22 | x2 = ui->x2->value(); 23 | y1 = ui->y1->value(); 24 | y2 = ui->y2->value(); 25 | 26 | k1 = y1/1.0/x1; 27 | k2 = (ui->y2->value()-ui->y1->value())/1.0/(ui->x2->value()-ui->x1->value()); 28 | k3 = (255-ui->y2->value())/1.0/(255-ui->x2->value()); 29 | 30 | b2 = y2-k2*x2; 31 | b3 = 255-k3*255; 32 | 33 | ui->k1->setText(QString::number(k1, 10, 2)); 34 | ui->k2->setText(QString::number(k2, 10, 2)); 35 | ui->k3->setText(QString::number(k3, 10, 2)); 36 | 37 | 38 | } 39 | 40 | void DialogStretchTransform::paintFunctionImage() 41 | { 42 | int x1 = ui->x1->value(); 43 | int x2 = ui->x2->value(); 44 | int y1 = ui->y1->value(); 45 | int y2 = ui->y2->value(); 46 | 47 | double b2 = y2-k2*x2; 48 | double b3 = 255-k3*255; 49 | 50 | QVector x(2560), y(2560); // initialize with entries 0..100 51 | for (int i=0; icustomPlot->addGraph(); 70 | ui->customPlot->graph(0)->setData(x, y); 71 | // give the axes some labels: 72 | ui->customPlot->xAxis->setLabel("x"); 73 | ui->customPlot->yAxis->setLabel("y"); 74 | // set axes ranges, so we see all data: 75 | ui->customPlot->xAxis->setRange(0, 255); 76 | ui->customPlot->yAxis->setRange(0, 255); 77 | ui->customPlot->replot(); 78 | } 79 | 80 | void DialogStretchTransform::on_x1_valueChanged(int arg1) 81 | { 82 | calK(); 83 | paintFunctionImage(); 84 | } 85 | 86 | void DialogStretchTransform::on_y1_valueChanged(int arg1) 87 | { 88 | calK(); 89 | paintFunctionImage(); 90 | } 91 | 92 | void DialogStretchTransform::on_x2_valueChanged(int arg1) 93 | { 94 | calK(); 95 | paintFunctionImage(); 96 | } 97 | 98 | void DialogStretchTransform::on_y2_valueChanged(int arg1) 99 | { 100 | calK(); 101 | paintFunctionImage(); 102 | } 103 | 104 | void DialogStretchTransform::on_buttonBox_accepted() 105 | { 106 | emit sendData(x1, x2, k1,k2,k3,b2,b3); 107 | } 108 | -------------------------------------------------------------------------------- /src/dialog/dialog_stretch_transform.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_STRETCH_TRANSFORM_H 2 | #define DIALOG_STRETCH_TRANSFORM_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class DialogStretchTransform; 8 | } 9 | 10 | class DialogStretchTransform : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogStretchTransform(QWidget *parent = 0); 16 | ~DialogStretchTransform(); 17 | 18 | void calK(); 19 | 20 | private slots: 21 | void on_x1_valueChanged(int arg1); 22 | 23 | void on_y1_valueChanged(int arg1); 24 | 25 | void on_x2_valueChanged(int arg1); 26 | 27 | void on_y2_valueChanged(int arg1); 28 | 29 | void on_buttonBox_accepted(); 30 | 31 | private: 32 | Ui::DialogStretchTransform *ui; 33 | void paintFunctionImage(); 34 | 35 | double k1, k2, k3; 36 | int x1, x2, y1, y2; 37 | double b2, b3; 38 | 39 | signals: 40 | // x1, y1, x2, y2, k1, k2, k3, b2, b3 41 | void sendData(int, int, double, double, double, double, double); 42 | }; 43 | 44 | #endif // DIALOG_STRETCH_TRANSFORM_H 45 | -------------------------------------------------------------------------------- /src/dialog/dialog_stretch_transform.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogStretchTransform 4 | 5 | 6 | 7 | 0 8 | 0 9 | 575 10 | 374 11 | 12 | 13 | 14 | Grey Level Transform - Stretch 15 | 16 | 17 | 18 | 19 | 230 20 | 10 21 | 331 22 | 291 23 | 24 | 25 | 26 | 27 | 28 | 29 | 340 30 | 320 31 | 222 32 | 36 33 | 34 | 35 | 36 | 37 | 38 | 39 | Qt::Horizontal 40 | 41 | 42 | 43 | 40 44 | 20 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Qt::Horizontal 53 | 54 | 55 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 10 65 | 10 66 | 201 67 | 291 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">(</span></p></body></html> 81 | 82 | 83 | 84 | 85 | 86 | 87 | 255 88 | 89 | 90 | 50 91 | 92 | 93 | 94 | 95 | 96 | 97 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">,</span></p></body></html> 98 | 99 | 100 | 101 | 102 | 103 | 104 | 255 105 | 106 | 107 | 60 108 | 109 | 110 | 111 | 112 | 113 | 114 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">)</span></p></body></html> 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">(</span></p></body></html> 126 | 127 | 128 | 129 | 130 | 131 | 132 | 255 133 | 134 | 135 | 160 136 | 137 | 138 | 139 | 140 | 141 | 142 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">,</span></p></body></html> 143 | 144 | 145 | 146 | 147 | 148 | 149 | 255 150 | 151 | 152 | 150 153 | 154 | 155 | 156 | 157 | 158 | 159 | <html><head/><body><p><span style=" font-size:14pt; font-weight:600;">)</span></p></body></html> 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | font: 87 14pt "Roboto"; 175 | 176 | 177 | k1 = 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | font: 87 14pt "Roboto"; 196 | 197 | 198 | k2 = 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | font: 87 14pt "Roboto"; 217 | 218 | 219 | k3 = 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 240 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 241 | p, li { white-space: pre-wrap; } 242 | </style></head><body style=" font-family:'Roboto'; font-size:10pt; font-weight:400; font-style:normal;"> 243 | <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#ff0000;">NOTE!</span></p> 244 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Input two points, and then the slope will be calculate automatically.</p></body></html> 245 | 246 | 247 | 248 | 249 | 250 | 251 | Qt::Vertical 252 | 253 | 254 | 255 | 20 256 | 40 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | QCustomPlot 267 | QWidget 268 |
qcustomplot.h
269 | 1 270 |
271 |
272 | 273 | 274 | 275 | buttonBox 276 | accepted() 277 | DialogStretchTransform 278 | accept() 279 | 280 | 281 | 248 282 | 254 283 | 284 | 285 | 157 286 | 274 287 | 288 | 289 | 290 | 291 | buttonBox 292 | rejected() 293 | DialogStretchTransform 294 | reject() 295 | 296 | 297 | 316 298 | 260 299 | 300 | 301 | 286 302 | 274 303 | 304 | 305 | 306 | 307 |
308 | -------------------------------------------------------------------------------- /src/dialog/dialog_two_threshold_transform.cpp: -------------------------------------------------------------------------------- 1 | #include "dialog_two_threshold_transform.h" 2 | #include "ui_dialog_two_threshold_transform.h" 3 | 4 | DialogThresholdTransform::DialogThresholdTransform(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::DialogThresholdTransform) 7 | { 8 | ui->setupUi(this); 9 | paintFunctionImage(ui->T1SpinBox->value(), ui->T2SpinBox->value(), ui->comboBox->currentIndex()); 10 | } 11 | 12 | DialogThresholdTransform::~DialogThresholdTransform() 13 | { 14 | delete ui; 15 | } 16 | 17 | void DialogThresholdTransform::on_buttonBox_accepted() 18 | { 19 | emit sendData(ui->T1SpinBox->value(), ui->T2SpinBox->value(), ui->comboBox->currentIndex()); 20 | } 21 | 22 | void DialogThresholdTransform::paintFunctionImage(int t1, int t2, int option) 23 | // int option: 24 | // 0: 0-255-0 25 | // 1: 255-0-255 26 | { 27 | QVector x(2560), y(2560); // initialize with entries 0..100 28 | if (option == 0) 29 | { 30 | for (int i=0; icustomPlot->addGraph(); 66 | ui->customPlot->graph(0)->setData(x, y); 67 | // give the axes some labels: 68 | ui->customPlot->xAxis->setLabel("x"); 69 | ui->customPlot->yAxis->setLabel("y"); 70 | // set axes ranges, so we see all data: 71 | ui->customPlot->xAxis->setRange(0, 255); 72 | ui->customPlot->yAxis->setRange(0, 600); 73 | ui->customPlot->replot(); 74 | } 75 | 76 | void DialogThresholdTransform::on_T1SpinBox_valueChanged(int t1) 77 | { 78 | // qDebug()<comboBox->currentIndex(); 79 | paintFunctionImage(t1, ui->T2SpinBox->value(), ui->comboBox->currentIndex()); 80 | } 81 | 82 | void DialogThresholdTransform::on_T2SpinBox_valueChanged(int t2) 83 | { 84 | paintFunctionImage(ui->T1SpinBox->value(), t2, ui->comboBox->currentIndex()); 85 | } 86 | 87 | void DialogThresholdTransform::on_comboBox_currentIndexChanged(int index) 88 | { 89 | paintFunctionImage(ui->T1SpinBox->value(), ui->T2SpinBox->value(), index); 90 | } 91 | -------------------------------------------------------------------------------- /src/dialog/dialog_two_threshold_transform.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOG_THRESHOLD_TRANSFORM_H 2 | #define DIALOG_THRESHOLD_TRANSFORM_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class DialogThresholdTransform; 8 | } 9 | 10 | class DialogThresholdTransform : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogThresholdTransform(QWidget *parent = 0); 16 | ~DialogThresholdTransform(); 17 | 18 | private: 19 | Ui::DialogThresholdTransform *ui; 20 | 21 | void paintFunctionImage(int t1, int t2, int option); 22 | 23 | signals: 24 | void sendData(int t1, int t2, int opt); 25 | 26 | private slots: 27 | void on_buttonBox_accepted(); 28 | void on_T1SpinBox_valueChanged(int arg1); 29 | void on_T2SpinBox_valueChanged(int arg1); 30 | void on_comboBox_currentIndexChanged(int index); 31 | }; 32 | 33 | #endif // DIALOG_THRESHOLD_TRANSFORM_H 34 | -------------------------------------------------------------------------------- /src/dialog/dialog_two_threshold_transform.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogThresholdTransform 4 | 5 | 6 | 7 | 0 8 | 0 9 | 601 10 | 401 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 567 22 | 383 23 | 24 | 25 | 26 | 27 | 1000 28 | 700 29 | 30 | 31 | 32 | Grey Transform - Two Threshold Transform 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Type: 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 0-255-0 55 | 56 | 57 | 58 | 59 | 255-0-255 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | <html><head/><body><p><span style=" font-size:14pt;">T1 = </span></p></body></html> 72 | 73 | 74 | 75 | 76 | 77 | 78 | 255 79 | 80 | 81 | 1 82 | 83 | 84 | 80 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | <html><head/><body><p><span style=" font-size:14pt;">T2 = </span></p></body></html> 96 | 97 | 98 | 99 | 100 | 101 | 102 | 255 103 | 104 | 105 | 160 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 117 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 118 | p, li { white-space: pre-wrap; } 119 | </style></head><body style=" font-family:'Roboto'; font-size:10pt; font-weight:400; font-style:normal;"> 120 | <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; color:#ff0000;">NOTE:</span></p> 121 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Input two integer values between 0~255 for the two thresholds transform.</span></p></body></html> 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 0 132 | 0 133 | 134 | 135 | 136 | 137 | 0 138 | 0 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | Qt::Horizontal 149 | 150 | 151 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | QCustomPlot 160 | QWidget 161 |
qcustomplot.h
162 | 1 163 |
164 |
165 | 166 | 167 | 168 | buttonBox 169 | accepted() 170 | DialogThresholdTransform 171 | accept() 172 | 173 | 174 | 248 175 | 254 176 | 177 | 178 | 157 179 | 274 180 | 181 | 182 | 183 | 184 | buttonBox 185 | rejected() 186 | DialogThresholdTransform 187 | reject() 188 | 189 | 190 | 316 191 | 260 192 | 193 | 194 | 286 195 | 274 196 | 197 | 198 | 199 | 200 |
201 | -------------------------------------------------------------------------------- /src/dialog/gaussianblurdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | GaussianBlurDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 243 10 | 102 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Gauss 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | <html><head/><body><p><span style=" font-size:11pt;">Radius = </span></p></body></html> 31 | 32 | 33 | 34 | 35 | 36 | 37 | 3 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | <html><head/><body><p><span style=" font-size:11pt;">Sigma = </span></p></body></html> 49 | 50 | 51 | 52 | 53 | 54 | 55 | Qt::StrongFocus 56 | 57 | 58 | 4 59 | 60 | 61 | 1.000000000000000 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Qt::Vertical 73 | 74 | 75 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | buttonBox 85 | accepted() 86 | GaussianBlurDialog 87 | accept() 88 | 89 | 90 | 248 91 | 254 92 | 93 | 94 | 157 95 | 274 96 | 97 | 98 | 99 | 100 | buttonBox 101 | rejected() 102 | GaussianBlurDialog 103 | reject() 104 | 105 | 106 | 316 107 | 260 108 | 109 | 110 | 286 111 | 274 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | w.show(); 10 | 11 | return a.exec(); 12 | } 13 | -------------------------------------------------------------------------------- /src/mainwindow/graphicsview.cpp: -------------------------------------------------------------------------------- 1 | #include "graphicsview.h" 2 | 3 | GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent) 4 | { 5 | factor = 0; 6 | } 7 | 8 | GraphicsView::~GraphicsView() 9 | { 10 | // to do 11 | } 12 | 13 | int GraphicsView::getFactor() 14 | { 15 | return factor; 16 | } 17 | 18 | void GraphicsView::setFactor(int _factor) 19 | { 20 | if (_factor == 0) 21 | { 22 | factor = 0; 23 | } 24 | else 25 | { 26 | factor += _factor; 27 | } 28 | } 29 | 30 | void GraphicsView::wheelEvent(QWheelEvent *e) 31 | { 32 | // Calculate wheel movement 33 | int distance = e->delta()/15/8; 34 | qreal val; 35 | 36 | if (distance != 0) 37 | { 38 | val = pow(1.2, distance); 39 | this->scale(val, val); 40 | if (distance > 0) 41 | { 42 | factor ++; 43 | } 44 | else 45 | { 46 | factor --; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/mainwindow/graphicsview.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPHICSVIEW_H 2 | #define GRAPHICSVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class GraphicsView : public QGraphicsView 9 | { 10 | private: 11 | int factor; 12 | 13 | public: 14 | GraphicsView(QWidget* parent = nullptr); 15 | ~GraphicsView(); 16 | 17 | int getFactor(); 18 | void setFactor(int _factor); 19 | 20 | protected: 21 | virtual void wheelEvent(QWheelEvent *e); 22 | }; 23 | 24 | #endif // GRAPHICSVIEW_H 25 | -------------------------------------------------------------------------------- /src/mainwindow/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.h" 2 | #include "ui_mainwindow.h" 3 | #include 4 | #include 5 | 6 | MainWindow::MainWindow(QWidget *parent) : 7 | QMainWindow(parent), 8 | ui(new Ui::MainWindow) 9 | { 10 | ui->setupUi(this); 11 | 12 | 13 | leftScene = new QGraphicsScene; 14 | rightScene = new QGraphicsScene; 15 | 16 | leftPixmapItem = new QGraphicsPixmapItem(); 17 | rightPixmapItem = new QGraphicsPixmapItem(); 18 | 19 | size = new QLabel; 20 | 21 | info = nullptr; 22 | 23 | leftScene->setBackgroundBrush(QColor::fromRgb(224,224,224)); 24 | ui->leftGraphicsView->setScene(leftScene); 25 | rightScene->setBackgroundBrush(QColor::fromRgb(224,224,224)); 26 | ui->rightGraphicsView->setScene(rightScene); 27 | 28 | ui->statusBar->addPermanentWidget(size); 29 | 30 | 31 | createAction(); 32 | createToolBar(); 33 | 34 | 35 | setActionStatus(false); 36 | setWindowTitle("ImageQt"); 37 | } 38 | 39 | void MainWindow::createToolBar() 40 | { 41 | ui->toolBar->addAction(ui->actionOpen); 42 | ui->toolBar->addAction(ui->actionClose); 43 | 44 | ui->toolBar->addSeparator(); 45 | ui->toolBar->addAction(ui->actionRestore); 46 | ui->toolBar->addAction(ui->actionHistogram); 47 | 48 | ui->toolBar->addSeparator(); 49 | } 50 | 51 | void MainWindow::createAction() 52 | { 53 | 54 | } 55 | 56 | 57 | 58 | MainWindow::~MainWindow() 59 | { 60 | delete ui; 61 | 62 | if (leftScene) 63 | { 64 | delete leftScene; 65 | leftScene = nullptr; 66 | } 67 | 68 | if (size) 69 | { 70 | delete size; 71 | size = nullptr; 72 | } 73 | 74 | 75 | //add 76 | if (rightScene) 77 | { 78 | delete leftScene; 79 | leftScene = nullptr; 80 | } 81 | 82 | } 83 | 84 | /****************************************************************************** 85 | * Update right image and repaint right scene 86 | *****************************************************************************/ 87 | void MainWindow::updateRightImage(QPixmap &pixmap) 88 | { 89 | rightPixmapItem->setPixmap(pixmap); 90 | rightScene->setSceneRect(QRectF(pixmap.rect())); 91 | } 92 | 93 | /****************************************************************************** 94 | * Clean image of both Scene 95 | * 96 | *****************************************************************************/ 97 | void MainWindow::cleanImage() 98 | { 99 | leftScene->clear(); 100 | ui->leftGraphicsView->resetTransform(); 101 | 102 | rightScene->clear(); 103 | ui->rightGraphicsView->resetTransform(); 104 | 105 | 106 | if (size) 107 | { 108 | delete size; 109 | size = new QLabel; 110 | ui->statusBar->addPermanentWidget(size); 111 | } 112 | 113 | 114 | 115 | this->setWindowTitle(WINDOW_TITLE); 116 | setActionStatus(false); 117 | } 118 | 119 | void MainWindow::setActionStatus(bool status) 120 | { 121 | ui->actionPrewitt->setEnabled(status); 122 | ui->actionContour_extraction->setEnabled(status); 123 | ui->actionEdge_following->setEnabled(status); 124 | // sharpen 125 | ui->actionLaplace->setEnabled(status); 126 | ui->actionSobel->setEnabled(status); 127 | //ui->actionEdge_Detection->setEnabled(status); 128 | // Blur 129 | ui->actionSimple->setEnabled(status); 130 | ui->actionGauss->setEnabled(status); 131 | ui->actionMeida_Filter->setEnabled(status); 132 | // Grey Transform 133 | ui->actionBinaryzation->setEnabled(status); 134 | ui->actionStretch_transformation->setEnabled(status); 135 | ui->actionExp_transfrom->setEnabled(status); 136 | ui->actionTwo_thresholds_transform->setEnabled(status); 137 | ui->actionPower_transformation->setEnabled(status); 138 | ui->actionLogarithm_grey_level_transformation->setEnabled(status); 139 | ui->actionSave->setEnabled(status); 140 | ui->actionClose->setEnabled(status); 141 | ui->actionSave_As->setEnabled(status); 142 | 143 | ui->actionCool->setEnabled(status); 144 | ui->actionWarm->setEnabled(status); 145 | ui->actionFlower_frame->setEnabled(status); 146 | ui->actionGrayscale->setEnabled(status); 147 | ui->actionHistogram->setEnabled(status); 148 | ui->actionHorizontal->setEnabled(status); 149 | ui->actionLeft->setEnabled(status); 150 | ui->actionLinear_level_transformation->setEnabled(status); 151 | ui->actionMetal->setEnabled(status); 152 | ui->actionMovie_frame->setEnabled(status); 153 | ui->actionNormal->setEnabled(status); 154 | ui->actionRestore->setEnabled(status); 155 | ui->actionVertical->setEnabled(status); 156 | ui->actionClassic_frame->setEnabled(status); 157 | ui->actionAdjust_brightness->setEnabled(status); 158 | ui->zoomAction->setEnabled(status); 159 | } 160 | 161 | 162 | 163 | 164 | void MainWindow::receiveGaussianFactor(int radius, double sigma) 165 | { 166 | GaussianBlur *blur = new GaussianBlur(radius, sigma); 167 | 168 | QPixmap rightImage = rightPixmapItem->pixmap(); 169 | 170 | QImage newImage = blur->BlurImage(rightImage.toImage()); 171 | rightImage.convertFromImage(newImage); 172 | 173 | updateRightImage(rightImage); 174 | } 175 | 176 | ///****************************************************************************** 177 | // * Receive data from zoom dialog 178 | // * and then call the function to done zoom action 179 | // *****************************************************************************/ 180 | //void MainWindow::receiveZoomFactor(int factor) 181 | //{ 182 | // qDebug()<<"zoom factor:"<pixmap(); 187 | 188 | // int cur_width = rightImage.width(); 189 | // int cur_height = rightImage.height(); 190 | 191 | // QPixmap newPixmap = rightImage.scaled(cur_width*factor/100, cur_height*factor/100); 192 | 193 | // updateRightImage(newPixmap); 194 | // } 195 | // else 196 | // { 197 | // return; 198 | // } 199 | //} 200 | 201 | void MainWindow::receiveLinearGreyParameter(double _a, double _b) 202 | { 203 | QPixmap rightImage = rightPixmapItem->pixmap(); 204 | 205 | QImage newImage = Tools::LinearLevelTransformation(rightImage.toImage(), _a, _b); 206 | rightImage.convertFromImage(newImage); 207 | 208 | updateRightImage(rightImage); 209 | } 210 | 211 | void MainWindow::receivePowerGreyParamter(double c, double r, double b) 212 | { 213 | QPixmap rightImage = rightPixmapItem->pixmap(); 214 | QImage newImage = Tools::PowerGreyLevelTransformation(rightImage.toImage(), c, r, b); 215 | rightImage.convertFromImage(newImage); 216 | 217 | updateRightImage(rightImage); 218 | } 219 | 220 | void MainWindow::receiveLogGreyParamter(double _a, double _b) 221 | { 222 | QPixmap rightImage = rightPixmapItem->pixmap(); 223 | QImage newImage = Tools::LinearLevelTransformation(rightImage.toImage(), _a, _b); 224 | rightImage.convertFromImage(newImage); 225 | 226 | updateRightImage(rightImage); 227 | } 228 | 229 | void MainWindow::receiveExpGreyParamter(double b, double c, double a) 230 | { 231 | QPixmap rightImage = rightPixmapItem->pixmap(); 232 | QImage newImage = Tools::ExpTransform(rightImage.toImage(), b, c, a); 233 | rightImage.convertFromImage(newImage); 234 | 235 | updateRightImage(rightImage); 236 | } 237 | 238 | void MainWindow::receiveTwoThresholdParamter(int t1, int t2, int option) 239 | { 240 | QPixmap rightImage = rightPixmapItem->pixmap(); 241 | QImage newImage = Tools::TwoThreshold(rightImage.toImage(), t1, t2, option); 242 | rightImage.convertFromImage(newImage); 243 | 244 | updateRightImage(rightImage); 245 | } 246 | 247 | void MainWindow::receiveStretchParamter(int x1, int x2, 248 | double k1, double k2, double k3, 249 | double b2, double b3) 250 | { 251 | QPixmap rightImage = rightPixmapItem->pixmap(); 252 | QImage newImage = Tools::StretchTransform(rightImage.toImage(),x1,x2,k1,k2,k3,b2,b3); 253 | rightImage.convertFromImage(newImage); 254 | 255 | updateRightImage(rightImage); 256 | } 257 | 258 | 259 | 260 | 261 | /****************************************************************************** 262 | * Open a image file and show it 263 | ****************************************************************************** 264 | * Args: 265 | * QString imagePath: The abslute path of a image 266 | *****************************************************************************/ 267 | void MainWindow::on_actionOpen_triggered() 268 | { 269 | // Automatically detects the current user's home directory 270 | // And then wait the user to select one image 271 | QString imagePath = QFileDialog::getOpenFileName(this, tr("Open image"), getUserPath() + "/Pictures", 272 | tr("All Files (*);;" 273 | "All Images (*.bpm *.gif *.jpg *.jpeg *.png *.ppm *.xbm *.xpm);;" 274 | "Image BPM (*.bpm);;" 275 | "Image GIF (*.gif);;" 276 | "Image JPG (*.jpg);;" 277 | "Image JPEG (*.jpeg);;" 278 | "Image PNG (*.png);;" 279 | "Image PPM (*.ppm);;" 280 | "Image XBM (*.xbm);;" 281 | "Image XPM (*.xpm);;")); 282 | 283 | if (!imagePath.isEmpty()) 284 | { 285 | QFile file(imagePath); 286 | if (!file.open(QIODevice::ReadOnly)) { 287 | QMessageBox::critical(this, tr(WINDOW_CRITICAL), 288 | tr("Unable to open image.")); 289 | return; 290 | } 291 | 292 | // delete previous image 293 | cleanImage(); 294 | 295 | // upload image 296 | info = new QFileInfo(imagePath); 297 | 298 | QPixmap leftPixmap(imagePath); 299 | leftPixmapItem = leftScene->addPixmap(leftPixmap); 300 | leftScene->setSceneRect(QRectF(leftPixmap.rect())); 301 | 302 | QPixmap rightPixmap(imagePath); 303 | rightPixmapItem = rightScene->addPixmap(rightPixmap); 304 | rightScene->setSceneRect(QRectF(rightPixmap.rect())); 305 | 306 | // settings 307 | this->setWindowTitle(info->fileName() + " - ImageQt"); 308 | 309 | setActionStatus(true); 310 | 311 | size->setText(QString::number(leftPixmapItem->pixmap().width()) 312 | + " x " + QString::number(leftPixmapItem->pixmap().height())); 313 | } 314 | } 315 | 316 | /****************************************************************************** 317 | * Clean image of both Scene 318 | * 319 | *****************************************************************************/ 320 | void MainWindow::on_actionClose_triggered() 321 | { 322 | cleanImage(); 323 | } 324 | 325 | void MainWindow::on_actionSave_triggered() 326 | { 327 | 328 | } 329 | 330 | /****************************************************************************** 331 | * Action : Save as 332 | *****************************************************************************/ 333 | void MainWindow::on_actionSave_As_triggered() 334 | { 335 | 336 | QString newPath = QFileDialog::getSaveFileName(this, tr("Save image"), QString(), 337 | tr("All files (*);;" 338 | "Image BPM (*.bpm);;" 339 | "Image GIF (*.gif);;" 340 | "Image JPG (*.jpg);;" 341 | "Image JPEG (*.jpeg);;" 342 | "Image PNG (*.png);;" 343 | "Image PPM (*.ppm);;" 344 | "Image XBM (*.xbm);;" 345 | "Image XPM (*.xpm);;")); 346 | 347 | if (!newPath.isEmpty()) { 348 | 349 | QFile file(newPath); 350 | if (!file.open(QIODevice::WriteOnly)) { 351 | QMessageBox::critical(this, tr(WINDOW_CRITICAL), tr("Unable to save image.")); 352 | return; 353 | } 354 | 355 | //Save image to new path 356 | rightPixmapItem->pixmap().save(newPath); 357 | // rightImage->save(newPath); 358 | } 359 | } 360 | 361 | /****************************************************************************** 362 | * Exit the program 363 | * 364 | *****************************************************************************/ 365 | void MainWindow::on_actionExit_triggered() 366 | { 367 | qApp->quit(); 368 | } 369 | 370 | 371 | 372 | 373 | /****************************************************************************** 374 | * Greyscale 375 | *****************************************************************************/ 376 | void MainWindow::on_actionGrayscale_triggered() 377 | { 378 | QPixmap rightImage = rightPixmapItem->pixmap(); 379 | QImage newImage = Tools::GreyScale(rightImage.toImage()); 380 | rightImage.convertFromImage(newImage); 381 | 382 | updateRightImage(rightImage); 383 | } 384 | 385 | 386 | 387 | /****************************************************************************** 388 | * Adjust the image size to fit the window 389 | * 390 | *****************************************************************************/ 391 | void MainWindow::on_actionAdjust_triggered() 392 | { 393 | // left 394 | int height = leftPixmapItem->pixmap().height(); 395 | int width = leftPixmapItem->pixmap().width(); 396 | int max_height = ui->leftGraphicsView->height(); 397 | int max_width = ui->leftGraphicsView->width(); 398 | int size,max_size,fact=0; 399 | double val=0; 400 | 401 | 402 | size = qMin(width,height); 403 | max_size = qMin(max_width,max_height); 404 | 405 | 406 | if (size < max_size) { 407 | while ((size*val) < max_size) 408 | val = pow(1.2,fact++); 409 | val = pow(1.2,fact-2); 410 | ui->leftGraphicsView->setFactor(fact-2); 411 | } 412 | 413 | else { 414 | val = 1; 415 | while ((size*val) > max_size) 416 | val = pow(1.2,fact--); 417 | val = pow(1.2,fact+1); 418 | ui->leftGraphicsView->setFactor(fact+1); 419 | } 420 | 421 | ui->leftGraphicsView->scale(val,val); 422 | 423 | 424 | // right 425 | height = leftPixmapItem->pixmap().height(); 426 | width = leftPixmapItem->pixmap().width(); 427 | max_height = ui->rightGraphicsView->height(); 428 | max_width = ui->rightGraphicsView->width(); 429 | size = max_size = fact = 0; 430 | val=0; 431 | 432 | 433 | size = qMin(width,height); 434 | max_size = qMin(max_width,max_height); 435 | 436 | 437 | if (size < max_size) { 438 | while ((size*val) < max_size) 439 | val = pow(1.2,fact++); 440 | val = pow(1.2,fact-2); 441 | ui->rightGraphicsView->setFactor(fact-2); 442 | } 443 | 444 | else { 445 | val = 1; 446 | while ((size*val) > max_size) 447 | val = pow(1.2,fact--); 448 | val = pow(1.2,fact+1); 449 | ui->rightGraphicsView->setFactor(fact+1); 450 | } 451 | 452 | ui->rightGraphicsView->scale(val,val); 453 | 454 | 455 | } 456 | 457 | 458 | 459 | 460 | /****************************************************************************** 461 | * Restore the image, both size and rotate 462 | *****************************************************************************/ 463 | void MainWindow::on_actionRestore_triggered() 464 | { 465 | on_actionNormal_triggered(); 466 | 467 | } 468 | 469 | /****************************************************************************** 470 | * 绘制图像直方图 471 | *****************************************************************************/ 472 | void MainWindow::on_actionHistogram_triggered() 473 | { 474 | 475 | QDialog * hstgrmDialog = new QDialog(this); 476 | QScrollArea * scrollArea = new QScrollArea(hstgrmDialog); 477 | Histogram * hstgrm = new Histogram(scrollArea); 478 | hstgrm->computeHstgrm(rightPixmapItem->pixmap().toImage()); 479 | 480 | if (hstgrm == nullptr) 481 | return; 482 | 483 | 484 | scrollArea->setWidget(hstgrm); 485 | 486 | QHBoxLayout * layout = new QHBoxLayout; 487 | layout->addWidget(scrollArea); 488 | hstgrmDialog->setLayout(layout); 489 | 490 | hstgrm->resize(800, 780); 491 | hstgrmDialog->setFixedWidth(820); 492 | scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 493 | scrollArea->adjustSize(); 494 | 495 | hstgrmDialog->setWindowTitle("Histogram - ImageQt"); 496 | 497 | hstgrmDialog->show(); 498 | } 499 | 500 | 501 | /****************************************************************************** 502 | * Add frame 503 | *****************************************************************************/ 504 | void MainWindow::on_actionMovie_frame_triggered() 505 | { 506 | QPixmap rightImage = rightPixmapItem->pixmap(); 507 | QImage frame = QImage(":/img/frame_3.png"); 508 | QImage newImage = Tools::DrawFrame(rightImage.toImage(), frame); 509 | rightImage.convertFromImage(newImage); 510 | 511 | updateRightImage(rightImage); 512 | } 513 | 514 | void MainWindow::on_actionClassic_frame_triggered() 515 | { 516 | QPixmap rightImage = rightPixmapItem->pixmap(); 517 | QImage frame = QImage(":/img/frame_1.png"); 518 | QImage newImage = Tools::DrawFrame(rightImage.toImage(), frame); 519 | rightImage.convertFromImage(newImage); 520 | 521 | updateRightImage(rightImage); 522 | } 523 | 524 | void MainWindow::on_actionFlower_frame_triggered() 525 | { 526 | QPixmap rightImage = rightPixmapItem->pixmap(); 527 | QImage frame = QImage(":/img/frame_2.png"); 528 | QImage newImage = Tools::DrawFrame(rightImage.toImage(), frame); 529 | rightImage.convertFromImage(newImage); 530 | 531 | updateRightImage(rightImage); 532 | } 533 | 534 | /****************************************************************************** 535 | * Add metal texture 536 | *****************************************************************************/ 537 | void MainWindow::on_actionMetal_triggered() 538 | { 539 | QPixmap rightImage = rightPixmapItem->pixmap(); 540 | QImage newImage = Tools::Metal(rightImage.toImage()); 541 | rightImage.convertFromImage(newImage); 542 | 543 | updateRightImage(rightImage); 544 | } 545 | 546 | /****************************************************************************** 547 | * Cool 548 | *****************************************************************************/ 549 | void MainWindow::on_actionCool_triggered() 550 | { 551 | QPixmap rightImage = rightPixmapItem->pixmap(); 552 | QImage newImage = Tools::Cool(30, rightImage.toImage()); 553 | rightImage.convertFromImage(newImage); 554 | 555 | updateRightImage(rightImage); 556 | } 557 | 558 | /****************************************************************************** 559 | * Warm 560 | *****************************************************************************/ 561 | void MainWindow::on_actionWarm_triggered() 562 | { 563 | QPixmap rightImage = rightPixmapItem->pixmap(); 564 | QImage newImage = Tools::Warm(30, rightImage.toImage()); 565 | rightImage.convertFromImage(newImage); 566 | 567 | updateRightImage(rightImage); 568 | } 569 | 570 | 571 | 572 | 573 | /****************************************************************************** 574 | * 简单平滑 575 | *****************************************************************************/ 576 | void MainWindow::on_actionSimple_triggered() 577 | { 578 | QPixmap rightImage = rightPixmapItem->pixmap(); 579 | QImage newImage = Tools::SimpleSmooth(rightImage.toImage()); 580 | rightImage.convertFromImage(newImage); 581 | 582 | updateRightImage(rightImage); 583 | } 584 | 585 | /****************************************************************************** 586 | * 高斯平滑 587 | *****************************************************************************/ 588 | void MainWindow::on_actionGauss_triggered() 589 | { 590 | GaussianBlurDialog dialog; 591 | connect(&dialog, SIGNAL(sendData(int, double)), this, 592 | SLOT(receiveGaussianFactor(int, double))); 593 | 594 | dialog.exec(); 595 | } 596 | 597 | /****************************************************************************** 598 | * 中值滤波 599 | *****************************************************************************/ 600 | void MainWindow::on_actionMeida_Filter_triggered() 601 | { 602 | bool ok; 603 | int value = QInputDialog::getInt(this, tr("Media Filter"), "Input a value for radius(1~30)",3,1,30,1,&ok); 604 | if (ok) 605 | { 606 | QPixmap rightImage = rightPixmapItem->pixmap(); 607 | QImage newImage = Tools::MeidaFilter(rightImage.toImage(), value); 608 | rightImage.convertFromImage(newImage); 609 | 610 | updateRightImage(rightImage); 611 | } 612 | } 613 | 614 | 615 | /****************************************************************************** 616 | * on Action tools->zoom triggered 617 | *****************************************************************************/ 618 | void MainWindow::on_zoomAction_triggered() 619 | { 620 | 621 | bool ok; 622 | int factor = QInputDialog::getInt(this, tr("Zoom"), "Input a value for zoom ratio(%)",100,10,1000,10,&ok); 623 | if (ok) 624 | { 625 | if (factor != 100) 626 | { 627 | QPixmap rightImage = rightPixmapItem->pixmap(); 628 | 629 | int cur_width = rightImage.width(); 630 | int cur_height = rightImage.height(); 631 | 632 | QPixmap newPixmap = rightImage.scaled(cur_width*factor/100, cur_height*factor/100); 633 | 634 | updateRightImage(newPixmap); 635 | } 636 | else 637 | { 638 | return; 639 | } 640 | } 641 | 642 | } 643 | 644 | /****************************************************************************** 645 | * Flip Horizontal 646 | *****************************************************************************/ 647 | void MainWindow::on_actionHorizontal_triggered() 648 | { 649 | QPixmap rightImage = rightPixmapItem->pixmap(); 650 | QImage newImage = Tools::Horizontal(rightImage.toImage()); 651 | rightImage.convertFromImage(newImage); 652 | 653 | updateRightImage(rightImage); 654 | } 655 | 656 | /****************************************************************************** 657 | * Flip Vertical 658 | *****************************************************************************/ 659 | void MainWindow::on_actionVertical_triggered() 660 | { 661 | QPixmap rightImage = rightPixmapItem->pixmap(); 662 | QImage newImage = Tools::Vertical(rightImage.toImage()); 663 | rightImage.convertFromImage(newImage); 664 | 665 | updateRightImage(rightImage); 666 | } 667 | 668 | 669 | 670 | 671 | /****************************************************************************** 672 | * 灰度线性变换 y = ax + b 673 | *****************************************************************************/ 674 | void MainWindow::on_actionLinear_level_transformation_triggered() 675 | { 676 | LinearGrayDialog dialog; 677 | connect(&dialog, SIGNAL(sendData(double, double)), 678 | this, SLOT(receiveLinearGreyParameter(double,double))); 679 | dialog.exec(); 680 | } 681 | 682 | /****************************************************************************** 683 | * 灰度幂次变换 684 | *****************************************************************************/ 685 | void MainWindow::on_actionPower_transformation_triggered() 686 | { 687 | DialogPowerGrey dialog; 688 | connect(&dialog, SIGNAL(sendData(double, double, double)), 689 | this, SLOT(receivePowerGreyParamter(double,double,double))); 690 | dialog.exec(); 691 | } 692 | 693 | /****************************************************************************** 694 | * 灰度对数变换 y = log(b+x)/log(a) 695 | *****************************************************************************/ 696 | void MainWindow::on_actionLogarithm_grey_level_transformation_triggered() 697 | { 698 | DialogLogGrey dialog; 699 | connect(&dialog, SIGNAL(sendData(double, double)), 700 | this, SLOT(receiveLogGreyParamter(double,double))); 701 | dialog.exec(); 702 | } 703 | 704 | /****************************************************************************** 705 | * 灰度指数变换 706 | *****************************************************************************/ 707 | void MainWindow::on_actionExp_transfrom_triggered() 708 | { 709 | DialogExpTransform dialog; 710 | connect(&dialog, SIGNAL(sendData(double, double, double)), 711 | this, SLOT(receiveExpGreyParamter(double,double,double))); 712 | dialog.exec(); 713 | } 714 | 715 | /****************************************************************************** 716 | * 灰度双阈值变换 717 | *****************************************************************************/ 718 | void MainWindow::on_actionTwo_thresholds_transform_triggered() 719 | { 720 | DialogThresholdTransform dialog; 721 | connect(&dialog, SIGNAL(sendData(int, int, int)), 722 | this, SLOT(receiveTwoThresholdParamter(int,int,int))); 723 | dialog.exec(); 724 | } 725 | 726 | /****************************************************************************** 727 | * 灰度拉伸变换 728 | *****************************************************************************/ 729 | void MainWindow::on_actionStretch_transformation_triggered() 730 | { 731 | DialogStretchTransform dialog; 732 | connect(&dialog, SIGNAL(sendData(int,int,double,double,double,double,double)), 733 | this, SLOT(receiveStretchParamter(int,int,double,double,double,double,double))); 734 | dialog.exec(); 735 | } 736 | 737 | /****************************************************************************** 738 | * laplace sharpen 739 | *****************************************************************************/ 740 | void MainWindow::on_actionLaplace_triggered() 741 | { 742 | QPixmap rightImage = rightPixmapItem->pixmap(); 743 | QImage newImage = Tools::LaplaceSharpen(rightImage.toImage()); 744 | rightImage.convertFromImage(newImage); 745 | 746 | updateRightImage(rightImage); 747 | } 748 | 749 | void MainWindow::on_actionSobel_triggered() 750 | { 751 | QPixmap rightImage = rightPixmapItem->pixmap(); 752 | QImage newImage = Tools::SobelEdge(rightImage.toImage()); 753 | rightImage.convertFromImage(newImage); 754 | 755 | updateRightImage(rightImage); 756 | } 757 | 758 | 759 | void MainWindow::on_actionBinaryzation_triggered() 760 | { 761 | QPixmap rightImage = rightPixmapItem->pixmap(); 762 | QImage newImage = Tools::Binaryzation(rightImage.toImage()); 763 | rightImage.convertFromImage(newImage); 764 | 765 | updateRightImage(rightImage); 766 | } 767 | 768 | 769 | 770 | /****************************************************************************** 771 | * 调整亮度 772 | *****************************************************************************/ 773 | void MainWindow::on_actionAdjust_brightness_triggered() 774 | { 775 | bool ok; 776 | int delta = QInputDialog::getInt(this, 777 | tr("Brightness"), 778 | "Input a value for brightness(+/-)", 779 | 0,-1000,1000,10,&ok); 780 | if (ok) 781 | { 782 | if (delta != 100) 783 | { 784 | QPixmap rightImage = rightPixmapItem->pixmap(); 785 | 786 | QImage newImage = Tools::Brightness(delta, rightImage.toImage()); 787 | rightImage.convertFromImage(newImage); 788 | 789 | updateRightImage(rightImage); 790 | } 791 | else 792 | { 793 | return; 794 | } 795 | } 796 | 797 | } 798 | 799 | 800 | /****************************************************************************** 801 | * To do 802 | *****************************************************************************/ 803 | void MainWindow::on_actionNormal_triggered() 804 | { 805 | QPixmap leftImage = leftPixmapItem->pixmap(); 806 | updateRightImage(leftImage); 807 | ui->rightGraphicsView->resetTransform(); 808 | } 809 | 810 | 811 | 812 | 813 | /****************************************************************************** 814 | * “关于”窗口 815 | *****************************************************************************/ 816 | void MainWindow::on_actionAbout_triggered() 817 | { 818 | QMessageBox message(QMessageBox::NoIcon, tr(WINDOW_ABOUT), "

ImageQt

" 819 | "Powered By Qt 5.12.0."); 820 | message.setIconPixmap(QPixmap(":/img/logo_1.png")); 821 | message.exec(); 822 | } 823 | 824 | 825 | /****************************************************************************** 826 | * 获得当前用户的用户名 827 | *****************************************************************************/ 828 | QString MainWindow::getUserName() 829 | { 830 | QString userPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); 831 | QString userName = userPath.section("/", -1, -1); 832 | return userName; 833 | } 834 | 835 | /****************************************************************************** 836 | * 获得当前用户的家目录 837 | *****************************************************************************/ 838 | QString MainWindow::getUserPath() 839 | { 840 | QString userPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); 841 | return userPath; 842 | } 843 | 844 | //void MainWindow::on_actionT_triggered() 845 | //{ 846 | // QLabel* l = new QLabel; 847 | // if (!rightPixmapItem->pixmap().isNull()) { 848 | // qDebug() << "hello"; 849 | // l->setPixmap(rightPixmapItem->pixmap()); 850 | // l->show(); 851 | // } 852 | //} 853 | 854 | /****************************************************************************** 855 | * Prewitt边缘检测 856 | *****************************************************************************/ 857 | void MainWindow::on_actionPrewitt_triggered() 858 | { 859 | QPixmap rightImage = rightPixmapItem->pixmap(); 860 | QImage newImage = Tools::PrewittEdge(rightImage.toImage()); 861 | rightImage.convertFromImage(newImage); 862 | 863 | updateRightImage(rightImage); 864 | } 865 | 866 | 867 | /****************************************************************************** 868 | * 轮廓提取法 869 | *****************************************************************************/ 870 | void MainWindow::on_actionContour_extraction_triggered() 871 | { 872 | QPixmap rightImage = rightPixmapItem->pixmap(); 873 | QImage newImage = Tools::ContourExtraction(rightImage.toImage()); 874 | rightImage.convertFromImage(newImage); 875 | 876 | updateRightImage(rightImage); 877 | } 878 | 879 | void MainWindow::on_actionArea_triggered() 880 | { 881 | QPixmap rightImage = rightPixmapItem->pixmap(); 882 | QImage newImg = rightImage.toImage(); 883 | QImage binImg = Tools::Binaryzation(newImg); 884 | int area = 0; 885 | for(int x=0; xshow(); 896 | } 897 | 898 | 899 | void MainWindow::on_actionCircumference_triggered() 900 | { 901 | QPixmap rightImage = rightPixmapItem->pixmap(); 902 | QImage newImg = rightImage.toImage(); 903 | QImage sobelImg = Tools::SobelEdge(newImg); 904 | sobelImg = Tools::Binaryzation(sobelImg); 905 | int c = 0; 906 | for(int x=0; xshow(); 916 | } 917 | 918 | 919 | 920 | void MainWindow::on_actionDilate_triggered() 921 | { 922 | QPixmap rightImage = rightPixmapItem->pixmap(); 923 | QImage binaryImage = Tools::Binaryzation(rightImage.toImage()); 924 | QImage newImage = Tools::Dilate(binaryImage); 925 | rightImage.convertFromImage(newImage); 926 | 927 | updateRightImage(rightImage); 928 | } 929 | 930 | void MainWindow::on_actionExpansion_triggered() 931 | { 932 | QPixmap rightImage = rightPixmapItem->pixmap(); 933 | QImage binaryImage = Tools::Binaryzation(rightImage.toImage()); 934 | QImage newImage = Tools::Expansion(binaryImage); 935 | rightImage.convertFromImage(newImage); 936 | 937 | updateRightImage(rightImage); 938 | } 939 | 940 | /***************************************************************************** 941 | * 开运算 942 | * **************************************************************************/ 943 | void MainWindow::on_actionOpening_triggered() 944 | { 945 | QPixmap rightImage = rightPixmapItem->pixmap(); 946 | QImage binaryImage = Tools::Binaryzation(rightImage.toImage()); 947 | QImage newImage = Tools::Opening(binaryImage); 948 | rightImage.convertFromImage(newImage); 949 | 950 | updateRightImage(rightImage); 951 | } 952 | 953 | 954 | /***************************************************************************** 955 | * 闭运算 956 | * **************************************************************************/ 957 | void MainWindow::on_actionClosing_triggered() 958 | { 959 | QPixmap rightImage = rightPixmapItem->pixmap(); 960 | QImage binaryImage = Tools::Binaryzation(rightImage.toImage()); 961 | QImage newImage = Tools::Closing(binaryImage); 962 | rightImage.convertFromImage(newImage); 963 | 964 | updateRightImage(rightImage); 965 | } 966 | 967 | /***************************************************************************** 968 | * 图像细化 969 | * **************************************************************************/ 970 | void MainWindow::on_actionThinning_triggered() 971 | { 972 | // QPixmap rightImage = rightPixmapItem->pixmap(); 973 | // QImage newImage = Tools::Thinning(rightImage.toImage()); 974 | // rightImage.convertFromImage(newImage); 975 | 976 | // updateRightImage(rightImage); 977 | qDebug() << "TODO"; 978 | } 979 | 980 | 981 | //void MainWindow::on_actionRGB2HSV_triggered() 982 | //{ 983 | // QPixmap rightImage = rightPixmapItem->pixmap(); 984 | // QImage newImage = Tools::RGB2HSV(rightImage.toImage()); 985 | // rightImage.convertFromImage(newImage); 986 | 987 | // updateRightImage(rightImage); 988 | //} 989 | 990 | //void MainWindow::on_actionRGB2HSL_triggered() 991 | //{ 992 | // QPixmap rightImage = rightPixmapItem->pixmap(); 993 | // QImage newImage = Tools::RGB2HSL(rightImage.toImage()); 994 | // rightImage.convertFromImage(newImage); 995 | 996 | // updateRightImage(rightImage); 997 | //} 998 | 999 | //void MainWindow::on_actionRGB2Cmyk_triggered() 1000 | //{ 1001 | // QPixmap rightImage = rightPixmapItem->pixmap(); 1002 | // QImage newImage = Tools::RGB2CMYK(rightImage.toImage()); 1003 | // rightImage.convertFromImage(newImage); 1004 | 1005 | // updateRightImage(rightImage); 1006 | //} 1007 | 1008 | void MainWindow::on_actionRotate_triggered() 1009 | { 1010 | bool ok; 1011 | int factor = QInputDialog::getInt(this, tr("旋转"), "请输入要旋转的角度(正数向右,负数向左)",0,-360,360,10,&ok); 1012 | if (ok) 1013 | { 1014 | if (factor != 0) 1015 | { 1016 | QPixmap rightImage = rightPixmapItem->pixmap(); 1017 | 1018 | QImage *imgRotate = new QImage; 1019 | QMatrix matrix; 1020 | matrix.rotate(factor); 1021 | *imgRotate = rightImage.toImage().transformed(matrix); 1022 | QPixmap newPixmap; 1023 | newPixmap = QPixmap::fromImage(*imgRotate); 1024 | updateRightImage(newPixmap); 1025 | } 1026 | else 1027 | { 1028 | return; 1029 | } 1030 | } 1031 | } 1032 | -------------------------------------------------------------------------------- /src/mainwindow/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "graphicsview.h" 15 | #include "../dialog/dialog_gaussianblur.h" 16 | #include "../utils/tools.h" 17 | #include "../utils/histogram.h" 18 | #include "../utils/gaussianblur.h" 19 | #include "../utils/medianfilter.h" 20 | #include "../dialog/dialog_linear_gray.h" 21 | #include "../dialog/dialog_log_grey.h" 22 | #include "../dialog/dialog_power_grey.h" 23 | #include "../dialog/dialog_exp_transform.h" 24 | #include "../dialog/dialog_two_threshold_transform.h" 25 | #include "../dialog/dialog_stretch_transform.h" 26 | 27 | #define WINDOW_TITLE "ImageQt" 28 | #define WINDOW_CRITICAL "Error - ImageQt" 29 | #define WINDOW_WARNING "Notice - ImageQt" 30 | #define WINDOW_ABOUT "About - ImageQt" 31 | 32 | namespace Ui { 33 | class MainWindow; 34 | } 35 | 36 | class MainWindow : public QMainWindow 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | explicit MainWindow(QWidget *parent = nullptr); 42 | ~MainWindow(); 43 | 44 | void updateRightImage(QPixmap &pixmap); 45 | void cleanImage(); 46 | 47 | void setActionStatus(bool); 48 | void createToolBar(); 49 | void createAction(); 50 | 51 | private slots: 52 | 53 | // 从子对话框中接收数据 54 | void receiveGaussianFactor(int radius, double sigma); 55 | void receiveLinearGreyParameter(double, double); 56 | void receivePowerGreyParamter(double, double, double); 57 | void receiveLogGreyParamter(double, double); 58 | void receiveExpGreyParamter(double, double, double); 59 | void receiveTwoThresholdParamter(int, int, int); 60 | void receiveStretchParamter(int, int, double,double,double,double,double); 61 | 62 | // On action triggered 63 | void on_actionOpen_triggered(); 64 | void on_actionClose_triggered(); // Clear both left and right Scene 65 | void on_actionSave_triggered(); 66 | void on_actionSave_As_triggered(); // Save as 67 | void on_actionExit_triggered(); // Exit the program 68 | 69 | void on_actionGrayscale_triggered(); // Grayscale 70 | void on_actionAdjust_brightness_triggered(); 71 | 72 | void on_actionRestore_triggered(); // Restore to the original image 73 | void on_actionHistogram_triggered(); 74 | 75 | void on_actionMovie_frame_triggered(); 76 | void on_actionClassic_frame_triggered(); 77 | void on_actionFlower_frame_triggered(); 78 | void on_actionMetal_triggered(); 79 | void on_actionCool_triggered(); 80 | void on_actionWarm_triggered(); 81 | 82 | void on_actionSimple_triggered(); 83 | void on_actionGauss_triggered(); 84 | void on_actionMeida_Filter_triggered(); 85 | 86 | void on_zoomAction_triggered(); // Zoom action with dialog 87 | void on_actionHorizontal_triggered(); 88 | void on_actionVertical_triggered(); 89 | 90 | void on_actionLinear_level_transformation_triggered(); 91 | void on_actionPower_transformation_triggered(); 92 | void on_actionLogarithm_grey_level_transformation_triggered(); 93 | void on_actionExp_transfrom_triggered(); 94 | void on_actionTwo_thresholds_transform_triggered(); 95 | void on_actionStretch_transformation_triggered(); 96 | 97 | void on_actionAdjust_triggered(); // Adjust to fit the window size 98 | void on_actionNormal_triggered(); // Restore the right image to original size 99 | 100 | 101 | void on_actionAbout_triggered(); // Show "About" dialog 102 | 103 | // void on_actionT_triggered(); 104 | 105 | void on_actionLaplace_triggered(); 106 | 107 | // void on_actionEdge_Detection_triggered(); 108 | 109 | void on_actionSobel_triggered(); 110 | 111 | void on_actionBinaryzation_triggered(); 112 | 113 | void on_actionPrewitt_triggered(); 114 | 115 | void on_actionContour_extraction_triggered(); 116 | 117 | void on_actionArea_triggered(); 118 | 119 | void on_actionCircumference_triggered(); 120 | 121 | 122 | void on_actionDilate_triggered(); 123 | 124 | void on_actionExpansion_triggered(); 125 | 126 | void on_actionOpening_triggered(); 127 | 128 | void on_actionClosing_triggered(); 129 | 130 | void on_actionThinning_triggered(); 131 | 132 | // void on_actionRGB2HSV_triggered(); 133 | // void on_actionRGB2HSL_triggered(); 134 | // void on_actionRGB2Cmyk_triggered(); 135 | 136 | void on_actionRotate_triggered(); 137 | 138 | private: 139 | QAction *finalEx; 140 | 141 | Ui::MainWindow *ui; 142 | QGraphicsScene *leftScene; 143 | QGraphicsScene *rightScene; 144 | QGraphicsPixmapItem* leftPixmapItem; 145 | QGraphicsPixmapItem* rightPixmapItem; 146 | 147 | QLabel *size; 148 | 149 | QFileInfo *info; 150 | 151 | QString getUserName(); 152 | QString getUserPath(); 153 | }; 154 | 155 | #endif // MAINWINDOW_H 156 | -------------------------------------------------------------------------------- /src/mainwindow/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1196 10 | 711 11 | 12 | 13 | 14 | ImageQt 15 | 16 | 17 | 18 | :/img/logo_2.png:/img/logo_2.png 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 0 43 | 0 44 | 1196 45 | 26 46 | 47 | 48 | 49 | 50 | 文件(&F) 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 编辑 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 帮助 71 | 72 | 73 | 74 | 75 | 76 | 灰色变换(&G) 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 几何变换 90 | 91 | 92 | 93 | 翻转 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 艺术效果 106 | 107 | 108 | 109 | 相框 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 纹理 118 | 119 | 120 | 121 | 122 | 123 | 色温 124 | 125 | 126 | 127 | :/img/src/temperature_72px.png:/img/src/temperature_72px.png 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 模糊与锐化 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 轮廓提取 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 形态学 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | toolBar 180 | 181 | 182 | TopToolBarArea 183 | 184 | 185 | false 186 | 187 | 188 | 189 | 190 | 191 | :/img/open.svg:/img/open.svg 192 | 193 | 194 | 打开(&O) 195 | 196 | 197 | 打开一张图片 198 | 199 | 200 | Ctrl+O 201 | 202 | 203 | 204 | 205 | 206 | :/img/clear.svg:/img/clear.svg 207 | 208 | 209 | 关闭图片 210 | 211 | 212 | 213 | 214 | 215 | :/img/save.svg:/img/save.svg 216 | 217 | 218 | 保存(&S) 219 | 220 | 221 | Ctrl+S 222 | 223 | 224 | 225 | 226 | 另存为 227 | 228 | 229 | 230 | 231 | 退出 232 | 233 | 234 | Ctrl+Q 235 | 236 | 237 | 238 | 239 | 240 | :/img/about.svg:/img/about.svg 241 | 242 | 243 | 关于 244 | 245 | 246 | 247 | 248 | Normal 249 | 250 | 251 | 252 | 253 | Adjust 254 | 255 | 256 | 257 | 258 | 259 | :/img/restore.png:/img/restore.png 260 | 261 | 262 | 恢复 263 | 264 | 265 | 266 | 267 | 268 | :/img/src/left.png:/img/src/left.png 269 | 270 | 271 | &Left 272 | 273 | 274 | 275 | 276 | 277 | :/img/src/zoom.png:/img/src/zoom.png 278 | 279 | 280 | 缩放 281 | 282 | 283 | 284 | 285 | 灰度图像 286 | 287 | 288 | 289 | 290 | &Warm 291 | 292 | 293 | 294 | 295 | &Cool 296 | 297 | 298 | 299 | 300 | 电影 301 | 302 | 303 | 304 | 305 | 经典 306 | 307 | 308 | 309 | 310 | 小花 311 | 312 | 313 | 314 | 315 | 金属 316 | 317 | 318 | 319 | 320 | 321 | :/img/brightness.svg:/img/brightness.svg 322 | 323 | 324 | 亮度 325 | 326 | 327 | 328 | 329 | 330 | :/img/src/horizontal.png:/img/src/horizontal.png 331 | 332 | 333 | 水平 334 | 335 | 336 | 337 | 338 | 339 | :/img/src/vertical.png:/img/src/vertical.png 340 | 341 | 342 | 垂直 343 | 344 | 345 | 346 | 347 | 348 | :/img/histogram.png:/img/histogram.png 349 | 350 | 351 | 直方图 352 | 353 | 354 | 355 | 356 | 357 | :/img/src/line_graphic_72p.png:/img/src/line_graphic_72p.png 358 | 359 | 360 | 线性变换 361 | 362 | 363 | 364 | 365 | 对数变换 366 | 367 | 368 | 369 | 370 | 幂次变换 371 | 372 | 373 | 374 | 375 | 376 | :/img/src/Line_Chart_72px.png:/img/src/Line_Chart_72px.png 377 | 378 | 379 | 指数变换 380 | 381 | 382 | 383 | 384 | 双阈值变换 385 | 386 | 387 | 388 | 389 | 拉伸变换 390 | 391 | 392 | 393 | 394 | 简单模糊 395 | 396 | 397 | 398 | 399 | 400 | :/img/src/blur_on_72px.png:/img/src/blur_on_72px.png 401 | 402 | 403 | 高斯模糊 404 | 405 | 406 | 407 | 408 | 中值滤波 409 | 410 | 411 | 412 | 413 | 拉普拉斯锐化 414 | 415 | 416 | 417 | 418 | Sobel 边缘检测 419 | 420 | 421 | 422 | 423 | 二值化 424 | 425 | 426 | 427 | 428 | Prewitt 边缘检测 429 | 430 | 431 | 432 | 433 | 轮廓提取 434 | 435 | 436 | 437 | 438 | 边缘跟踪 439 | 440 | 441 | 442 | 443 | Area 444 | 445 | 446 | 447 | 448 | Circumference 449 | 450 | 451 | 452 | 453 | 腐蚀 454 | 455 | 456 | 457 | 458 | 膨胀 459 | 460 | 461 | 462 | 463 | 开运算 464 | 465 | 466 | 467 | 468 | 闭运算 469 | 470 | 471 | 472 | 473 | 细化处理 474 | 475 | 476 | 477 | 478 | Equalization 479 | 480 | 481 | 482 | 483 | 旋转 484 | 485 | 486 | 487 | 488 | 489 | 490 | GraphicsView 491 | QWidget 492 |
graphicsview.h
493 |
494 |
495 | 496 | 497 | 498 | 499 |
500 | -------------------------------------------------------------------------------- /src/res/Line_Chart_72px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/Line_Chart_72px.png -------------------------------------------------------------------------------- /src/res/Open_folder_full_48px_1186194_easyicon.net.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/Open_folder_full_48px_1186194_easyicon.net.png -------------------------------------------------------------------------------- /src/res/about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res/blur_on_72px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/blur_on_72px.png -------------------------------------------------------------------------------- /src/res/brightness.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res/chinese.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/chinese.png -------------------------------------------------------------------------------- /src/res/clear.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res/cn.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/cn.qm -------------------------------------------------------------------------------- /src/res/default.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | frame_3.png 4 | frame_1.png 5 | frame_2.png 6 | logo_1.png 7 | logo_2.png 8 | metal.png 9 | chinese.png 10 | english.png 11 | right.png 12 | horizontal.png 13 | vertical.png 14 | left.png 15 | restore.png 16 | histogram.png 17 | brightness.svg 18 | save.svg 19 | zoom.png 20 | lineGrey.gif 21 | quill_72px.png 22 | log.png 23 | fun_exp.png 24 | line_graphic_72p.png 25 | Line_Chart_72px.png 26 | temperature_72px.png 27 | blur_on_72px.png 28 | open.svg 29 | clear.svg 30 | about.svg 31 | 32 | 33 | cn.qm 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/res/english.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/english.png -------------------------------------------------------------------------------- /src/res/frame_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/frame_1.png -------------------------------------------------------------------------------- /src/res/frame_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/frame_2.png -------------------------------------------------------------------------------- /src/res/frame_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/frame_3.png -------------------------------------------------------------------------------- /src/res/fun_exp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/fun_exp.png -------------------------------------------------------------------------------- /src/res/histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/histogram.png -------------------------------------------------------------------------------- /src/res/horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/horizontal.png -------------------------------------------------------------------------------- /src/res/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/left.png -------------------------------------------------------------------------------- /src/res/lineGrey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/lineGrey.gif -------------------------------------------------------------------------------- /src/res/line_graphic_72p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/line_graphic_72p.png -------------------------------------------------------------------------------- /src/res/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/log.png -------------------------------------------------------------------------------- /src/res/logo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/logo_1.png -------------------------------------------------------------------------------- /src/res/logo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/logo_2.png -------------------------------------------------------------------------------- /src/res/metal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/metal.png -------------------------------------------------------------------------------- /src/res/open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res/quill_72px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/quill_72px.png -------------------------------------------------------------------------------- /src/res/restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/restore.png -------------------------------------------------------------------------------- /src/res/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/right.png -------------------------------------------------------------------------------- /src/res/save.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/res/temperature_72px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/temperature_72px.png -------------------------------------------------------------------------------- /src/res/vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/vertical.png -------------------------------------------------------------------------------- /src/res/zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/my3rs/ImageQt/d6b9cdc215c2f7bb178944c58d73ffe2e3f60a8e/src/res/zoom.png -------------------------------------------------------------------------------- /src/src.pro: -------------------------------------------------------------------------------- 1 | QT += core gui concurrent 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport 4 | 5 | TARGET = imViewer 6 | TEMPLATE = app 7 | CONFIG += C++11 8 | 9 | TEMPLATE = app 10 | 11 | INCLUDEPATH += ./ \ 12 | dialog/ \ 13 | utils/ \ 14 | mainwindow/ 15 | 16 | HEADERS += dialog/dialog_exp_transform.h \ 17 | dialog/dialog_linear_gray.h \ 18 | dialog/dialog_log_grey.h \ 19 | dialog/dialog_power_grey.h \ 20 | dialog/dialog_stretch_transform.h \ 21 | dialog/dialog_two_threshold_transform.h \ 22 | mainwindow/mainwindow.h \ 23 | mainwindow/graphicsview.h \ 24 | dialog/dialog_gaussianblur.h \ 25 | mainwindow/graphicsview.h \ 26 | utils/histogram.h \ 27 | utils/medianfilter.h \ 28 | utils/tools.h \ 29 | utils/qcustomplot.h \ 30 | 31 | 32 | 33 | SOURCES += dialog/dialog_exp_transform.cpp \ 34 | dialog/dialog_gaussianblur.cpp \ 35 | dialog/dialog_linear_gray.cpp \ 36 | dialog/dialog_log_grey.cpp \ 37 | dialog/dialog_power_grey.cpp \ 38 | dialog/dialog_stretch_transform.cpp \ 39 | dialog/dialog_two_threshold_transform.cpp \ 40 | mainwindow/mainwindow.cpp \ 41 | mainwindow/graphicsview.cpp \ 42 | utils/gaussianblur.cpp \ 43 | utils/histogram.cpp \ 44 | utils/medianfilter.cpp \ 45 | utils/qcustomplot.cpp \ 46 | utils/tools.cpp \ 47 | main.cpp 48 | 49 | FORMS += mainwindow/mainwindow.ui \ 50 | dialog/gaussianblurdialog.ui \ 51 | dialog/dialog_linear_gray.ui \ 52 | dialog/dialog_log_grey.ui \ 53 | dialog/dialog_power_grey.ui \ 54 | dialog/dialog_exp_transform.ui \ 55 | dialog/dialog_two_threshold_transform.ui \ 56 | dialog/dialog_stretch_transform.ui 57 | 58 | RESOURCES += \ 59 | res/default.qrc 60 | 61 | TRANSLATIONS += res/cn.ts 62 | -------------------------------------------------------------------------------- /src/utils/gaussianblur.cpp: -------------------------------------------------------------------------------- 1 | #define _USE_MATH_DEFINES 2 | #include "gaussianblur.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | GaussianBlur::GaussianBlur(int blurRadius, double sigma) : 10 | mBlurRadius(blurRadius), 11 | mSigma(sigma) 12 | { 13 | CreateConvolutionMatrix(); 14 | } 15 | 16 | QImage GaussianBlur::BlurImage(const QImage& in) 17 | { 18 | if(in.isNull()) 19 | return QImage(); 20 | 21 | QImage image(in.size(), in.format()); 22 | 23 | int matrixSize = mConvolutionMatrix.size(); 24 | int halfMatrixSize = matrixSize / 2; 25 | 26 | float sumRed = 0.0f; 27 | float sumBlue = 0.0f; 28 | float sumGreen = 0.0f; 29 | float matrixValue = 0.0f; 30 | int x1 = 0, y1 = 0; 31 | 32 | for (int x = 0; x < in.width(); ++x) 33 | { 34 | for (int y = 0; y < in.height(); ++y) 35 | { 36 | for (int kx = -halfMatrixSize; kx <= halfMatrixSize; ++kx) 37 | { 38 | x1 = ReflectIndex(x - kx, in.width()); 39 | 40 | QColor color(in.pixel(x1, y)); 41 | 42 | matrixValue = mConvolutionMatrix[kx + halfMatrixSize]; 43 | 44 | sumRed += color.red() * matrixValue; 45 | sumBlue += color.blue() * matrixValue; 46 | sumGreen += color.green() * matrixValue; 47 | } 48 | 49 | QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue); 50 | image.setPixel(x, y, finalColor); 51 | 52 | sumRed = sumGreen = sumBlue = 0.0f; 53 | } 54 | } 55 | 56 | for (int x = 0; x < in.width(); ++x) 57 | { 58 | for (int y = 0; y < in.height(); ++y) 59 | { 60 | for (int ky = -halfMatrixSize; ky <= halfMatrixSize; ++ky) 61 | { 62 | y1 = ReflectIndex(y - ky, in.height()); 63 | 64 | QColor color(image.pixel(x, y1)); 65 | matrixValue = mConvolutionMatrix[ky + halfMatrixSize]; 66 | 67 | sumRed += color.red() * matrixValue; 68 | sumBlue += color.blue() * matrixValue; 69 | sumGreen += color.green() * matrixValue; 70 | } 71 | 72 | QRgb finalColor = qRgb(sumRed, sumGreen, sumBlue); 73 | image.setPixel(x, y, finalColor); 74 | 75 | sumRed = sumGreen = sumBlue = 0.0f; 76 | } 77 | } 78 | 79 | return image; 80 | } 81 | 82 | float GaussianBlur::GaussFunc(float x) 83 | { 84 | // Gaussian function in one dimension 85 | return (1 / sqrtf(2*M_PI * mSigma * mSigma)) * 86 | exp(-(x*x)/(2*mSigma*mSigma)); 87 | } 88 | 89 | void GaussianBlur::CreateConvolutionMatrix() 90 | { 91 | int x = 0; 92 | size_t matrixSize, halfMatrixSize; 93 | 94 | matrixSize = (size_t)(2*mBlurRadius + 1); 95 | halfMatrixSize = matrixSize / 2; 96 | 97 | mConvolutionMatrix.resize(matrixSize); 98 | 99 | vector::iterator begin = mConvolutionMatrix.begin(); 100 | vector::iterator end = mConvolutionMatrix.end(); 101 | 102 | x = -(int)halfMatrixSize; 103 | std::for_each(begin, end, 104 | [&] (float& val) mutable 105 | { 106 | val = GaussFunc(x); 107 | x++; 108 | }); 109 | 110 | // normalize the values in the convolution matrix 111 | float sum = std::accumulate(begin, end, 0.0f); 112 | 113 | std::for_each(begin, end, [&] (float& val) { val /= sum; }); 114 | } 115 | 116 | int GaussianBlur::ReflectIndex(int x, int length) 117 | { 118 | if (x < 0) 119 | return -x - 1; 120 | else if(x >= length) 121 | return 2*length - x - 1; 122 | 123 | return x; 124 | } 125 | 126 | float GaussianBlur::getSigma() const 127 | { 128 | return mSigma; 129 | } 130 | 131 | void GaussianBlur::setSigma(float value) 132 | { 133 | mSigma = value; 134 | CreateConvolutionMatrix(); 135 | } 136 | 137 | int GaussianBlur::getBlurRadius() const 138 | { 139 | return mBlurRadius; 140 | } 141 | 142 | void GaussianBlur::setBlurRadius(int value) 143 | { 144 | mBlurRadius = value; 145 | CreateConvolutionMatrix(); 146 | } 147 | 148 | GaussianBlur::~GaussianBlur() 149 | { 150 | } 151 | -------------------------------------------------------------------------------- /src/utils/gaussianblur.h: -------------------------------------------------------------------------------- 1 | #ifndef GAUSSIANBLUR_H 2 | #define GAUSSIANBLUR_H 3 | 4 | #include 5 | 6 | #include "qcolor.h" 7 | #include "qimage.h" 8 | 9 | using std::vector; 10 | 11 | class GaussianBlur 12 | { 13 | 14 | public: 15 | GaussianBlur(int blurRadius, double sigma); 16 | 17 | QImage BlurImage(const QImage& in); 18 | 19 | float GaussFunc(float x); 20 | 21 | int getBlurRadius() const; 22 | void setBlurRadius(int value); 23 | 24 | float getSigma() const; 25 | void setSigma(float value); 26 | 27 | ~GaussianBlur(); 28 | 29 | private: 30 | 31 | vector mConvolutionMatrix; 32 | 33 | int ReflectIndex(int x, int length); 34 | void CreateConvolutionMatrix(); 35 | 36 | int mBlurRadius; 37 | float mSigma; 38 | }; 39 | 40 | #endif // GAUSSIANBLUR_H 41 | -------------------------------------------------------------------------------- /src/utils/histogram.cpp: -------------------------------------------------------------------------------- 1 | #include "histogram.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | Histogram::Histogram(QWidget * parent) : QLabel(parent) 8 | { 9 | for(int i = 0;i<256;i++) 10 | { 11 | bwHstgrm[i] = 0; 12 | redHstgrm[i] = 0; 13 | greenHstgrm[i] = 0; 14 | blueHstgrm[i] = 0; 15 | } 16 | 17 | bwHstgrm[256] = -1; 18 | redHstgrm[256] = -1; 19 | greenHstgrm[256] = -1; 20 | blueHstgrm[256] = -1; 21 | 22 | redHstgrm[257] = 0; 23 | greenHstgrm[257] = 0; 24 | blueHstgrm[257] = 0; 25 | 26 | bwHstgrm[257] = 0; 27 | bwHstgrm[258] = 0; 28 | } 29 | 30 | 31 | 32 | Histogram::Histogram(QWidget * parent, Histogram * hstgrm) : QLabel(parent) 33 | { 34 | for(int i = 0;i<258;i++) 35 | { 36 | bwHstgrm[i] = hstgrm->bwHstgrm[i]; 37 | redHstgrm[i] = hstgrm->redHstgrm[i]; 38 | greenHstgrm[i] = hstgrm->greenHstgrm[i]; 39 | blueHstgrm[i] = hstgrm->blueHstgrm[i]; 40 | } 41 | 42 | bwHstgrm[258] = hstgrm->bwHstgrm[258]; 43 | } 44 | 45 | 46 | 47 | void Histogram::computeHstgrm(QImage img) 48 | { 49 | if (!img.isNull()) 50 | { 51 | for(int i = 0;i= 0 && index <= 258) 373 | return bwHstgrm[index]; 374 | else 375 | return -2; 376 | } 377 | 378 | 379 | 380 | int Histogram::getRedHstgrm(int index) 381 | { 382 | if (index >= 0 && index <= 257) 383 | return redHstgrm[index]; 384 | else 385 | return -2; 386 | } 387 | 388 | 389 | 390 | int Histogram::getGreenHstgrm(int index) 391 | { 392 | if (index >= 0 && index <= 257) 393 | return greenHstgrm[index]; 394 | else 395 | return -2; 396 | } 397 | 398 | 399 | 400 | int Histogram::getBlueHstgrm(int index) 401 | { 402 | if (index >= 0 && index <= 257) 403 | return blueHstgrm[index]; 404 | else 405 | return -2; 406 | } 407 | 408 | 409 | -------------------------------------------------------------------------------- /src/utils/histogram.h: -------------------------------------------------------------------------------- 1 | #ifndef HISTOGRAM_H 2 | #define HISTOGRAM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Histogram : public QLabel 10 | { 11 | public: 12 | Histogram(QWidget* parent = nullptr); 13 | Histogram(QWidget*, Histogram*); 14 | 15 | void computeHstgrm(QImage img); 16 | void paintEvent(QPaintEvent *e); 17 | void drawBwHstgrm(int xBase, int yBase, int height); 18 | void drawRedHstgrm(int xBase, int yBase, int height); 19 | void drawGreenHstgrm(int xBase, int yBase, int height); 20 | void drawBlueHstgrm(int xBase, int yBase, int height); 21 | int getBwHstgrm(int index); 22 | int getRedHstgrm(int index); 23 | int getGreenHstgrm(int index); 24 | int getBlueHstgrm(int index); 25 | 26 | private: 27 | // index 0 to 255 => count of image's pixels for this value 28 | // index 256 => maximum value 29 | // index 257 => total value of the dark component 30 | // index 258 => total value of the light component 31 | int bwHstgrm[259]; 32 | 33 | // index 0 to 255 => count of image's pixels for this value 34 | // index 256 => maximum value 35 | // index 257 => total value of the component 36 | int redHstgrm[258]; 37 | int greenHstgrm[258]; 38 | int blueHstgrm[258]; 39 | }; 40 | 41 | #endif // HISTOGRAM_H 42 | -------------------------------------------------------------------------------- /src/utils/medianfilter.cpp: -------------------------------------------------------------------------------- 1 | #include "medianfilter.h" 2 | #include 3 | 4 | MedianFilter* MedianFilter::mfStatic = NULL; 5 | 6 | MedianFilter::MedianFilter(QObject *parent) : QObject(parent) 7 | { 8 | mfStatic = this; 9 | image = NULL; 10 | extensionImage = NULL; 11 | resImage = NULL; 12 | futureWatcher = new QFutureWatcher(this); 13 | progressDialog = new QProgressDialog(NULL); 14 | connect(futureWatcher, SIGNAL(progressValueChanged(int)), progressDialog, SLOT(setValue(int))); 15 | connect(futureWatcher, SIGNAL(progressRangeChanged(int,int)), progressDialog, SLOT(setRange(int,int))); 16 | connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelMedianFilter())); 17 | } 18 | 19 | MedianFilter::~MedianFilter() 20 | { 21 | if (futureWatcher->isRunning()) 22 | { 23 | futureWatcher->cancel(); 24 | futureWatcher->waitForFinished(); 25 | } 26 | 27 | if(extensionImage) 28 | delete [] extensionImage; 29 | } 30 | 31 | void MedianFilter::cancelMedianFilter() 32 | { 33 | if (futureWatcher->isRunning()) 34 | { 35 | futureWatcher->cancel(); 36 | futureWatcher->waitForFinished(); 37 | } 38 | } 39 | 40 | void getResPixelValueST(IndexPair &p) 41 | { 42 | MedianFilter::mfStatic->getResPixelValue(p); 43 | } 44 | 45 | void MedianFilter::getResPixelValue(IndexPair &p) 46 | { 47 | int k = 0, workingWeight = originImageweight+2*radius; 48 | element window[windowSize]; 49 | 50 | for (int i = p.i - radius; i < p.i + radius+1; i++) 51 | { 52 | for (int j = p.j - radius; j < p.j + radius + 1; j++) 53 | window[k++] = this->extensionImage[i * (workingWeight) + j]; 54 | } 55 | 56 | for (int j = 0; j <= windowSizeHalf; j++) 57 | { 58 | int min = j; 59 | for (int l = j + 1; l < windowSize; l++) 60 | if (window[l] < window[min]) 61 | min = l; 62 | const element el = window[j]; 63 | window[j] = window[min]; 64 | window[min] = el; 65 | } 66 | 67 | resImage[(p.i - radius) * originImageweight + (p.j - radius)] = window[windowSizeHalf]; 68 | } 69 | 70 | void MedianFilter::applyMedianFilter(element *i, element *res, const int imageHeight, const int imageWidth, const int r) 71 | { 72 | if (!i || imageHeight < 1 || imageWidth < 1) 73 | return; 74 | 75 | if (futureWatcher->isRunning()) 76 | { 77 | futureWatcher->cancel(); 78 | futureWatcher->waitForFinished(); 79 | } 80 | 81 | this->originImageweight = imageWidth; 82 | this->radius = r; 83 | image = i; 84 | 85 | int extWidth = imageWidth + 2*radius, extHeight = imageHeight + 2*radius; 86 | this->windowSize = (2*radius+1) * (2*radius+1); 87 | this->windowSizeHalf = windowSize/2; 88 | 89 | extensionImage = new element[extWidth * extHeight]; 90 | if (!extensionImage) 91 | return; 92 | resImage = res; 93 | 94 | //Init working extented image 95 | for (int i = 0; i < imageHeight; i++) 96 | { 97 | //memcpy(extensionImage + (w + 2) * (i + 1) + 1, image + w * i, w * sizeof(element)); 98 | //extensionImage[(w + 2) * (i + 1)] = image[w * i]; //first cells on the line 99 | //extensionImage[(w + 2) * (i + 2) - 1] = image[w * (i + 1) - 1]; 100 | memcpy(extensionImage + extWidth * (i + radius) + radius, image + imageWidth * i, imageWidth * sizeof(element)); 101 | memcpy(extensionImage + extWidth * (i + radius), image + (imageWidth * i), radius * sizeof(element)); //first cells on the line 102 | memcpy(extensionImage + (extWidth * (i + radius + 1) - radius), image + imageWidth * (i + 1) - radius, radius * sizeof(element)); 103 | } 104 | 105 | for(int i = 0; i < radius; i++) 106 | { 107 | memcpy(extensionImage + i * extWidth, extensionImage + extWidth * (i + imageHeight - 1), extWidth * sizeof(element)); //first lines of the window 108 | memcpy(extensionImage + extWidth * (imageHeight + radius + i), extensionImage + extWidth * (imageHeight + radius - i - 1), extWidth * sizeof(element)); //last lines 109 | //qDebug()< indexes; 116 | for (int i = radius; i < imageHeight + radius; i++) 117 | { for (int j = radius; j < imageWidth + radius; j++) 118 | { 119 | IndexPair p(i,j); 120 | indexes<setFuture(QtConcurrent::map(indexes, getResPixelValueST)); 125 | progressDialog->exec(); 126 | futureWatcher->waitForFinished(); 127 | 128 | } 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/utils/medianfilter.h: -------------------------------------------------------------------------------- 1 | #ifndef MEDIANFILTER_H 2 | #define MEDIANFILTER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef int element; 9 | #define MAX_FILTER_RADIUS 30 10 | 11 | struct IndexPair{ 12 | int i, j; 13 | IndexPair(int a, int b) 14 | { 15 | i = a; j = b; 16 | } 17 | }; 18 | 19 | class MedianFilter : public QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | static MedianFilter *mfStatic; 24 | explicit MedianFilter(QObject *parent = 0); 25 | ~MedianFilter(); 26 | void applyMedianFilter(element *i, element *res, const int imageHeight, const int imageWidth, const int r); 27 | void getResPixelValue(IndexPair &p); 28 | public slots: 29 | void cancelMedianFilter(); 30 | private: 31 | element *image, *extensionImage, *resImage; 32 | int originImageweight, radius, windowSize, windowSizeHalf; 33 | QFutureWatcher *futureWatcher; 34 | QProgressDialog *progressDialog; 35 | }; 36 | 37 | #endif // MEDIANFILTER_H 38 | -------------------------------------------------------------------------------- /src/utils/tools.cpp: -------------------------------------------------------------------------------- 1 | #include "tools.h" 2 | #include "medianfilter.h" 3 | 4 | #define min2(a,b) (a)<(b)?(a):(a) 5 | #define min(a,b,c) (min2(a,b))<(c)?(min2(a,b)):(c) 6 | 7 | 8 | /***************************************************************************** 9 | * Greyscale 10 | * **************************************************************************/ 11 | QImage Tools::GreyScale(QImage origin) 12 | { 13 | QImage *newImage = new QImage(origin.width(), origin.height(), 14 | QImage::Format_ARGB32); 15 | QColor oldColor; 16 | 17 | for (int x=0; xwidth(); x++) { 18 | for (int y=0; yheight(); y++) { 19 | oldColor = QColor(origin.pixel(x,y)); 20 | int average = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 21 | newImage->setPixel(x,y,qRgb(average,average,average)); 22 | } 23 | } 24 | 25 | return *newImage; 26 | 27 | } 28 | 29 | /***************************************************************************** 30 | * Adjust color temperature 31 | * **************************************************************************/ 32 | QImage Tools::Warm(int delta, QImage origin) 33 | { 34 | QImage *newImage = new QImage(origin.width(), origin.height(), 35 | QImage::Format_ARGB32); 36 | 37 | QColor oldColor; 38 | int r, g, b; 39 | 40 | for (int x=0; xwidth(); x++) 41 | { 42 | for (int y=0; yheight(); y++) 43 | { 44 | oldColor = QColor(origin.pixel(x,y)); 45 | 46 | r = oldColor.red() + delta; 47 | g = oldColor.green() + delta; 48 | b = oldColor.blue(); 49 | // qDebug()<setPixel(x,y, qRgb(r,g,b)); 56 | } 57 | } 58 | return *newImage; 59 | } 60 | 61 | QImage Tools::Cool(int delta, QImage origin) 62 | { 63 | QImage *newImage = new QImage(origin.width(), origin.height(), 64 | QImage::Format_ARGB32); 65 | 66 | QColor oldColor; 67 | int r, g, b; 68 | 69 | for (int x=0; xwidth(); x++) 70 | { 71 | for (int y=0; yheight(); y++) 72 | { 73 | oldColor = QColor(origin.pixel(x,y)); 74 | 75 | r = oldColor.red(); 76 | g = oldColor.green(); 77 | b = oldColor.blue() + delta; 78 | 79 | // Check if the new values are between 0 and 255 80 | r = qBound(0, r, 255); 81 | g = qBound(0, g, 255); 82 | 83 | newImage->setPixel(x,y, qRgb(r,g,b)); 84 | } 85 | } 86 | return *newImage; 87 | } 88 | 89 | 90 | 91 | /***************************************************************************** 92 | * Adjust image brightness 93 | * **************************************************************************/ 94 | QImage Tools::Brightness(int delta, QImage origin) 95 | { 96 | QImage *newImage = new QImage(origin.width(), origin.height(), 97 | QImage::Format_ARGB32); 98 | 99 | QColor oldColor; 100 | int r, g, b; 101 | 102 | for (int x=0; xwidth(); x++) 103 | { 104 | for (int y=0; yheight(); y++) 105 | { 106 | oldColor = QColor(origin.pixel(x,y)); 107 | 108 | r = oldColor.red() + delta; 109 | g = oldColor.green() + delta; 110 | b = oldColor.blue() + delta; 111 | 112 | // Check if the new values are between 0 and 255 113 | r = qBound(0, r, 255); 114 | g = qBound(0, g, 255); 115 | b = qBound(0, b, 255); 116 | 117 | newImage->setPixel(x,y, qRgb(r,g,b)); 118 | } 119 | } 120 | return *newImage; 121 | } 122 | 123 | /***************************************************************************** 124 | * Flip 125 | * **************************************************************************/ 126 | QImage Tools::Horizontal(const QImage &origin) 127 | { 128 | QImage *newImage = new QImage(QSize(origin.width(), origin.height()), 129 | QImage::Format_ARGB32); 130 | QColor tmpColor; 131 | int r, g, b; 132 | for (int x=0; xwidth(); x++) 133 | { 134 | for (int y=0; yheight(); y++) 135 | { 136 | tmpColor = QColor(origin.pixel(x, y)); 137 | r = tmpColor.red(); 138 | g = tmpColor.green(); 139 | b = tmpColor.blue(); 140 | 141 | newImage->setPixel(newImage->width()-x-1,y, qRgb(r,g,b)); 142 | 143 | } 144 | } 145 | return *newImage; 146 | } 147 | 148 | QImage Tools::Vertical(const QImage &origin) 149 | { 150 | QImage *newImage = new QImage(QSize(origin.width(), origin.height()), 151 | QImage::Format_ARGB32); 152 | QColor tmpColor; 153 | int r, g, b; 154 | for (int x=0; xwidth(); x++) 155 | { 156 | for (int y=0; yheight(); y++) 157 | { 158 | tmpColor = QColor(origin.pixel(x, y)); 159 | r = tmpColor.red(); 160 | g = tmpColor.green(); 161 | b = tmpColor.blue(); 162 | 163 | newImage->setPixel(x, newImage->height()-y-1, qRgb(r,g,b)); 164 | 165 | } 166 | } 167 | return *newImage; 168 | } 169 | 170 | 171 | 172 | 173 | 174 | /***************************************************************************** 175 | * 添加相框 176 | * **************************************************************************/ 177 | QImage Tools::DrawFrame(QImage origin, QImage &frame) 178 | { 179 | QImage *newImage = new QImage(origin); 180 | QPainter painter; 181 | 182 | int width = origin.width(); 183 | int height = origin.height(); 184 | 185 | QImage tmpFrame = frame.scaled(QSize(width, height)); 186 | 187 | painter.begin(newImage); 188 | painter.drawImage(0, 0, tmpFrame); 189 | painter.end(); 190 | 191 | return *newImage; 192 | 193 | } 194 | 195 | /***************************************************************************** 196 | * 线性灰度变换 y = ax + b 197 | * **************************************************************************/ 198 | QImage Tools::LinearLevelTransformation(const QImage &origin, double _a, double _b) 199 | { 200 | QImage *newImage = new QImage(origin.width(), origin.height(), 201 | QImage::Format_ARGB32); 202 | QColor oldColor; 203 | int grayLevel = 0; 204 | 205 | for (int x=0; xwidth(); x++) { 206 | for (int y=0; yheight(); y++) { 207 | oldColor = QColor(origin.pixel(x,y)); 208 | grayLevel = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 209 | int _y = _a*grayLevel + _b; 210 | // Make sure that the new values are between 0 and 255 211 | _y = qBound(0, _y, 255); 212 | 213 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 214 | } 215 | } 216 | // qDebug()<<"a:"<<_a<<"\tb:"<<_b; 217 | 218 | return *newImage; 219 | } 220 | 221 | 222 | /***************************************************************************** 223 | * 对数灰度变换 224 | * **************************************************************************/ 225 | QImage Tools::LogGreyLevelTransformation(const QImage &origin, double a, double b) 226 | { 227 | QImage *newImage = new QImage(origin.width(), origin.height(), 228 | QImage::Format_ARGB32); 229 | QColor oldColor; 230 | int grayLevel = 0; 231 | 232 | for (int x=0; xwidth(); x++) { 233 | for (int y=0; yheight(); y++) { 234 | oldColor = QColor(origin.pixel(x,y)); 235 | grayLevel = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 236 | int _y = qLn(b+grayLevel)/qLn(a); 237 | 238 | // Make sure that the new values are between 0 and 255 239 | _y = qBound(0, _y, 255); 240 | 241 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 242 | } 243 | } 244 | 245 | return *newImage; 246 | } 247 | 248 | 249 | /***************************************************************************** 250 | * 幂次灰度变换 _y=c*_x^r+b 251 | * **************************************************************************/ 252 | QImage Tools::PowerGreyLevelTransformation(const QImage &origin, double c, double r, double b) 253 | { 254 | QImage *newImage = new QImage(origin.width(), origin.height(), 255 | QImage::Format_ARGB32); 256 | QColor oldColor; 257 | int _x = 0; 258 | 259 | for (int x=0; xwidth(); x++) { 260 | for (int y=0; yheight(); y++) { 261 | oldColor = QColor(origin.pixel(x,y)); 262 | _x = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 263 | int _y =c*qPow(_x, r)+b; 264 | 265 | // Make sure that the new values are between 0 and 255 266 | _y = qBound(0, _y, 255); 267 | 268 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 269 | } 270 | } 271 | 272 | return *newImage; 273 | } 274 | 275 | 276 | /***************************************************************************** 277 | * 指数灰度变换 278 | * **************************************************************************/ 279 | QImage Tools::ExpTransform(const QImage &origin, double b, double c, double a) 280 | { 281 | QImage *newImage = new QImage(origin.width(), origin.height(), 282 | QImage::Format_ARGB32); 283 | QColor oldColor; 284 | int _x = 0; 285 | 286 | for (int x=0; xwidth(); x++) { 287 | for (int y=0; yheight(); y++) { 288 | oldColor = QColor(origin.pixel(x,y)); 289 | _x = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 290 | int _y =qPow(b, c*(_x-a)); 291 | 292 | // Make sure that the new values are between 0 and 255 293 | _y = qBound(0, _y, 255); 294 | 295 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 296 | } 297 | } 298 | 299 | return *newImage; 300 | } 301 | 302 | /***************************************************************************** 303 | * 双阈值灰度变换 304 | * int option: 305 | * 0 0-255-0 306 | * 1 255-0-255 307 | * **************************************************************************/ 308 | QImage Tools::TwoThreshold(const QImage &origin, double t1, double t2, int option) 309 | { 310 | QImage *newImage = new QImage(origin.width(), origin.height(), 311 | QImage::Format_ARGB32); 312 | QColor oldColor; 313 | int _x = 0; 314 | int _y = 0; 315 | if (option == 0) 316 | { 317 | for (int x=0; xwidth(); x++) { 318 | for (int y=0; yheight(); y++) { 319 | oldColor = QColor(origin.pixel(x,y)); 320 | _x = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 321 | 322 | if (_x < t1 || _x > t2) 323 | _y = 0; 324 | else 325 | _y = 255; 326 | 327 | 328 | // Make sure that the new values are between 0 and 255 329 | _y = qBound(0, _y, 255); 330 | 331 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 332 | } 333 | } 334 | } 335 | else 336 | { 337 | for (int x=0; xwidth(); x++) { 338 | for (int y=0; yheight(); y++) { 339 | oldColor = QColor(origin.pixel(x,y)); 340 | _x = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 341 | 342 | if (_x>=t1 && _x<=t2) 343 | _y = 0; 344 | else 345 | _y = 255; 346 | 347 | 348 | // Make sure that the new values are between 0 and 255 349 | _y = qBound(0, _y, 255); 350 | 351 | newImage->setPixel(x,y,qRgb(_y,_y,_y)); 352 | } 353 | } 354 | } 355 | 356 | return *newImage; 357 | } 358 | 359 | 360 | 361 | /***************************************************************************** 362 | * 拉伸灰度变换 363 | * 拉伸变换使用一个分段函数,三个k值 364 | * **************************************************************************/ 365 | QImage Tools::StretchTransform(const QImage &origin, 366 | int x1, int x2, 367 | double k1, double k2, double k3, 368 | double b2, double b3) 369 | { 370 | QImage *newImage = new QImage(origin.width(), origin.height(), 371 | QImage::Format_ARGB32); 372 | QColor oldColor; 373 | int _x = 0; 374 | int _y = 0; 375 | 376 | for (int x=0; xwidth(); x++) { 377 | for (int y=0; yheight(); y++) { 378 | oldColor = QColor(origin.pixel(x,y)); 379 | _x = (oldColor.red()*299+oldColor.green()*587+oldColor.blue()*114+500)/1000; 380 | 381 | if ( _xsetPixel(x,y,qRgb(_y,_y,_y)); 393 | } 394 | } 395 | 396 | return *newImage; 397 | } 398 | 399 | 400 | /***************************************************************************** 401 | * 简单平滑处理 402 | * **************************************************************************/ 403 | QImage Tools::SimpleSmooth(const QImage &origin) 404 | { 405 | QImage *newImage = new QImage(origin); 406 | 407 | int kernel[5][5] = { 408 | {0,0,1,0,0}, 409 | {0,1,3,1,0}, 410 | {1,3,7,3,1}, 411 | {0,1,3,1,0}, 412 | {0,0,1,0,0} 413 | }; 414 | int kernelSize = 5; 415 | int sumKernel=27; 416 | int r,g,b; 417 | QColor color; 418 | 419 | for(int x=kernelSize/2; xwidth()-kernelSize/2; x++) 420 | { 421 | for (int y=kernelSize/2; yheight()-kernelSize/2; y++) 422 | { 423 | r = g = b = 0; 424 | for (int i=-kernelSize/2; i<=kernelSize/2; i++) 425 | { 426 | for (int j=-kernelSize/2; j<=kernelSize/2; j++) 427 | { 428 | color = QColor(origin.pixel(x+i,y+j)); 429 | r += color.red()*kernel[kernelSize/2+i][kernelSize/2+j]; 430 | g += color.green()*kernel[kernelSize/2+i][kernelSize/2+j]; 431 | b += color.blue()*kernel[kernelSize/2+i][kernelSize/2+j]; 432 | 433 | } 434 | } 435 | r = qBound(0, r/sumKernel, 255); 436 | g = qBound(0, g/sumKernel, 255); 437 | b = qBound(0, b/sumKernel, 255); 438 | 439 | newImage->setPixel(x,y,qRgb(r,g,b)); 440 | 441 | } 442 | } 443 | return *newImage; 444 | } 445 | 446 | 447 | /***************************************************************************** 448 | * 中值滤波 449 | * **************************************************************************/ 450 | QImage Tools::MeidaFilter(const QImage &origin, int filterRadius) 451 | { 452 | int imageHeight = origin.height(); 453 | int imageWidth = origin.width(); 454 | MedianFilter medianFilter; 455 | int* resImageBits = new int[imageHeight * imageWidth]; 456 | medianFilter.applyMedianFilter((int*)origin.bits(), resImageBits, imageHeight, imageWidth, filterRadius); 457 | 458 | QImage destImage((uchar*)resImageBits, imageWidth, imageHeight, origin.format()); 459 | // QPixmap pixRes; 460 | // pixRes.convertFromImage(destImage); 461 | 462 | 463 | return destImage; 464 | } 465 | 466 | 467 | /***************************************************************************** 468 | * 拉普拉斯锐化 469 | * **************************************************************************/ 470 | QImage Tools::LaplaceSharpen(const QImage &origin) 471 | { 472 | 473 | int width = origin.width(); 474 | int height = origin.height(); 475 | QImage newImage = QImage(width, height,QImage::Format_RGB888); 476 | int window[3][3] = {0,-1,0,-1,4,-1,0,-1,0}; 477 | 478 | for (int x=1; x=0 && mmax ? sobel_norm[x+y*width]:max; 570 | } 571 | } 572 | } 573 | 574 | for(int i=0;imax ? sobel_norm[x+y*width]:max; 627 | } 628 | } 629 | } 630 | 631 | for(int i=0;iBlurImage(origin); 651 | 652 | return newImage; 653 | } 654 | 655 | /***************************************************************************** 656 | * 二值化 657 | * **************************************************************************/ 658 | QImage Tools::Binaryzation(const QImage &origin) 659 | { 660 | 661 | 662 | int width = origin.width(); 663 | int height = origin.height(); 664 | QImage newImg = QImage(width, height, QImage::Format_RGB888); 665 | 666 | for (int x=0; x 128) 673 | newGray = 255; 674 | else 675 | newGray = 0; 676 | newImg.setPixel(x,y,qRgb(newGray, newGray, newGray)); 677 | } 678 | } 679 | return newImg; 680 | } 681 | 682 | 683 | /***************************************************************************** 684 | * 金属拉丝效果 685 | * **************************************************************************/ 686 | QImage Tools::Metal(QImage origin) 687 | { 688 | QImage *baseImage = new QImage(":/img/src/metal.png"); 689 | QImage darkImage = Tools::Brightness(-100, origin); 690 | QImage greyImage = Tools::GreyScale(darkImage); 691 | QPainter painter; 692 | 693 | QImage newImage = baseImage->scaled(QSize(origin.width(),origin.height())); 694 | 695 | painter.begin(&newImage); 696 | painter.setOpacity(0.5); 697 | painter.drawImage(0, 0, greyImage); 698 | painter.end(); 699 | 700 | return newImage; 701 | } 702 | 703 | 704 | /***************************************************************************** 705 | * 轮廓提取法 706 | * **************************************************************************/ 707 | QImage Tools::ContourExtraction(const QImage &origin) 708 | { 709 | int width = origin.width(); 710 | int height = origin.height(); 711 | int pixel[8]; // 当前像素周围的8个像素的像素值 712 | // int *pixel = new int[9]; 713 | QImage binImg = Binaryzation(origin); 714 | QImage newImg = QImage(width, height, QImage::Format_RGB888); 715 | newImg.fill(Qt::white); 716 | 717 | for(int y=1; y 128){ 770 | newImg.setPixel(x,y,qRgb(255,255,255)); 771 | } 772 | } 773 | } 774 | } 775 | } 776 | return newImg; 777 | } 778 | 779 | /***************************************************************************** 780 | * 全方位膨胀 781 | * **************************************************************************/ 782 | 783 | QImage Tools::Expansion(const QImage &origin) 784 | { 785 | int width = origin.width(); 786 | int height = origin.height(); 787 | QImage newImg = QImage(width, height, QImage::Format_RGB888); 788 | 789 | int dilateItem[9] = {1,0,1, 790 | 0,0,0, 791 | 1,0,1}; 792 | 793 | for (int x=1; x=0 && m 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "gaussianblur.h" 16 | 17 | 18 | namespace Tools { 19 | QImage GreyScale(QImage origin); 20 | QImage Warm(int delta, QImage origin); 21 | QImage Cool(int delta, QImage origin); 22 | QImage DrawFrame(QImage origin, QImage &frame); 23 | QImage Brightness(int delta, QImage origin); 24 | QImage Horizontal(const QImage &origin); 25 | QImage Vertical(const QImage &origin); 26 | QImage LinearLevelTransformation(const QImage &origin, double a, double b); 27 | QImage LogGreyLevelTransformation(const QImage &origin, double a, double b); 28 | QImage PowerGreyLevelTransformation(const QImage &origin, double c, double r, double b); 29 | QImage ExpTransform(const QImage &origin, double b, double c, double a); 30 | QImage TwoThreshold(const QImage &orogin, double t1, double t2, int option); 31 | QImage StretchTransform(const QImage &origin, 32 | int x1, int x2, 33 | double k1, double k2, double k3, 34 | double b2, double b3); 35 | QImage SimpleSmooth(const QImage &origin); 36 | QImage MeidaFilter(const QImage &origin, int radius); 37 | QImage LaplaceSharpen(const QImage &origin); 38 | QImage SobelEdge(const QImage &origin); 39 | QImage GaussianSmoothing(const QImage &origin, int radius, double sigma); 40 | QImage Binaryzation(const QImage &origin); 41 | QImage Metal(QImage origin); 42 | QImage PrewittEdge(const QImage &origin); 43 | QImage ContourExtraction(const QImage &origin); 44 | QImage Dilate(const QImage &origin); 45 | QImage Expansion(const QImage &origin); 46 | QImage Opening(const QImage &origin); 47 | QImage Closing(const QImage &origin); 48 | QImage Thinning(const QImage &origin); 49 | //QImage RGB2HSV(const QImage &origin); 50 | //QImage RGB2HSL(const QImage &origin); 51 | //QImage RGB2CMYK(const QImage &origin); 52 | QImage Final(const QImage &origin); 53 | } 54 | 55 | 56 | 57 | 58 | #endif // TOOLS_H 59 | --------------------------------------------------------------------------------