Permalink
Browse files

(from marklr) Drag & Drop + Visual Studio support

Added basic drag & drop, resolved compilation issues with Visual Studio
(wrapped in ifdefs).
  • Loading branch information...
1 parent a438512 commit b7be3ec1954c2bb1d01dfa8f0ac5384ef0d383b3 @Y-Vladimir committed Jul 17, 2012
Showing with 1,699 additions and 1,625 deletions.
  1. +67 −60 src/DeconvolutionTool.h
  2. +134 −132 src/ImageUtils.cpp
  3. +50 −43 src/ImageUtils.h
  4. +446 −410 src/MainWindow.cpp
  5. +116 −103 src/MainWindow.h
  6. +886 −877 src/MainWindow.ui
View
127 src/DeconvolutionTool.h
@@ -1,60 +1,67 @@
-#ifndef DECONVOLUTIONTHREAD_H
-#define DECONVOLUTIONTHREAD_H
-
-#include <QThread>
-#include <QDebug>
-#include <QImage>
-#include <QPainter>
-#include <QTime>
-#include <QThread>
-#include <QPixmap>
-#include <QObject>
-#include <time.h>
-#include <math.h>
-#include "ImageUtils.h"
-#if defined (Q_WS_WIN)
-#include "fftw3.h"
-#else
-#include <fftw3.h>
-#endif
-#include <typeinfo>
-
-
-class DeconvolutionTool : public QObject
-{
- Q_OBJECT
-
-public:
- DeconvolutionTool(QObject* parent = 0);
- void initFFT(const QImage *inputImage);
- void doDeconvolution(const QImage *inputImage, QImage *outputImage, const Blur *blur);
- int getThreadsCount();
-
-signals:
- void progressEvent(int);
-
-private:
- void visualizeFFT(fftw_complex *fft, const int WIDTH, const int HEIGHT, QString path);
- void multiplayFFTs(const fftw_complex *firstFFT, const fftw_complex *secondFFT, fftw_complex *outFFT, const int width, const int height);
- void deconvolutionByWiener(const fftw_complex *kernelFFT, const fftw_complex *inImageFFT, fftw_complex *outImageFFT, const int WIDTH, const int HEIGHT, const double K);
-
- void buildKernel(fftw_complex* outKernelFFT, const int WIDTH, const int HEIGHT, const Blur *blur);
- void doDeconvolutionForChannel(const QImage *inputImage, QImage *outputImage, const fftw_complex *kernelMatrixFFT, const int width, const int height, const double kernelRadius, const double PSNR, const CurrentChannel channel);
-
- int width, height;
- int threadsCount;
-
- fftw_complex *inputMatrix;
- fftw_complex *outputMatrix;
- fftw_complex *kernelMatrix;
- fftw_complex *inputMatrixFFT;
- fftw_complex *kernelMatrixFFT;
-
- fftw_plan forwardImagePlan;
- fftw_plan forwardKernelPlan;
- fftw_plan backwardImagePlan;
-};
-
-
-
-#endif // DECONVOLUTIONTHREAD_H
+#ifndef DECONVOLUTIONTHREAD_H
+#define DECONVOLUTIONTHREAD_H
+
+#include <QThread>
+#include <QDebug>
+#include <QImage>
+#include <QPainter>
+#include <QTime>
+#include <QThread>
+#include <QPixmap>
+#include <QObject>
+#include <time.h>
+
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#include "ImageUtils.h"
+#if defined (Q_WS_WIN)
+#include "fftw3.h"
+#else
+#include <fftw3.h>
+#endif
+#include <typeinfo>
+
+
+class DeconvolutionTool : public QObject
+{
+ Q_OBJECT
+
+public:
+ DeconvolutionTool(QObject* parent = 0);
+ void initFFT(const QImage *inputImage);
+ void doDeconvolution(const QImage *inputImage, QImage *outputImage, const Blur *blur);
+ int getThreadsCount();
+
+signals:
+ void progressEvent(int);
+
+private:
+ void visualizeFFT(fftw_complex *fft, const int WIDTH, const int HEIGHT, QString path);
+ void multiplayFFTs(const fftw_complex *firstFFT, const fftw_complex *secondFFT, fftw_complex *outFFT, const int width, const int height);
+ void deconvolutionByWiener(const fftw_complex *kernelFFT, const fftw_complex *inImageFFT, fftw_complex *outImageFFT, const int WIDTH, const int HEIGHT, const double K);
+
+ void buildKernel(fftw_complex* outKernelFFT, const int WIDTH, const int HEIGHT, const Blur *blur);
+ void doDeconvolutionForChannel(const QImage *inputImage, QImage *outputImage, const fftw_complex *kernelMatrixFFT, const int width, const int height, const double kernelRadius, const double PSNR, const CurrentChannel channel);
+
+ int width, height;
+ int threadsCount;
+
+ fftw_complex *inputMatrix;
+ fftw_complex *outputMatrix;
+ fftw_complex *kernelMatrix;
+ fftw_complex *inputMatrixFFT;
+ fftw_complex *kernelMatrixFFT;
+
+ fftw_plan forwardImagePlan;
+ fftw_plan forwardKernelPlan;
+ fftw_plan backwardImagePlan;
+};
+
+
+
+#endif // DECONVOLUTIONTHREAD_H
View
266 src/ImageUtils.cpp
@@ -1,132 +1,134 @@
-#include "ImageUtils.h"
-
-QImage* ImageUtils::buildKernelImage(const FocusBlur* focusBlur) {
- double radius = focusBlur->radius;
- double edgeFeather = focusBlur->edgeFeather;
- double correctionStrength = focusBlur->correctionStrength;
-
- // Double radius plus 2*3 pixels to ensure that generated kernel will be fitted inside the image
- int size = 2 * radius + 6;
- size += size%2;
-
- QImage* kernelImage = new QImage(size, size, QImage::Format_RGB32);
- kernelImage->fill(Qt::black);
-
- // Prepare painter to have antialiasing and sub-pixel accuracy
- QPainter kernelPainter(kernelImage);
- kernelPainter.setRenderHint(QPainter::Antialiasing);
- kernelPainter.setBrush(QBrush(Qt::white));
-
- // Draw circle
- kernelPainter.drawEllipse(QPointF(0.5+kernelImage->width()/2.0, 0.5+kernelImage->height()/2.0), radius, radius);
- kernelPainter.end();
-
- // Draw edge correction - add ring (with radius=kernelRadiaus) blurred by Gauss to the drawed circle
- int center = size/2;
- for (int y = 0; y<size; y++) {
- for (int x = 0; x<size; x++) {
- double dist = sqrt(pow(x-center,2) + pow(y-center,2));
- if (dist <= radius) {
- double mu = radius;
- double sigma = radius*edgeFeather/100;
-
- // Gaussian normalized by kernelStrength
- double gaussValue = pow(M_E, -pow((dist-mu)/sigma,2)/2);
- gaussValue *= 255*(correctionStrength)/100;
-
- // Circle pixel value normalized by 1-kernelStrength
- int curValue = qRed(kernelImage->pixel(x,y));
- if (correctionStrength >= 0) {
- curValue *= (100-correctionStrength)/100;
- }
-
- // Sum and check
- curValue += gaussValue;
- if (curValue < 0) {
- curValue = 0;
- }
- if (curValue > 255) {
- curValue = 255;
- }
-
- kernelImage->setPixel(x,y,qRgb(curValue, curValue, curValue));
- }
- }
- }
-
-
- return kernelImage;
-}
-
-QImage *ImageUtils::buildKernelImage(const MotionBlur* motionBlur) {
- // motionLength plus 2*3 pixels to ensure that generated kernel will be fitted inside the image
- double motionLength = motionBlur->radius * 2;
- double motionAngle = motionBlur->angle;
-
- int size = motionLength + 6;
- size += size%2;
-
- QImage* kernelImage = new QImage(size, size, QImage::Format_RGB32);
- kernelImage->fill(Qt::black);
-
- // Prepare painter to have antialiasing and sub-pixel accuracy
- QPainter kernelPainter(kernelImage);
- kernelPainter.setRenderHint(QPainter::Antialiasing);
-
- // Workarround to have high accuracy, otherwise drawLine method has some micro-mistakes in the rendering
- QPen pen = kernelPainter.pen();
- pen.setColor(Qt::white);
- pen.setWidthF(1.01);
- kernelPainter.setPen(pen);
-
- double center = 0.5 + size/2;
- double motionAngleRad = M_PI*motionAngle/180;
- QLineF line(center - motionLength*cos(motionAngleRad)/2,
- center - motionLength*sin(motionAngleRad)/2,
- center + motionLength*cos(motionAngleRad)/2,
- center + motionLength*sin(motionAngleRad)/2);
- kernelPainter.drawLine(line);
- kernelPainter.end();
-
- return kernelImage;
-}
-
-void ImageUtils::fillInputMatrix(fftw_complex *inputMatrix, const QImage *inputImage, const int width, const int height, const CurrentChannel channel) {
- for (int y=0; y<height; y++) {
- QRgb *line = (QRgb*)inputImage->constScanLine(y);
- for (int x=0; x<width; x++) {
- int value = 0;
- switch (channel) {
- case RED: value = qRed(line[x]); break;
- case GREEN: value = qGreen(line[x]); break;
- case BLUE: value = qBlue(line[x]); break;
- case GRAY: value = qGray(line[x]); break;
- }
- inputMatrix[y*width + x][0] = centerFFTKoef(x, y) * value;
- }
- }
-}
-
-void ImageUtils::fillOutputImage(const QImage *inputImage, const fftw_complex *outputMatrix, QImage *outputImage, const int width, const int height, const CurrentChannel channel) {
- for (int y = 0; y < height; y++) {
- QRgb *line = (QRgb*) outputImage->scanLine(y);
- for (int x = 0; x < width; x++) {
- double value = outputMatrix[y*width + x][0] / (width * height);
- value *= centerFFTKoef(x, y);
- value = fabs(value);
- if (value < 0) {
- value = 0;
- }
- if (value > 255) {
- value = 255;
- }
-
- switch (channel) {
- case RED: line[x] = qRgb(value, 0, 0); break;
- case GREEN: line[x] = line[x] | qRgb(0, value, 0); break;
- case BLUE: line[x] = line[x] | qRgb(0, 0, value); break;
- case GRAY: line[x] = qRgb(value, value, value); break;
- }
- }
- }
-}
+#include "ImageUtils.h"
+
+QImage* ImageUtils::buildKernelImage(const FocusBlur* focusBlur) {
+ double radius = focusBlur->radius;
+ double edgeFeather = focusBlur->edgeFeather;
+ double correctionStrength = focusBlur->correctionStrength;
+
+ // Double radius plus 2*3 pixels to ensure that generated kernel will be fitted inside the image
+ int size = 2 * radius + 6;
+ size += size%2;
+
+ QImage* kernelImage = new QImage(size, size, QImage::Format_RGB32);
+ kernelImage->fill(Qt::black);
+
+ // Prepare painter to have antialiasing and sub-pixel accuracy
+ QPainter kernelPainter(kernelImage);
+ kernelPainter.setRenderHint(QPainter::Antialiasing);
+ kernelPainter.setBrush(QBrush(Qt::white));
+
+ // Draw circle
+ kernelPainter.drawEllipse(QPointF(0.5+kernelImage->width()/2.0, 0.5+kernelImage->height()/2.0), radius, radius);
+ kernelPainter.end();
+
+ // Draw edge correction - add ring (with radius=kernelRadiaus) blurred by Gauss to the drawed circle
+ int center = size/2;
+ for (int y = 0; y<size; y++) {
+ for (int x = 0; x<size; x++) {
+ double dist = pow((double)x-center,2) + pow((double)y-center,2);
+ dist = sqrt(dist);
+ if (dist <= radius) {
+ double mu = radius;
+ double sigma = radius*edgeFeather/100;
+
+ // Gaussian normalized by kernelStrength
+
+ double gaussValue = pow(M_E, -pow((dist-mu)/sigma,2)/2);
+ gaussValue *= 255*(correctionStrength)/100;
+
+ // Circle pixel value normalized by 1-kernelStrength
+ int curValue = qRed(kernelImage->pixel(x,y));
+ if (correctionStrength >= 0) {
+ curValue *= (100-correctionStrength)/100;
+ }
+
+ // Sum and check
+ curValue += gaussValue;
+ if (curValue < 0) {
+ curValue = 0;
+ }
+ if (curValue > 255) {
+ curValue = 255;
+ }
+
+ kernelImage->setPixel(x,y,qRgb(curValue, curValue, curValue));
+ }
+ }
+ }
+
+
+ return kernelImage;
+}
+
+QImage *ImageUtils::buildKernelImage(const MotionBlur* motionBlur) {
+ // motionLength plus 2*3 pixels to ensure that generated kernel will be fitted inside the image
+ double motionLength = motionBlur->radius * 2;
+ double motionAngle = motionBlur->angle;
+
+ int size = motionLength + 6;
+ size += size%2;
+
+ QImage* kernelImage = new QImage(size, size, QImage::Format_RGB32);
+ kernelImage->fill(Qt::black);
+
+ // Prepare painter to have antialiasing and sub-pixel accuracy
+ QPainter kernelPainter(kernelImage);
+ kernelPainter.setRenderHint(QPainter::Antialiasing);
+
+ // Workarround to have high accuracy, otherwise drawLine method has some micro-mistakes in the rendering
+ QPen pen = kernelPainter.pen();
+ pen.setColor(Qt::white);
+ pen.setWidthF(1.01);
+ kernelPainter.setPen(pen);
+
+ double center = 0.5 + size/2;
+ double motionAngleRad = M_PI*motionAngle/180;
+ QLineF line(center - motionLength*cos(motionAngleRad)/2,
+ center - motionLength*sin(motionAngleRad)/2,
+ center + motionLength*cos(motionAngleRad)/2,
+ center + motionLength*sin(motionAngleRad)/2);
+ kernelPainter.drawLine(line);
+ kernelPainter.end();
+
+ return kernelImage;
+}
+
+void ImageUtils::fillInputMatrix(fftw_complex *inputMatrix, const QImage *inputImage, const int width, const int height, const CurrentChannel channel) {
+ for (int y=0; y<height; y++) {
+ QRgb *line = (QRgb*)inputImage->constScanLine(y);
+ for (int x=0; x<width; x++) {
+ int value = 0;
+ switch (channel) {
+ case RED: value = qRed(line[x]); break;
+ case GREEN: value = qGreen(line[x]); break;
+ case BLUE: value = qBlue(line[x]); break;
+ case GRAY: value = qGray(line[x]); break;
+ }
+ inputMatrix[y*width + x][0] = centerFFTKoef(x, y) * value;
+ }
+ }
+}
+
+void ImageUtils::fillOutputImage(const QImage *inputImage, const fftw_complex *outputMatrix, QImage *outputImage, const int width, const int height, const CurrentChannel channel) {
+ for (int y = 0; y < height; y++) {
+ QRgb *line = (QRgb*) outputImage->scanLine(y);
+ for (int x = 0; x < width; x++) {
+ double value = outputMatrix[y*width + x][0] / (width * height);
+ value *= centerFFTKoef(x, y);
+ value = fabs(value);
+ if (value < 0) {
+ value = 0;
+ }
+ if (value > 255) {
+ value = 255;
+ }
+
+ switch (channel) {
+ case RED: line[x] = qRgb(value, 0, 0); break;
+ case GREEN: line[x] = line[x] | qRgb(0, value, 0); break;
+ case BLUE: line[x] = line[x] | qRgb(0, 0, value); break;
+ case GRAY: line[x] = qRgb(value, value, value); break;
+ }
+ }
+ }
+}
View
93 src/ImageUtils.h
@@ -1,43 +1,50 @@
-#ifndef IMAGEUTILS_H
-#define IMAGEUTILS_H
-
-#include <QDebug>
-#include <QTime>
-#include <QImage>
-#include <QPainter>
-#if defined (Q_WS_WIN)
-#include "fftw3.h"
-#else
-#include <fftw3.h>
-#endif
-#include <math.h>
-#include "Models/Blur.h"
-#include "Models/FocusBlur.h"
-#include "Models/MotionBlur.h"
-
-enum CurrentChannel {
- RED,
- GREEN,
- BLUE,
- GRAY
-};
-
-
-// Optimized version of pow(-1, x+y)
-inline signed char centerFFTKoef(int x, int y) {
- return((x+y) & 1) == 0 ? 1 : -1;
- // return pow(-1, x+y);
- // return 1;
-}
-
-class ImageUtils {
-
-public:
- static QImage* buildKernelImage(const FocusBlur* focusBlur);
- static QImage* buildKernelImage(const MotionBlur* motionBlur);
-
- static void fillInputMatrix(fftw_complex *inputMatrix, const QImage *inputImage, const int width, const int height, const CurrentChannel channel);
- static void fillOutputImage(const QImage *inputImage, const fftw_complex *outputMatrix, QImage *outputImage, const int width, const int height, const CurrentChannel channel);
-};
-
-#endif // IMAGEUTILS_H
+#ifndef IMAGEUTILS_H
+#define IMAGEUTILS_H
+
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#include <QDebug>
+#include <QTime>
+#include <QImage>
+#include <QPainter>
+#if defined (Q_WS_WIN)
+#include "fftw3.h"
+#else
+#include <fftw3.h>
+#endif
+#include <math.h>
+#include "Models/Blur.h"
+#include "Models/FocusBlur.h"
+#include "Models/MotionBlur.h"
+
+enum CurrentChannel {
+ RED,
+ GREEN,
+ BLUE,
+ GRAY
+};
+
+
+// Optimized version of pow(-1, x+y)
+inline signed char centerFFTKoef(int x, int y) {
+ return((x+y) & 1) == 0 ? 1 : -1;
+ // return pow(-1, x+y);
+ // return 1;
+}
+
+class ImageUtils {
+
+public:
+ static QImage* buildKernelImage(const FocusBlur* focusBlur);
+ static QImage* buildKernelImage(const MotionBlur* motionBlur);
+
+ static void fillInputMatrix(fftw_complex *inputMatrix, const QImage *inputImage, const int width, const int height, const CurrentChannel channel);
+ static void fillOutputImage(const QImage *inputImage, const fftw_complex *outputMatrix, QImage *outputImage, const int width, const int height, const CurrentChannel channel);
+};
+
+#endif // IMAGEUTILS_H
View
856 src/MainWindow.cpp
@@ -1,410 +1,446 @@
-#include "MainWindow.h"
-#include "ui_MainWindow.h"
-
-const QString MainWindow::appVersion = "0.48";
-
-MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
- ui->setupUi(this);
-
- resize(1000, 700);
-
- imageLabel = new QLabel;
- imageLabel->setBackgroundRole(QPalette::Base);
- imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
- imageLabel->setScaledContents(true);
-
- ui->scrollArea->setBackgroundRole(QPalette::Dark);
- ui->scrollArea->setWidget(imageLabel);
-
- radius = 9;
- PSNR = 0.001;
-
- workerThread = new WorkerThread();
-
- inputImage = NULL;
- outputImage = NULL;
-
- createActions();
- initControls();
- updateZoomControls();
-
- progressBar = new QProgressBar();
- progressBar->setValue(0);
- progressBar->setVisible(false);
- lblDeconvolutionTime = new QLabel();
- lblThreadsCount = new QLabel();
- lblImageSize = new QLabel();
- ui->statusBar->addWidget(lblThreadsCount);
- ui->statusBar->addWidget(lblImageSize);
- ui->statusBar->addWidget(lblDeconvolutionTime);
- ui->statusBar->addWidget(progressBar);
-
- workerThread->start();
-}
-
-
-MainWindow::~MainWindow() {
- delete ui;
-}
-
-void MainWindow::updatePreviewImage(int deconvolutionTime) {
- progressBar->setValue(0);
- progressBar->setVisible(false);
- // Hack to force update resized pixmap
- imageLabel->setPixmap(0);
- imageLabel->setPixmap(QPixmap::fromImage(*outputImage));
-
- lblDeconvolutionTime->setText(" Last operation time: " + QString::number(deconvolutionTime) + " ms ");
-}
-
-void MainWindow::updateProgress(int value) {
- progressBar->setVisible(true);
- progressBar->setValue(value);
-}
-
-
-Blur *MainWindow::generateBlurInfo(bool previewMode) {
- Blur* blur;
- QImage* kernelImage;
- if (ui->comboBoxType->currentIndex() == 0) {
- FocusBlur* focusBlur = new FocusBlur();
- focusBlur->radius = radius;
- focusBlur->edgeFeather = feather;
- focusBlur->correctionStrength = strength;
- focusBlur->PSNR = PSNR;
- focusBlur->previewMode = previewMode;
- kernelImage = ImageUtils::buildKernelImage(focusBlur);
- blur = focusBlur;
- } else {
- MotionBlur* motionBlur = new MotionBlur();
- motionBlur->radius = motionLength;
- motionBlur->angle = motionAngle;
- motionBlur->PSNR = PSNR;
- motionBlur->previewMode = previewMode;
- kernelImage = ImageUtils::buildKernelImage(motionBlur);
- blur = motionBlur;
- }
- // Update kernel preview
- ui->labelKernelPreview->setPixmap(QPixmap::fromImage(kernelImage->scaled(ui->labelKernelPreview->size())));
- delete(kernelImage);
-
- return blur;
-}
-
-
-void MainWindow::updatePreviewDeconvolution() {
- Blur* blur = generateBlurInfo(true);
- if (inputImage) {
- workerThread->deconvolutionRequest(inputImage, outputImage, blur);
- }
-}
-
-
-void MainWindow::updateFullDeconvolution() {
- Blur* blur = generateBlurInfo(false);
- if (inputImage) {
- workerThread->deconvolutionRequest(inputImage, outputImage, blur);
- }
-}
-
-void MainWindow::radiusChanged() {
- radius = ui->sliderRadius->value()/10.0;
- ui->labelRadius->setText(QString::number(radius));
- updatePreviewDeconvolution();
-
-}
-
-void MainWindow::PSNRChanged() {
- // Non-linear transformation
- PSNR = pow(1.07, ui->sliderPSNR->value())/10000.0;
- ui->labelPSNR->setText(QString::number(ui->sliderPSNR->value()) + "%");
- updatePreviewDeconvolution();
-}
-
-void MainWindow::kernelFeatherChanged() {
- feather = ui->sliderKernelFeather->value();
- ui->labelFeather->setText(QString::number(feather) + "%");
- updatePreviewDeconvolution();;
-}
-
-void MainWindow::kernelStrengthChanged() {
- strength = ui->sliderKernelStrength->value();
- ui->labelStrength->setText(QString::number(strength) + "%");
- updatePreviewDeconvolution();;
-}
-
-void MainWindow::motionLengthChanged() {
- motionLength = ui->sliderMotionLength->value()/10.0;
- ui->labelMotionLength->setText(QString::number(motionLength));
- updatePreviewDeconvolution();
-
-}
-
-void MainWindow::motionAngleChanged() {
- motionAngle = ui->sliderMotionAngle->value();
- ui->labelMotionAngle->setText(QString::number(motionAngle) + "°");
- updatePreviewDeconvolution();
-}
-
-void MainWindow::defectTypeChanged(int type) {
- bool motionVisible = (type == 1);
- int yMotion1 = 29;
- int yMotion2 = 49;
- int yMotion3 = 69;
-
- bool focusVisible = (type == 0);
- int yFocus1 = 36;
- int yFocus2 = 63;
-
- // Set visibility
- ui->labelMotionLengthCaption->setVisible(motionVisible);
- ui->labelMotionLength->setVisible(motionVisible);
- ui->sliderMotionLength->setVisible(motionVisible);
-
- ui->labelMotionAngleCaption->setVisible(motionVisible);
- ui->labelMotionAngle->setVisible(motionVisible);
- ui->sliderMotionAngle->setVisible(motionVisible);
-
- ui->labelRadiusCaption->setVisible(focusVisible);
- ui->labelRadius->setVisible(focusVisible);
- ui->sliderRadius->setVisible(focusVisible);
-
- ui->labelFeatherCaption->setVisible(focusVisible);
- ui->labelFeather->setVisible(focusVisible);
- ui->sliderKernelFeather->setVisible(focusVisible);
-
- ui->labelStrengthCaption->setVisible(focusVisible);
- ui->labelStrength->setVisible(focusVisible);
- ui->sliderKernelStrength->setVisible(focusVisible);
-
- // Move controls
- if (type == 1) {
- // Out of Focus Blur
- ui->labelMotionLengthCaption->move( ui->labelMotionLengthCaption->x(), yMotion1);
- ui->labelMotionLength->move( ui->labelMotionLength->x(), yMotion1);
- ui->sliderMotionLength->move( ui->sliderMotionLength->x(), yMotion1);
-
- ui->labelMotionAngleCaption->move( ui->labelMotionAngleCaption->x(), yMotion2);
- ui->labelMotionAngle->move( ui->labelMotionAngle->x(), yMotion2);
- ui->sliderMotionAngle->move( ui->sliderMotionAngle->x(), yMotion2);
-
- ui->labelPSNRCaption->move( ui->labelPSNRCaption->x(), yMotion3);
- ui->labelPSNR->move( ui->labelPSNR->x(), yMotion3);
- ui->sliderPSNR->move( ui->sliderPSNR->x(), yMotion3);
- } else {
- // Motion Blur
- ui->labelRadiusCaption->move( ui->labelRadiusCaption->x(), yFocus1);
- ui->labelRadius->move( ui->labelRadius->x(), yFocus1);
- ui->sliderRadius->move( ui->sliderRadius->x(), yFocus1);
-
- ui->labelPSNRCaption->move( ui->labelPSNRCaption->x(), yFocus2);
- ui->labelPSNR->move( ui->labelPSNR->x(), yFocus2);
- ui->sliderPSNR->move( ui->sliderPSNR->x(), yFocus2);
- }
-
- updateFullDeconvolution();
-}
-
-
-void MainWindow::open() {
- QString fileName = QFileDialog::getOpenFileName(this,
- tr("Open File"), QDir::currentPath());
- if (!fileName.isEmpty()) {
- delete(inputImage);
- delete(outputImage);
- inputImage = new QImage(fileName);
-
- if (inputImage->isNull()) {
- QMessageBox::information(this, tr("Smart Deblur"),
- tr("Cannot load %1.").arg(fileName));
- return;
- }
-
- // Resize image if it's necessary
- int width = inputImage->width();
- int height = inputImage->height();
-
- if (width > MAX_IMAGE_DIMENSION || height > MAX_IMAGE_DIMENSION) {
- double resizeRatio = qMin(MAX_IMAGE_DIMENSION/width, MAX_IMAGE_DIMENSION/height);
- width = width*resizeRatio;
- height = height*resizeRatio;
-
- width += width % 2;
- height += height % 2;
-
- inputImage = new QImage(inputImage->scaled(
- width, height,
- Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
-
- QMessageBox::information(this, tr("Smart Deblur"),
- tr("Image was resized to %1 * %2 because of performance reason")
- .arg(width).arg(height));
- }
-
- // Crop image if sizes are odd
- if (width%2 != 0 || height%2 !=0) {
- width -= width % 2;
- height -= height % 2;
- inputImage = new QImage(inputImage->copy(0,0, width, height));
- }
-
- lblImageSize->setText(tr(" Image Size: %1 x %2 ").arg(inputImage->width()).arg(inputImage->height()));
-
- ui->btnSave->setEnabled(true);
- ui->btnShowOriginal->setEnabled(true);
-
- outputImage = new QImage(inputImage->width(), inputImage->height(), QImage::Format_RGB32);
- lblThreadsCount->setText(tr(" Threads: %1 ").arg(workerThread->initFFT(inputImage)));
- imageLabel->setPixmap(QPixmap::fromImage(*inputImage));
- updateFullDeconvolution();
- ui->checkBoxFitToWindow->setChecked(true);
- fitToWindow();
- }
-}
-
-void MainWindow::save() {
- QString fileName = QFileDialog::getSaveFileName(this,
- tr("Save File"), QDir::currentPath(),tr("Images (*.png *.jpg)"));
- if (!fileName.isEmpty()) {
- outputImage->save(fileName);
- }
-}
-
-void MainWindow::zoomIn() {
- ui->checkBoxFitToWindow->setChecked(false);
- scaleImage(scaleFactor*2.0);
-}
-
-void MainWindow::zoomOut() {
- ui->checkBoxFitToWindow->setChecked(false);
- scaleImage(scaleFactor*0.5);
-}
-
-void MainWindow::actualSize() {
- ui->checkBoxFitToWindow->setChecked(false);
- scaleFactor = 1;
- scaleImage(scaleFactor);
-}
-
-void MainWindow::fitToWindow() {
- if (!imageLabel->pixmap()) {
- return;
- }
-
- double factor = qMin(
- ui->scrollArea->width()/((double)inputImage->width()),
- ui->scrollArea->height()/((double)inputImage->height()));
- if (factor > 1) {
- factor = 1;
- }
- scaleImage(factor);
-}
-
-void MainWindow::about() {
- QMessageBox::about(this, tr("About SmartDeblur"),
- tr("<p>The <b>SmartDeblur</b> is a tool for restoration of defocused and blurred images. "
- "Algorithm based on Wiener deconvolution.<br>"
- "Supported defect types:<ul>"
- "<li>Out of Focus blur (with kernel deep tuning)</li>"
- "<li>Motion blur</li></ul></p>"
- "<p>SmartDeblur uses the FFTW library which provides fast fourier tranformation implementation. "
- "See <a href='www.fftw.org'>www.fftw.org</a> for details </p>"
- "<p>Author: <b>Vladimir Yuzhikov</b> (yuvladimir@gmail.com), the latest sources and binaries are available on: <a href='https://github.com/Y-Vladimir/SmartDeblur'>https://github.com/Y-Vladimir/SmartDeblur</a></p>"
- "<p><b>Version: %1</b></p>").arg(appVersion));
-
-}
-
-void MainWindow::showOriginalPressed() {
- imageLabel->setPixmap(QPixmap::fromImage(*inputImage));
-}
-
-void MainWindow::showOriginalReleased() {
- imageLabel->setPixmap(QPixmap::fromImage(*outputImage));
-}
-
-
-void MainWindow::scaleImage(double factor) {
- if (!imageLabel->pixmap()) {
- return;
- }
-
- scaleFactor =factor;
- imageLabel->resize(scaleFactor * imageLabel->pixmap()->size());
-
- adjustScrollBar(ui->scrollArea->horizontalScrollBar(), factor);
- adjustScrollBar(ui->scrollArea->verticalScrollBar(), factor);
-
- ui->btnZoomIn->setEnabled(scaleFactor < 1.0);
- ui->btnZoomOut->setEnabled(scaleFactor > 0.3);
-}
-
-void MainWindow::initControls() {
- ui->sliderRadius->setValue(1);
- ui->sliderPSNR->setValue(40);
- ui->sliderKernelStrength->setValue(0);
- ui->sliderKernelFeather->setValue(20);
-
- ui->sliderMotionLength->setValue(1);
- ui->sliderMotionAngle->setValue(0);
-
- ui->comboBoxType->setCurrentIndex(0);
- defectTypeChanged(0);
-
- ui->btnSave->setEnabled(false);
- ui->btnShowOriginal->setEnabled(false);
-}
-
-void MainWindow::createActions() {
- connect(ui->btnZoomIn, SIGNAL(clicked()), this, SLOT(zoomIn()));
- connect(ui->btnZoomOut, SIGNAL(clicked()), this, SLOT(zoomOut()));
- connect(ui->btnZoomNormal, SIGNAL(clicked()), this, SLOT(actualSize()));
- connect(ui->checkBoxFitToWindow, SIGNAL(stateChanged(int)), SLOT(updateZoomControls()));
-
- connect(ui->btnOpen, SIGNAL(clicked()), this, SLOT(open()));
- connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(save()));
- connect(ui->btnAbout, SIGNAL(clicked()), this, SLOT(about()));
-
- connect(ui->sliderRadius, SIGNAL(valueChanged(int)), this, SLOT(radiusChanged()));
- connect(ui->sliderKernelFeather, SIGNAL(valueChanged(int)), this, SLOT(kernelFeatherChanged()));
- connect(ui->sliderKernelStrength, SIGNAL(valueChanged(int)), this, SLOT(kernelStrengthChanged()));
- connect(ui->sliderMotionLength, SIGNAL(valueChanged(int)), this, SLOT(motionLengthChanged()));
- connect(ui->sliderMotionAngle, SIGNAL(valueChanged(int)), this, SLOT(motionAngleChanged()));
- connect(ui->sliderPSNR, SIGNAL(valueChanged(int)), this, SLOT(PSNRChanged()));
-
- connect(ui->sliderRadius, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
- connect(ui->sliderKernelFeather, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
- connect(ui->sliderKernelStrength, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
- connect(ui->sliderPSNR, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
- connect(ui->sliderMotionLength, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
- connect(ui->sliderMotionAngle, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
-
- connect(ui->btnShowOriginal, SIGNAL(pressed()), this, SLOT(showOriginalPressed()));
- connect(ui->btnShowOriginal, SIGNAL(released()), this, SLOT(showOriginalReleased()));
-
- connect(ui->comboBoxType, SIGNAL(currentIndexChanged(int)), this, SLOT(defectTypeChanged(int)));
-
- connect(workerThread, SIGNAL(deconvolutionFinished(int)), SLOT(updatePreviewImage(int)));
- connect(workerThread->getDeconvolutionTool(), SIGNAL(progressEvent(int)), this, SLOT(updateProgress(int)));
-}
-
-void MainWindow::adjustScrollBar(QScrollBar *scrollBar, double factor) {
- scrollBar->setValue(int(factor * scrollBar->value()
- + ((factor - 1) * scrollBar->pageStep()/2)));
-}
-
-void MainWindow::resizeEvent(QResizeEvent *resizeEvent) {
- if (ui->checkBoxFitToWindow->isChecked()) {
- fitToWindow();
- }
-}
-
-void MainWindow::updateZoomControls() {
- bool fitChecked = ui->checkBoxFitToWindow->isChecked();
-
- ui->scrollArea->setVerticalScrollBarPolicy(!fitChecked ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
- ui->scrollArea->setHorizontalScrollBarPolicy(!fitChecked ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
-
- if (fitChecked) {
- fitToWindow();
- }
-}
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+
+const QString MainWindow::appVersion = "0.48";
+const double MainWindow::MAX_IMAGE_PIXELS = 3000000;
+const double MainWindow::MAX_IMAGE_DIMENSION = 2048;
+
+MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
+
+
+ ui->setupUi(this);
+
+ resize(1000, 700);
+
+ imageLabel = new QLabel;
+ imageLabel->setBackgroundRole(QPalette::Base);
+ imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ imageLabel->setScaledContents(true);
+
+ ui->scrollArea->setBackgroundRole(QPalette::Dark);
+ ui->scrollArea->setWidget(imageLabel);
+
+ radius = 9;
+ PSNR = 0.001;
+
+ workerThread = new WorkerThread();
+
+ inputImage = NULL;
+ outputImage = NULL;
+
+ createActions();
+ initControls();
+ updateZoomControls();
+
+ progressBar = new QProgressBar();
+ progressBar->setValue(0);
+ progressBar->setVisible(false);
+ lblDeconvolutionTime = new QLabel();
+ lblThreadsCount = new QLabel();
+ lblImageSize = new QLabel();
+ ui->statusBar->addWidget(lblThreadsCount);
+ ui->statusBar->addWidget(lblImageSize);
+ ui->statusBar->addWidget(lblDeconvolutionTime);
+ ui->statusBar->addWidget(progressBar);
+
+ workerThread->start();
+}
+
+
+MainWindow::~MainWindow() {
+ delete ui;
+}
+
+void MainWindow::updatePreviewImage(int deconvolutionTime) {
+ progressBar->setValue(0);
+ progressBar->setVisible(false);
+ // Hack to force update resized pixmap
+ imageLabel->setPixmap(0);
+ imageLabel->setPixmap(QPixmap::fromImage(*outputImage));
+
+ lblDeconvolutionTime->setText(" Last operation time: " + QString::number(deconvolutionTime) + " ms ");
+}
+
+void MainWindow::updateProgress(int value) {
+ progressBar->setVisible(true);
+ progressBar->setValue(value);
+}
+
+
+Blur *MainWindow::generateBlurInfo(bool previewMode) {
+ Blur* blur;
+ QImage* kernelImage;
+ if (ui->comboBoxType->currentIndex() == 0) {
+ FocusBlur* focusBlur = new FocusBlur();
+ focusBlur->radius = radius;
+ focusBlur->edgeFeather = feather;
+ focusBlur->correctionStrength = strength;
+ focusBlur->PSNR = PSNR;
+ focusBlur->previewMode = previewMode;
+ kernelImage = ImageUtils::buildKernelImage(focusBlur);
+ blur = focusBlur;
+ } else {
+ MotionBlur* motionBlur = new MotionBlur();
+ motionBlur->radius = motionLength;
+ motionBlur->angle = motionAngle;
+ motionBlur->PSNR = PSNR;
+ motionBlur->previewMode = previewMode;
+ kernelImage = ImageUtils::buildKernelImage(motionBlur);
+ blur = motionBlur;
+ }
+ // Update kernel preview
+ ui->labelKernelPreview->setPixmap(QPixmap::fromImage(kernelImage->scaled(ui->labelKernelPreview->size())));
+ delete(kernelImage);
+
+ return blur;
+}
+
+
+void MainWindow::updatePreviewDeconvolution() {
+ Blur* blur = generateBlurInfo(true);
+ if (inputImage) {
+ workerThread->deconvolutionRequest(inputImage, outputImage, blur);
+ }
+}
+
+
+void MainWindow::updateFullDeconvolution() {
+ Blur* blur = generateBlurInfo(false);
+ if (inputImage) {
+ workerThread->deconvolutionRequest(inputImage, outputImage, blur);
+ }
+}
+
+void MainWindow::radiusChanged() {
+ radius = ui->sliderRadius->value()/10.0;
+ ui->labelRadius->setText(QString::number(radius));
+ updatePreviewDeconvolution();
+
+}
+
+void MainWindow::PSNRChanged() {
+ // Non-linear transformation
+ PSNR = pow(1.07, ui->sliderPSNR->value())/10000.0;
+ ui->labelPSNR->setText(QString::number(ui->sliderPSNR->value()) + "%");
+ updatePreviewDeconvolution();
+}
+
+void MainWindow::kernelFeatherChanged() {
+ feather = ui->sliderKernelFeather->value();
+ ui->labelFeather->setText(QString::number(feather) + "%");
+ updatePreviewDeconvolution();;
+}
+
+void MainWindow::kernelStrengthChanged() {
+ strength = ui->sliderKernelStrength->value();
+ ui->labelStrength->setText(QString::number(strength) + "%");
+ updatePreviewDeconvolution();;
+}
+
+void MainWindow::motionLengthChanged() {
+ motionLength = ui->sliderMotionLength->value()/10.0;
+ ui->labelMotionLength->setText(QString::number(motionLength));
+ updatePreviewDeconvolution();
+
+}
+
+void MainWindow::motionAngleChanged() {
+ motionAngle = ui->sliderMotionAngle->value();
+ ui->labelMotionAngle->setText(QString::number(motionAngle) + "°");
+ updatePreviewDeconvolution();
+}
+
+void MainWindow::defectTypeChanged(int type) {
+ bool motionVisible = (type == 1);
+ int yMotion1 = 29;
+ int yMotion2 = 49;
+ int yMotion3 = 69;
+
+ bool focusVisible = (type == 0);
+ int yFocus1 = 36;
+ int yFocus2 = 63;
+
+ // Set visibility
+ ui->labelMotionLengthCaption->setVisible(motionVisible);
+ ui->labelMotionLength->setVisible(motionVisible);
+ ui->sliderMotionLength->setVisible(motionVisible);
+
+ ui->labelMotionAngleCaption->setVisible(motionVisible);
+ ui->labelMotionAngle->setVisible(motionVisible);
+ ui->sliderMotionAngle->setVisible(motionVisible);
+
+ ui->labelRadiusCaption->setVisible(focusVisible);
+ ui->labelRadius->setVisible(focusVisible);
+ ui->sliderRadius->setVisible(focusVisible);
+
+ ui->labelFeatherCaption->setVisible(focusVisible);
+ ui->labelFeather->setVisible(focusVisible);
+ ui->sliderKernelFeather->setVisible(focusVisible);
+
+ ui->labelStrengthCaption->setVisible(focusVisible);
+ ui->labelStrength->setVisible(focusVisible);
+ ui->sliderKernelStrength->setVisible(focusVisible);
+
+ // Move controls
+ if (type == 1) {
+ // Out of Focus Blur
+ ui->labelMotionLengthCaption->move( ui->labelMotionLengthCaption->x(), yMotion1);
+ ui->labelMotionLength->move( ui->labelMotionLength->x(), yMotion1);
+ ui->sliderMotionLength->move( ui->sliderMotionLength->x(), yMotion1);
+
+ ui->labelMotionAngleCaption->move( ui->labelMotionAngleCaption->x(), yMotion2);
+ ui->labelMotionAngle->move( ui->labelMotionAngle->x(), yMotion2);
+ ui->sliderMotionAngle->move( ui->sliderMotionAngle->x(), yMotion2);
+
+ ui->labelPSNRCaption->move( ui->labelPSNRCaption->x(), yMotion3);
+ ui->labelPSNR->move( ui->labelPSNR->x(), yMotion3);
+ ui->sliderPSNR->move( ui->sliderPSNR->x(), yMotion3);
+ } else {
+ // Motion Blur
+ ui->labelRadiusCaption->move( ui->labelRadiusCaption->x(), yFocus1);
+ ui->labelRadius->move( ui->labelRadius->x(), yFocus1);
+ ui->sliderRadius->move( ui->sliderRadius->x(), yFocus1);
+
+ ui->labelPSNRCaption->move( ui->labelPSNRCaption->x(), yFocus2);
+ ui->labelPSNR->move( ui->labelPSNR->x(), yFocus2);
+ ui->sliderPSNR->move( ui->sliderPSNR->x(), yFocus2);
+ }
+
+ updateFullDeconvolution();
+}
+
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+ {
+ event->acceptProposedAction();
+ }
+
+ void MainWindow::dragMoveEvent(QDragMoveEvent *event)
+ {
+ event->acceptProposedAction();
+ }
+
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ QList<QUrl> urls = event->mimeData()->urls();
+ if (urls.isEmpty()) {
+ return;
+ }
+
+ QString fileName = urls.first().toLocalFile();
+ if (fileName.isEmpty()) {
+ return;
+ }
+ event->acceptProposedAction();
+ openFile(fileName);
+
+}
+
+void MainWindow::openFile(QString fileName) {
+ delete(inputImage);
+ delete(outputImage);
+ inputImage = new QImage(fileName);
+
+ if (inputImage->isNull()) {
+ QMessageBox::information(this, tr("Smart Deblur"),
+ tr("Cannot load %1.").arg(fileName));
+ return;
+ }
+
+ // Resize image if it's necessary
+ int width = inputImage->width();
+ int height = inputImage->height();
+
+ if (width > MAX_IMAGE_DIMENSION || height > MAX_IMAGE_DIMENSION) {
+ double resizeRatio = qMin(MAX_IMAGE_DIMENSION/width, MAX_IMAGE_DIMENSION/height);
+ width = width*resizeRatio;
+ height = height*resizeRatio;
+
+ width += width % 2;
+ height += height % 2;
+
+ inputImage = new QImage(inputImage->scaled(
+ width, height,
+ Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+
+ QMessageBox::information(this, tr("Smart Deblur"),
+ tr("Image was resized to %1 * %2 because of performance reason")
+ .arg(width).arg(height));
+ }
+
+ // Crop image if sizes are odd
+ if (width%2 != 0 || height%2 !=0) {
+ width -= width % 2;
+ height -= height % 2;
+ inputImage = new QImage(inputImage->copy(0,0, width, height));
+ }
+
+ lblImageSize->setText(tr(" Image Size: %1 x %2 ").arg(inputImage->width()).arg(inputImage->height()));
+
+ ui->btnSave->setEnabled(true);
+ ui->btnShowOriginal->setEnabled(true);
+
+ outputImage = new QImage(inputImage->width(), inputImage->height(), QImage::Format_RGB32);
+ lblThreadsCount->setText(tr(" Threads: %1 ").arg(workerThread->initFFT(inputImage)));
+ imageLabel->setPixmap(QPixmap::fromImage(*inputImage));
+ updateFullDeconvolution();
+ ui->checkBoxFitToWindow->setChecked(true);
+ fitToWindow();
+}
+
+void MainWindow::open() {
+ QString fileName = QFileDialog::getOpenFileName(this,
+ tr("Open File"), QDir::currentPath());
+ if (!fileName.isEmpty()) {
+ openFile(fileName);
+ }
+}
+
+void MainWindow::save() {
+ QString fileName = QFileDialog::getSaveFileName(this,
+ tr("Save File"), QDir::currentPath(),tr("Images (*.png *.jpg)"));
+ if (!fileName.isEmpty()) {
+ outputImage->save(fileName);
+ }
+}
+
+void MainWindow::zoomIn() {
+ ui->checkBoxFitToWindow->setChecked(false);
+ scaleImage(scaleFactor*2.0);
+}
+
+void MainWindow::zoomOut() {
+ ui->checkBoxFitToWindow->setChecked(false);
+ scaleImage(scaleFactor*0.5);
+}
+
+void MainWindow::actualSize() {
+ ui->checkBoxFitToWindow->setChecked(false);
+ scaleFactor = 1;
+ scaleImage(scaleFactor);
+}
+
+void MainWindow::fitToWindow() {
+ if (!imageLabel->pixmap()) {
+ return;
+ }
+
+ double factor = qMin(
+ ui->scrollArea->width()/((double)inputImage->width()),
+ ui->scrollArea->height()/((double)inputImage->height()));
+ if (factor > 1) {
+ factor = 1;
+ }
+ scaleImage(factor);
+}
+
+void MainWindow::about() {
+ QMessageBox::about(this, tr("About SmartDeblur"),
+ tr("<p>The <b>SmartDeblur</b> is a tool for restoration of defocused and blurred images. "
+ "Algorithm based on Wiener deconvolution.<br>"
+ "Supported defect types:<ul>"
+ "<li>Out of Focus blur (with kernel deep tuning)</li>"
+ "<li>Motion blur</li></ul></p>"
+ "<p>SmartDeblur uses the FFTW library which provides fast fourier tranformation implementation. "
+ "See <a href='www.fftw.org'>www.fftw.org</a> for details </p>"
+ "<p>Author: <b>Vladimir Yuzhikov</b> (yuvladimir@gmail.com), the latest sources and binaries are available on: <a href='https://github.com/Y-Vladimir/SmartDeblur'>https://github.com/Y-Vladimir/SmartDeblur</a></p>"
+ "<p><b>Version: %1</b></p>").arg(appVersion));
+
+}
+
+void MainWindow::showOriginalPressed() {
+ imageLabel->setPixmap(QPixmap::fromImage(*inputImage));
+}
+
+void MainWindow::showOriginalReleased() {
+ imageLabel->setPixmap(QPixmap::fromImage(*outputImage));
+}
+
+
+void MainWindow::scaleImage(double factor) {
+ if (!imageLabel->pixmap()) {
+ return;
+ }
+
+ scaleFactor =factor;
+ imageLabel->resize(scaleFactor * imageLabel->pixmap()->size());
+
+ adjustScrollBar(ui->scrollArea->horizontalScrollBar(), factor);
+ adjustScrollBar(ui->scrollArea->verticalScrollBar(), factor);
+
+ ui->btnZoomIn->setEnabled(scaleFactor < 1.0);
+ ui->btnZoomOut->setEnabled(scaleFactor > 0.3);
+}
+
+void MainWindow::initControls() {
+ ui->sliderRadius->setValue(1);
+ ui->sliderPSNR->setValue(40);
+ ui->sliderKernelStrength->setValue(0);
+ ui->sliderKernelFeather->setValue(20);
+
+ ui->sliderMotionLength->setValue(1);
+ ui->sliderMotionAngle->setValue(0);
+
+ ui->comboBoxType->setCurrentIndex(0);
+ defectTypeChanged(0);
+
+ ui->btnSave->setEnabled(false);
+ ui->btnShowOriginal->setEnabled(false);
+
+ this->setAcceptDrops(true);
+}
+
+void MainWindow::createActions() {
+ connect(ui->btnZoomIn, SIGNAL(clicked()), this, SLOT(zoomIn()));
+ connect(ui->btnZoomOut, SIGNAL(clicked()), this, SLOT(zoomOut()));
+ connect(ui->btnZoomNormal, SIGNAL(clicked()), this, SLOT(actualSize()));
+ connect(ui->checkBoxFitToWindow, SIGNAL(stateChanged(int)), SLOT(updateZoomControls()));
+
+ connect(ui->btnOpen, SIGNAL(clicked()), this, SLOT(open()));
+ connect(ui->btnSave, SIGNAL(clicked()), this, SLOT(save()));
+ connect(ui->btnAbout, SIGNAL(clicked()), this, SLOT(about()));
+
+ connect(ui->sliderRadius, SIGNAL(valueChanged(int)), this, SLOT(radiusChanged()));
+ connect(ui->sliderKernelFeather, SIGNAL(valueChanged(int)), this, SLOT(kernelFeatherChanged()));
+ connect(ui->sliderKernelStrength, SIGNAL(valueChanged(int)), this, SLOT(kernelStrengthChanged()));
+ connect(ui->sliderMotionLength, SIGNAL(valueChanged(int)), this, SLOT(motionLengthChanged()));
+ connect(ui->sliderMotionAngle, SIGNAL(valueChanged(int)), this, SLOT(motionAngleChanged()));
+ connect(ui->sliderPSNR, SIGNAL(valueChanged(int)), this, SLOT(PSNRChanged()));
+
+ connect(ui->sliderRadius, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+ connect(ui->sliderKernelFeather, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+ connect(ui->sliderKernelStrength, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+ connect(ui->sliderPSNR, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+ connect(ui->sliderMotionLength, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+ connect(ui->sliderMotionAngle, SIGNAL(sliderReleased()), this, SLOT(updateFullDeconvolution()));
+
+ connect(ui->btnShowOriginal, SIGNAL(pressed()), this, SLOT(showOriginalPressed()));
+ connect(ui->btnShowOriginal, SIGNAL(released()), this, SLOT(showOriginalReleased()));
+
+ connect(ui->comboBoxType, SIGNAL(currentIndexChanged(int)), this, SLOT(defectTypeChanged(int)));
+
+ connect(workerThread, SIGNAL(deconvolutionFinished(int)), SLOT(updatePreviewImage(int)));
+ connect(workerThread->getDeconvolutionTool(), SIGNAL(progressEvent(int)), this, SLOT(updateProgress(int)));
+}
+
+void MainWindow::adjustScrollBar(QScrollBar *scrollBar, double factor) {
+ scrollBar->setValue(int(factor * scrollBar->value()
+ + ((factor - 1) * scrollBar->pageStep()/2)));
+}
+
+void MainWindow::resizeEvent(QResizeEvent *resizeEvent) {
+ if (ui->checkBoxFitToWindow->isChecked()) {
+ fitToWindow();
+ }
+}
+
+void MainWindow::updateZoomControls() {
+ bool fitChecked = ui->checkBoxFitToWindow->isChecked();
+
+ ui->scrollArea->setVerticalScrollBarPolicy(!fitChecked ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
+ ui->scrollArea->setHorizontalScrollBarPolicy(!fitChecked ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff);
+
+ if (fitChecked) {
+ fitToWindow();
+ }
+}
View
219 src/MainWindow.h
@@ -1,103 +1,116 @@
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include <QMainWindow>
-#include <QDebug>
-#include <QImage>
-#include <QPainter>
-#include <QTime>
-#include <QThread>
-#include <QLabel>
-#include <QScrollBar>
-#include <QScrollArea>
-#include <QMessageBox>
-#include <QDir>
-#include <QFileDialog>
-#include <QResizeEvent>
-#include <QSharedPointer>
-#include <QProgressBar>
-#include <QString>
-
-#include <time.h>
-#include <math.h>
-#if defined (Q_WS_WIN)
-#include "fftw3.h"
-#else
-#include <fftw3.h>
-#endif
-#include "DeconvolutionTool.h"
-#include "WorkerThread.h"
-
-
-namespace Ui {
-class MainWindow;
-}
-
-class WorkerThread;
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- static const QString appVersion;
-
-protected:
- void resizeEvent(QResizeEvent *resizeEvent);
-
-private:
- Ui::MainWindow *ui;
- WorkerThread *workerThread;
- QLabel *imageLabel;
- double scaleFactor;
-
- QImage *inputImage;
- QImage *outputImage;
-
- QProgressBar* progressBar;
- QLabel* lblDeconvolutionTime;
- QLabel* lblThreadsCount;
- QLabel* lblImageSize;
-
- double radius, PSNR, feather, strength, motionLength, motionAngle;
-
- Blur* generateBlurInfo(bool previewMode);
- void updatePreviewDeconvolution();
- void scaleImage(double factor);
- void initControls();
- void createActions();
- void adjustScrollBar(QScrollBar *scrollBar, double factor);
-
- static const double MAX_IMAGE_PIXELS = 3000000; // 3 mega-pixels
- static const double MAX_IMAGE_DIMENSION = 2048; // 3 mega-pixels
-
-
-private slots:
- void radiusChanged();
- void PSNRChanged();
- void kernelFeatherChanged();
- void kernelStrengthChanged();
- void motionLengthChanged();
- void motionAngleChanged();
- void defectTypeChanged(int type);
- void open();
- void save();
- void zoomIn();
- void zoomOut();
- void actualSize();
- void fitToWindow();
- void about();
- void showOriginalPressed();
- void showOriginalReleased();
- void updateFullDeconvolution();
- void updateZoomControls();
- void updatePreviewImage(int deconvolutionTime);
- void updateProgress(int value);
-
-};
-
-
-
-#endif // MAINWINDOW_H
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QDebug>
+#include <QImage>
+#include <QPainter>
+#include <QTime>
+#include <QThread>
+#include <QLabel>
+#include <QScrollBar>
+#include <QScrollArea>
+#include <QMessageBox>
+#include <QDir>
+#include <QFileDialog>
+#include <QResizeEvent>
+#include <QSharedPointer>
+#include <QProgressBar>
+#include <QString>
+#include <QDropEvent>
+#include <QUrl>
+#include <time.h>
+
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#include <cmath>
+#else
+#include <math.h>
+#endif
+#if defined (Q_WS_WIN)
+
+#include "fftw3.h"
+#else
+#include <fftw3.h>
+#endif
+#include "DeconvolutionTool.h"
+#include "WorkerThread.h"
+
+
+namespace Ui {
+class MainWindow;
+}
+
+class WorkerThread;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ static const double MAX_IMAGE_PIXELS;
+ static const double MAX_IMAGE_DIMENSION;
+
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ static const QString appVersion;
+
+protected:
+ void resizeEvent(QResizeEvent *resizeEvent);
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+private:
+ Ui::MainWindow *ui;
+ WorkerThread *workerThread;
+ QLabel *imageLabel;
+ double scaleFactor;
+
+ QImage *inputImage;
+ QImage *outputImage;
+
+ QProgressBar* progressBar;
+ QLabel* lblDeconvolutionTime;
+ QLabel* lblThreadsCount;
+ QLabel* lblImageSize;
+
+ double radius, PSNR, feather, strength, motionLength, motionAngle;
+
+ Blur* generateBlurInfo(bool previewMode);
+ void updatePreviewDeconvolution();
+ void scaleImage(double factor);
+ void initControls();
+ void createActions();
+ void adjustScrollBar(QScrollBar *scrollBar, double factor);
+ void openFile(QString fileName);
+
+
+
+
+private slots:
+ void radiusChanged();
+ void PSNRChanged();
+ void kernelFeatherChanged();
+ void kernelStrengthChanged();
+ void motionLengthChanged();
+ void motionAngleChanged();
+ void defectTypeChanged(int type);
+ void open();
+ void save();
+ void zoomIn();
+ void zoomOut();
+ void actualSize();
+ void fitToWindow();
+ void about();
+ void showOriginalPressed();
+ void showOriginalReleased();
+ void updateFullDeconvolution();
+ void updateZoomControls();
+ void updatePreviewImage(int deconvolutionTime);
+ void updateProgress(int value);
+
+};
+
+
+
+#endif // MAINWINDOW_H
View
1,763 src/MainWindow.ui
@@ -1,877 +1,886 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>1107</width>
- <height>527</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>400</height>
- </size>
- </property>
- <property name="windowTitle">
- <string>SmartDeblur</string>
- </property>
- <property name="windowIcon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Logo2.png</normaloff>:/SmartDeblur/Icons/Logo2.png</iconset>
- </property>
- <widget class="QWidget" name="centralWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="margin">
- <number>3</number>
- </property>
- <property name="spacing">
- <number>2</number>
- </property>
- <item row="0" column="0">
- <widget class="QTabWidget" name="tabWidget">
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>140</height>
- </size>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Main</string>
- </attribute>
- <widget class="QFrame" name="frame">
- <property name="geometry">
- <rect>
- <x>1</x>
- <y>2</y>
- <width>161</width>
- <height>110</height>
- </rect>
- </property>
- <property name="styleSheet">
- <string notr="true">QFrame {background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))}
-
-QLabel {background-color: none;}
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <widget class="QToolButton" name="btnOpen">
- <property name="geometry">
- <rect>
- <x>3</x>
- <y>3</y>
- <width>51</width>
- <height>60</height>
- </rect>
- </property>
- <property name="text">
- <string>Open</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Open.png</normaloff>:/SmartDeblur/Icons/Open.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextUnderIcon</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QLabel" name="label_4">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>90</y>
- <width>162</width>
- <height>21</height>
- </rect>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="text">
- <string>File</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- <widget class="QToolButton" name="btnSave">
- <property name="geometry">
- <rect>
- <x>56</x>
- <y>3</y>
- <width>51</width>
- <height>60</height>
- </rect>
- </property>
- <property name="text">
- <string>Save</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Save.png</normaloff>:/SmartDeblur/Icons/Save.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextUnderIcon</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QToolButton" name="btnAbout">
- <property name="geometry">
- <rect>
- <x>109</x>
- <y>3</y>
- <width>51</width>
- <height>60</height>
- </rect>
- </property>
- <property name="text">
- <string>About</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/About.png</normaloff>:/SmartDeblur/Icons/About.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>32</width>
- <height>32</height>
- </size>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextUnderIcon</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- </widget>
- <widget class="QFrame" name="frame_2">
- <property name="geometry">
- <rect>
- <x>165</x>
- <y>2</y>
- <width>114</width>
- <height>110</height>
- </rect>
- </property>
- <property name="styleSheet">
- <string notr="true">QFrame {background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))}
-
-QLabel {background-color: none;}
-
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <widget class="QToolButton" name="btnZoomIn">
- <property name="geometry">
- <rect>
- <x>75</x>
- <y>10</y>
- <width>31</width>
- <height>31</height>
- </rect>
- </property>
- <property name="text">
- <string>+</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Zoom In.png</normaloff>:/SmartDeblur/Icons/Zoom In.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>24</width>
- <height>24</height>
- </size>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QToolButton" name="btnZoomOut">
- <property name="geometry">
- <rect>
- <x>41</x>
- <y>10</y>
- <width>31</width>
- <height>31</height>
- </rect>
- </property>
- <property name="text">
- <string>-</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Zoom Out.png</normaloff>:/SmartDeblur/Icons/Zoom Out.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>24</width>
- <height>24</height>
- </size>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QToolButton" name="btnZoomNormal">
- <property name="geometry">
- <rect>
- <x>6</x>
- <y>10</y>
- <width>31</width>
- <height>31</height>
- </rect>
- </property>
- <property name="text">
- <string>1:1</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/Zoom_Actual.png</normaloff>:/SmartDeblur/Icons/Zoom_Actual.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>24</width>
- <height>24</height>
- </size>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QCheckBox" name="checkBoxFitToWindow">
- <property name="geometry">
- <rect>
- <x>16</x>
- <y>51</y>
- <width>91</width>
- <height>17</height>
- </rect>
- </property>
- <property name="text">
- <string>Fit to Window</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QLabel" name="label_3">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>90</y>
- <width>115</width>
- <height>21</height>
- </rect>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="text">
- <string>Zoom</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </widget>
- <widget class="QFrame" name="frame_3">
- <property name="geometry">
- <rect>
- <x>282</x>
- <y>2</y>
- <width>437</width>
- <height>110</height>
- </rect>
- </property>
- <property name="styleSheet">
- <string notr="true">QFrame {background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))}
-
-QLabel {background-color: none;}
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <widget class="QSlider" name="sliderRadius">
- <property name="geometry">
- <rect>
- <x>77</x>
- <y>55</y>
- <width>356</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>500</number>
- </property>
- <property name="value">
- <number>50</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- <widget class="QSlider" name="sliderPSNR">
- <property name="geometry">
- <rect>
- <x>77</x>
- <y>70</y>
- <width>356</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>99</number>
- </property>
- <property name="value">
- <number>50</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- <widget class="QLabel" name="labelRadius">
- <property name="geometry">
- <rect>
- <x>49</x>
- <y>57</y>
- <width>32</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelPSNR">
- <property name="geometry">
- <rect>
- <x>49</x>
- <y>72</y>
- <width>32</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QComboBox" name="comboBoxType">
- <property name="geometry">
- <rect>
- <x>85</x>
- <y>3</y>
- <width>140</width>
- <height>21</height>
- </rect>
- </property>
- <item>
- <property name="text">
- <string>Out of Focus Blur</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Motion Blur</string>
- </property>
- </item>
- </widget>
- <widget class="QSlider" name="sliderMotionLength">
- <property name="geometry">
- <rect>
- <x>77</x>
- <y>23</y>
- <width>356</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>500</number>
- </property>
- <property name="value">
- <number>50</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- <widget class="QLabel" name="labelMotionLength">
- <property name="geometry">
- <rect>
- <x>49</x>
- <y>24</y>
- <width>32</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QSlider" name="sliderMotionAngle">
- <property name="geometry">
- <rect>
- <x>77</x>
- <y>39</y>
- <width>356</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>-90</number>
- </property>
- <property name="maximum">
- <number>90</number>
- </property>
- <property name="value">
- <number>50</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- <widget class="QLabel" name="labelMotionAngle">
- <property name="geometry">
- <rect>
- <x>49</x>
- <y>41</y>
- <width>32</width>
- <height>13</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_2">
- <property name="geometry">
- <rect>
- <x>6</x>
- <y>5</y>
- <width>70</width>
- <height>16</height>
- </rect>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Defect type:</string>
- </property>
- </widget>
- <widget class="QToolButton" name="btnShowOriginal">
- <property name="geometry">
- <rect>
- <x>235</x>
- <y>0</y>
- <width>105</width>
- <height>28</height>
- </rect>
- </property>
- <property name="text">
- <string>Show Original</string>
- </property>
- <property name="icon">
- <iconset resource="MainResources.qrc">
- <normaloff>:/SmartDeblur/Icons/image.png</normaloff>:/SmartDeblur/Icons/image.png</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>24</width>
- <height>24</height>
- </size>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- <property name="autoRaise">
- <bool>true</bool>
- </property>
- </widget>
- <widget class="QLabel" name="labelMotionLengthCaption">
- <property name="geometry">
- <rect>
- <x>5</x>
- <y>23</y>
- <width>47</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Length:</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelMotionAngleCaption">
- <property name="geometry">
- <rect>
- <x>5</x>
- <y>40</y>
- <width>47</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Angle:</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelRadiusCaption">
- <property name="geometry">
- <rect>
- <x>5</x>
- <y>56</y>
- <width>47</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Radius:</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelPSNRCaption">
- <property name="geometry">
- <rect>
- <x>5</x>
- <y>71</y>
- <width>47</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Smooth:</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_7">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>90</y>
- <width>438</width>
- <height>21</height>
- </rect>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="text">
- <string>Blur Parameters</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </widget>
- <widget class="QFrame" name="frame_5">
- <property name="geometry">
- <rect>
- <x>722</x>
- <y>2</y>
- <width>231</width>
- <height>110</height>
- </rect>
- </property>
- <property name="styleSheet">
- <string notr="true">QFrame {background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))}
-
-QLabel {background-color: none;}
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::NoFrame</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <widget class="QSlider" name="sliderKernelStrength">
- <property name="geometry">
- <rect>
- <x>94</x>
- <y>22</y>
- <width>131</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>-99</number>
- </property>
- <property name="maximum">
- <number>99</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::NoTicks</enum>
- </property>
- <property name="tickInterval">
- <number>20</number>
- </property>
- </widget>
- <widget class="QSlider" name="sliderKernelFeather">
- <property name="geometry">
- <rect>
- <x>94</x>
- <y>66</y>
- <width>131</width>
- <height>19</height>
- </rect>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>99</number>
- </property>
- <property name="value">
- <number>10</number>
- </property>
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="tickPosition">
- <enum>QSlider::NoTicks</enum>
- </property>
- <property name="tickInterval">
- <number>10</number>
- </property>
- </widget>
- <widget class="QLabel" name="labelKernelPreview">
- <property name="geometry">
- <rect>
- <x>3</x>
- <y>3</y>
- <width>85</width>
- <height>85</height>
- </rect>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: rgb(191, 191, 191);</string>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- <widget class="QLabel" name="labelStrength">
- <property name="geometry">
- <rect>
- <x>198</x>
- <y>5</y>
- <width>31</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelFeather">
- <property name="geometry">
- <rect>
- <x>200</x>
- <y>47</y>
- <width>31</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>5</string>
- </property>
- </widget>
- <widget class="QLabel" name="label_5">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>90</y>
- <width>232</width>
- <height>21</height>
- </rect>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="styleSheet">
- <string notr="true">background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(165, 206, 255, 255), stop:0.744318 rgba(219, 240, 255, 255))
-</string>
- </property>
- <property name="frameShape">
- <enum>QFrame::Box</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="text">
- <string>Kernel Preview &amp; Tuning</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- <widget class="QLabel" name="labelStrengthCaption">
- <property name="geometry">
- <rect>
- <x>94</x>
- <y>5</y>
- <width>99</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Correction Strength:</string>
- </property>
- </widget>
- <widget class="QLabel" name="labelFeatherCaption">
- <property name="geometry">
- <rect>
- <x>97</x>
- <y>47</y>
- <width>91</width>
- <height>16</height>
- </rect>
- </property>
- <property name="text">
- <string>Edge Feather:</string>
- </property>
- </widget>
- </widget>
- </widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string>Settings</string>
- </attribute>
- </widget>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QScrollArea" name="scrollArea">
- <property name="widgetResizable">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="scrollAreaWidgetContents">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width