Skip to content
Browse files

Ring effect and unstable issue fixes

  • Loading branch information...
1 parent 519cc4b commit ad701126078a70206b30f9681f2e4aee88049578 @Y-Vladimir committed Jul 14, 2012
View
BIN binaries/windows/SmartDeblur.exe
Binary file not shown.
View
BIN binaries/windows/imageformats/qjpeg4.dll
Binary file not shown.
View
BIN binaries/windows/imageformats/qtiff4.dll
Binary file not shown.
View
21 sources/DeconvolutionTool.cpp
@@ -4,7 +4,7 @@
DeconvolutionTool::DeconvolutionTool(QObject* parent):QObject(parent) {
// Init MultiThreading
- int threadsCount = QThread::idealThreadCount() > 0 ? QThread::idealThreadCount() : 2;
+ threadsCount = QThread::idealThreadCount() > 0 ? QThread::idealThreadCount() : 2;
qDebug("Init Multi-Threading with threads count: %d", threadsCount);
fftw_plan_with_nthreads(threadsCount);
@@ -59,7 +59,7 @@ void DeconvolutionTool::initFFT(const QImage *inputImage) {
void DeconvolutionTool::doDeconvolution(const QImage *inputImage, QImage *outputImage, const Blur* blur) {
// Create kernel
buildKernel(kernelMatrix, width, height, blur);
- fftw_execute(forwardKernelPlan);
+ fftw_execute(forwardKernelPlan);
if (blur->previewMode) {
doDeconvolutionForChannel(inputImage, outputImage, kernelMatrixFFT, width, height, blur->radius, blur->PSNR, GRAY);
@@ -74,6 +74,10 @@ void DeconvolutionTool::doDeconvolution(const QImage *inputImage, QImage *output
}
}
+int DeconvolutionTool::getThreadsCount() {
+ return threadsCount;
+}
+
void DeconvolutionTool::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) {
// Read given channel
@@ -87,10 +91,11 @@ void DeconvolutionTool::doDeconvolutionForChannel(const QImage *inputImage, QIma
for (int y = 0; y<height; y++) {
for (int x = 0; x<width; x++) {
int index = y*width+x;
- inputMatrix[index][0] =
- (x < kernelRadius || y < kernelRadius || x > width - kernelRadius ||y > height - kernelRadius )
- ? -outputMatrix[index][0] / (width * height)
- : inputMatrix[index][0];
+ if (x < kernelRadius || y < kernelRadius || x > width - kernelRadius ||y > height - kernelRadius) {
+ inputMatrix[index][0] = outputMatrix[y*width + x][0] / (width * height);
+ }
+
+ inputMatrix[index][0] = centerFFTKoef(x, y)*fabs(inputMatrix[index][0]);
inputMatrix[index][1] = 0;
}
}
@@ -109,7 +114,7 @@ void DeconvolutionTool::multiplayFFTs(const fftw_complex *firstFFT, const fftw_c
for (int y = 0; y<height; y++) {
for (int x = 0; x<width; x++) {
int index = y*width + x;
- double value = centerFFTKoef(x, y) * secondFFT[index][0] ;
+ double value = centerFFTKoef(x, y) * secondFFT[index][0];
outFFT[index][0] *= value;
outFFT[index][1] *= value;
}
@@ -147,7 +152,7 @@ void DeconvolutionTool::buildKernel(fftw_complex* outKernelFFT, const int WIDTH,
for (int x = 0; x<WIDTH; x++) {
int index = y*WIDTH + x;
int value = 0;
- // if we are in the kernel area, then take pixel values. Otherwise keep 0
+ // if we are in the kernel area (of small kernelImage), then take pixel values. Otherwise keep 0
if (abs(x-WIDTH/2)<(size-2)/2 && abs(y-HEIGHT/2)<(size-2)/2) {
int xLocal = x-(WIDTH-size)/2;
int yLocal = y-(HEIGHT-size)/2;
View
2 sources/DeconvolutionTool.h
@@ -24,6 +24,7 @@ class DeconvolutionTool : public QObject
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);
@@ -37,6 +38,7 @@ class DeconvolutionTool : public QObject
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;
View
3 sources/ImageUtils.cpp
@@ -112,7 +112,8 @@ void ImageUtils::fillOutputImage(const QImage *inputImage, const fftw_complex *o
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+1, y);
+ value *= centerFFTKoef(x, y);
+ value = fabs(value);
if (value < 0) {
value = 0;
}
View
3 sources/ImageUtils.h
@@ -22,7 +22,8 @@ enum CurrentChannel {
// Optimized version of pow(-1, x+y)
inline signed char centerFFTKoef(int x, int y) {
return((x+y) & 1) == 0 ? 1 : -1;
- // return 1;
+ // return pow(-1, x+y);
+ // return 1;
}
class ImageUtils {
View
32 sources/MainWindow.cpp
@@ -1,6 +1,7 @@
#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);
@@ -31,6 +32,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
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);
@@ -221,25 +226,35 @@ void MainWindow::open() {
if (width > MAX_IMAGE_DIMENSION || height > MAX_IMAGE_DIMENSION) {
double resizeRatio = qMin(MAX_IMAGE_DIMENSION/width, MAX_IMAGE_DIMENSION/height);
- int newWidth = width*resizeRatio;
- int newHeight = height*resizeRatio;
+ width = width*resizeRatio;
+ height = height*resizeRatio;
- newWidth += newWidth % 2;
- newHeight += newHeight % 2;
+ width += width % 2;
+ height += height % 2;
inputImage = new QImage(inputImage->scaled(
- newWidth, newHeight,
+ width, height,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+
QMessageBox::information(this, tr("Smart Deblur"),
tr("Image was resized to %1 * %2 because of performance reason")
- .arg(newWidth).arg(newHeight));
+ .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);
- workerThread->initFFT(inputImage);
+ lblThreadsCount->setText(tr(" Threads: %1 ").arg(workerThread->initFFT(inputImage)));
imageLabel->setPixmap(QPixmap::fromImage(*inputImage));
updateFullDeconvolution();
ui->checkBoxFitToWindow->setChecked(true);
@@ -294,7 +309,8 @@ void MainWindow::about() {
"<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>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));
}
View
7 sources/MainWindow.h
@@ -16,6 +16,7 @@
#include <QResizeEvent>
#include <QSharedPointer>
#include <QProgressBar>
+#include <QString>
#include <time.h>
#include <math.h>
@@ -37,6 +38,7 @@ class MainWindow : public QMainWindow
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
+ static const QString appVersion;
protected:
void resizeEvent(QResizeEvent *resizeEvent);
@@ -52,6 +54,8 @@ class MainWindow : public QMainWindow
QProgressBar* progressBar;
QLabel* lblDeconvolutionTime;
+ QLabel* lblThreadsCount;
+ QLabel* lblImageSize;
double radius, PSNR, feather, strength, motionLength, motionAngle;
@@ -65,6 +69,7 @@ class MainWindow : public QMainWindow
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();
@@ -89,4 +94,6 @@ private slots:
};
+
+
#endif // MAINWINDOW_H
View
2 sources/Models/FocusBlur.h
@@ -8,7 +8,7 @@ class FocusBlur : public Blur
public:
double edgeFeather;
double correctionStrength;
- const QString getName() const{
+ const QString getName() const{
return "FocusBlur";
}
};
View
1 sources/SmartDeblur.pro
@@ -36,3 +36,4 @@ RESOURCES += \
MainResources.qrc
RC_FILE = SmartDeblur.rc
+#CONFIG += console
View
3 sources/WorkerThread.cpp
@@ -6,9 +6,10 @@ WorkerThread::WorkerThread(QObject *parent) : QThread(parent) {
requestCondition = new QWaitCondition();
}
-void WorkerThread::initFFT(const QImage *inputImage) {
+int WorkerThread::initFFT(const QImage *inputImage) {
deconvolutionTool->initFFT(inputImage);
isRequestUpdated = false;
+ return deconvolutionTool->getThreadsCount();
}
void WorkerThread::deconvolutionRequest(QImage *inputImage, QImage *outputImage, Blur* blur) {
View
9 sources/WorkerThread.h
@@ -14,7 +14,7 @@ class WorkerThread : public QThread
public:
explicit WorkerThread(QObject *parent = 0);
- void initFFT(const QImage *inputImage);
+ int initFFT(const QImage *inputImage);
void deconvolutionRequest(QImage *inputImage, QImage *outputImage, Blur *blur);
DeconvolutionTool* getDeconvolutionTool();
@@ -28,13 +28,6 @@ class WorkerThread : public QThread
volatile bool isRequestUpdated;
QImage *inputImage;
QImage *outputImage;
- double kernelRadius;
- double kernelFeather;
- double kernelStrength;
- double motionLength;
- double motionAngle;
- double PSNR;
- bool previewMode;
Blur* blur;
DeconvolutionTool *deconvolutionTool;

0 comments on commit ad70112

Please sign in to comment.
Something went wrong with that request. Please try again.