1
0

Finished prototype

This commit is contained in:
2020-01-22 18:53:56 +01:00
parent 66b14d5964
commit e47dad757e
7 changed files with 251 additions and 27 deletions
+22 -14
View File
@@ -1,38 +1,38 @@
#include "clahe.h" #include "clahe.h"
#include <QDebug> #include <QDebug>
#include <opencv2/highgui.hpp>
CLAHE::CLAHE() CLAHE::CLAHE()
{ {
_clahe = cv::createCLAHE();
} }
void CLAHE::loadFile(const QString &path) void CLAHE::loadFile(const QString &path)
{ {
cv::Mat tmp; cv::Mat tmp;
tmp = cv::imread(path.toStdString(), cv::IMREAD_COLOR | cv::IMREAD_ANYDEPTH); tmp = cv::imread(path.toStdString(), cv::IMREAD_COLOR | cv::IMREAD_ANYDEPTH);
double scale = tmp.depth()==CV_8U ? 1.0/255 : 1.0/65535; int type = tmp.depth();
tmp.convertTo(tmp, CV_32F, scale); _scale = type==CV_8U ? 1.0/255 : 1.0/65535;
tmp.convertTo(tmp, CV_32F, _scale);
cv::cvtColor(tmp, tmp, cv::COLOR_BGR2Lab); cv::cvtColor(tmp, tmp, cv::COLOR_BGR2Lab);
cv::split(tmp, _image); cv::split(tmp, _image);
_image[0].convertTo(_lumImage, CV_16U, 655.35); _image[0].convertTo(_lumImage, type, 0.01/_scale);
double min, max;
cv::minMaxLoc(_image[0], &min, &max);
qDebug() << scale << min << max;
} }
void CLAHE::saveFile(const QString &path) void CLAHE::saveFile(const QString &path)
{ {
cv::Mat tmp;
cv::merge(_image, 3, tmp);
cv::cvtColor(tmp, tmp, cv::COLOR_Lab2BGR);
tmp.convertTo(tmp, _lumImage.depth(), 1/_scale);
cv::imwrite(path.toStdString(), tmp);
} }
void CLAHE::apply(float clipLimit, int kernelSize) void CLAHE::apply(float clipLimit, int kernelSize)
{ {
cv::Mat lum; cv::Mat lum;
_clahe->setClipLimit(clipLimit); cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(clipLimit, cv::Size(kernelSize, kernelSize));
_clahe->setTilesGridSize(cv::Size(kernelSize, kernelSize)); clahe->apply(_lumImage, lum);
_clahe->apply(_lumImage, lum); lum.convertTo(_image[0], CV_32F, 100*_scale);
//lum = _lumImage;
lum.convertTo(_image[0], CV_32F, 1.0/655.35);
double min, max; double min, max;
cv::minMaxLoc(_image[0], &min, &max); cv::minMaxLoc(_image[0], &min, &max);
qDebug() << min << max; qDebug() << min << max;
@@ -44,7 +44,15 @@ QPixmap CLAHE::getImage() const
cv::merge(_image, 3, tmp); cv::merge(_image, 3, tmp);
cv::cvtColor(tmp, tmp, cv::COLOR_Lab2RGB); cv::cvtColor(tmp, tmp, cv::COLOR_Lab2RGB);
tmp.convertTo(tmp, CV_8U, 255); tmp.convertTo(tmp, CV_8U, 255);
QImage ret(tmp.data, tmp.cols, tmp.rows, tmp.step, QImage::Format_RGB888); QImage ret(tmp.data, tmp.cols, tmp.rows, tmp.step1(), QImage::Format_RGB888);
//ret.bits();//perform deep copy of tmp.data pointer //ret.bits();//perform deep copy of tmp.data pointer
return QPixmap::fromImage(ret); return QPixmap::fromImage(ret);
} }
QPixmap CLAHE::getLumImage() const
{
cv::Mat tmp;
_image[0].convertTo(tmp, CV_8U, 2.55);
QImage ret(tmp.data, tmp.cols, tmp.rows, tmp.step1(), QImage::Format_Grayscale8);
return QPixmap::fromImage(ret);
}
+2 -1
View File
@@ -11,13 +11,14 @@ class CLAHE
{ {
cv::Mat _lumImage; cv::Mat _lumImage;
cv::Mat _image[3]; cv::Mat _image[3];
cv::Ptr<cv::CLAHE> _clahe; double _scale;
public: public:
CLAHE(); CLAHE();
void loadFile(const QString &path); void loadFile(const QString &path);
void saveFile(const QString &path); void saveFile(const QString &path);
void apply(float clipLimit, int kernelSize); void apply(float clipLimit, int kernelSize);
QPixmap getImage() const; QPixmap getImage() const;
QPixmap getLumImage() const;
}; };
#endif // CLAHE_H #endif // CLAHE_H
+4 -2
View File
@@ -29,11 +29,13 @@ PKGCONFIG += opencv
SOURCES += \ SOURCES += \
main.cpp \ main.cpp \
mainwindow.cpp \ mainwindow.cpp \
clahe.cpp clahe.cpp \
imagescrollarea.cpp
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
clahe.h clahe.h \
imagescrollarea.h
# Default rules for deployment. # Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin qnx: target.path = /tmp/$${TARGET}/bin
+121
View File
@@ -0,0 +1,121 @@
#include "imagescrollarea.h"
#include <QMouseEvent>
#include <QScrollBar>
#include <QKeyEvent>
#include <QPalette>
#include <QDebug>
ImageScrollArea::ImageScrollArea(QWidget *parent) : QScrollArea(parent),
m_scale(-1)
{
m_label = new QLabel(this);
setWidget(m_label);
setAlignment(Qt::AlignCenter);
setBackgroundRole(QPalette::Dark);
}
void ImageScrollArea::setImage(const QPixmap &img)
{
m_pixmap = img;
QPixmap pix;
if(m_scale < 0)
pix = img.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
else
pix = img.scaled(img.size() * m_scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);
m_label->setPixmap(pix);
m_label->resize(pix.size());
horizontalScrollBar()->setValue(horizontalScrollBar()->maximum() / 2);
verticalScrollBar()->setValue(verticalScrollBar()->maximum() / 2);
}
void ImageScrollArea::setScale(float scale)
{
if(scale > 4 || (scale < 0.2 && scale > 0) || m_pixmap.isNull())
return;
m_scale = scale;
QSize newSize = m_scale < 0 ? size() : m_pixmap.size()*scale;
m_label->setPixmap(m_pixmap.scaled(newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
m_label->resize(newSize);
}
void ImageScrollArea::zoomIn()
{
if(m_scale < 0)
m_scale = (float)size().width()/m_pixmap.size().width();
setScale(m_scale + 0.1);
}
void ImageScrollArea::zoomOut()
{
if(m_scale < 0)
m_scale = (float)size().width()/m_pixmap.size().width();
setScale(m_scale - 0.1);
}
void ImageScrollArea::bestFit()
{
setScale(-1);
}
void ImageScrollArea::oneToOne()
{
setScale(1);
}
void ImageScrollArea::keyPressEvent(QKeyEvent *event)
{
event->ignore();
}
void ImageScrollArea::keyReleaseEvent(QKeyEvent *event)
{
event->ignore();
}
void ImageScrollArea::mouseMoveEvent(QMouseEvent *event)
{
QPoint delta = m_lastPos - event->pos();
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + delta.x());
verticalScrollBar()->setValue(verticalScrollBar()->value() + delta.y());
m_lastPos = event->pos();
}
void ImageScrollArea::mousePressEvent(QMouseEvent *event)
{
m_lastPos = event->pos();
}
void ImageScrollArea::resizeEvent(QResizeEvent *event)
{
if(m_scale < 0 && !m_pixmap.isNull())
{
m_label->setPixmap(m_pixmap.scaled(event->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
m_label->resize(event->size());
}
QScrollArea::resizeEvent(event);
}
void ImageScrollArea::wheelEvent(QWheelEvent *event)
{
if(m_scale < 0)
m_scale = (float)size().width()/m_pixmap.size().width();
QPointF top(horizontalScrollBar()->value(), verticalScrollBar()->value());
QPointF mousePos = (top + event->posF()) / m_scale;
QPoint delta = event->angleDelta();
if(delta.y() > 0)
setScale(m_scale + 0.1);
else
setScale(m_scale - 0.1);
mousePos *= m_scale;
top = mousePos - event->posF();
horizontalScrollBar()->setValue(top.x());
verticalScrollBar()->setValue(top.y());
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef IMAGESCROLLAREA_H
#define IMAGESCROLLAREA_H
#include <QScrollArea>
#include <QLabel>
class ImageScrollArea : public QScrollArea
{
Q_OBJECT
QPoint m_lastPos;
QLabel *m_label;
QPixmap m_pixmap;
float m_scale;
public:
explicit ImageScrollArea(QWidget *parent = 0);
void setImage(const QPixmap &img);
void setScale(float scale);
public slots:
void zoomIn();
void zoomOut();
void bestFit();
void oneToOne();
protected:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void resizeEvent(QResizeEvent *event);
void wheelEvent(QWheelEvent *event);
};
#endif // IMAGESCROLLAREA_H
+59 -9
View File
@@ -2,36 +2,53 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QFileDialog> #include <QFileDialog>
#include <QMenuBar> #include <QMenuBar>
#include <QPushButton>
#include <QLineEdit>
#include <QDockWidget>
#include <QHBoxLayout>
#include "clahe.h" #include "clahe.h"
const QString imageFilter = "Images (*.png *.jpg *.jpeg);;All files (*)";
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{ {
setupUI(); setupUI();
_clahe = new CLAHE;
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete _clahe;
} }
void MainWindow::openFile() void MainWindow::openFile()
{ {
QStringList list = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::PicturesLocation); QStringList list = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::PicturesLocation);
list.append(""); list.append("");
QString path = QFileDialog::getOpenFileName(this, tr("Open image"), list.first(), tr("Images (*.png *.jpg *.jpeg);;All files (*)")); QString path = QFileDialog::getOpenFileName(this, tr("Open image"), list.first(), imageFilter);
if(!path.isEmpty()) if(!path.isEmpty())
{ {
CLAHE cl; _clahe->loadFile(path);
cl.loadFile(path); applyClahe();
cl.apply(5, 64);
QPixmap pixmap;
pixmap = cl.getImage();
_image->setPixmap(pixmap);
} }
} }
void MainWindow::saveFile() void MainWindow::saveFile()
{ {
QStringList list = QStandardPaths::standardLocations(QStandardPaths::StandardLocation::PicturesLocation);
QString path = QFileDialog::getSaveFileName(this, tr("Save image"), list.first(), imageFilter);
if(!path.isEmpty())
{
_clahe->saveFile(path);
}
}
void MainWindow::applyClahe()
{
QPixmap pixmap;
_clahe->apply(_clipLimitSlider->value()/100.0f, _kernelSizeSelect->currentText().toInt());
pixmap = _clahe->getImage();
_imageScrollArea->setImage(pixmap);
} }
void MainWindow::setupUI() void MainWindow::setupUI()
@@ -43,6 +60,39 @@ void MainWindow::setupUI()
fileMenu->addAction(tr("Save file"), this, SLOT(saveFile()), QKeySequence("Ctrl+S")); fileMenu->addAction(tr("Save file"), this, SLOT(saveFile()), QKeySequence("Ctrl+S"));
fileMenu->addAction(tr("Quit"), this, SLOT(close()), QKeySequence("Ctrl+Q")); fileMenu->addAction(tr("Quit"), this, SLOT(close()), QKeySequence("Ctrl+Q"));
_image = new QLabel(this); _clipLimitEdit = new QLineEdit;
setCentralWidget(_image); _clipLimitEdit->setInputMask("000.00");
_clipLimitEdit->setText("1.00");
_clipLimitEdit->setMaximumWidth(100);
_clipLimitSlider = new QSlider(Qt::Horizontal);
_clipLimitSlider->setRange(0, 10000);
_clipLimitSlider->setValue(100);
connect(_clipLimitSlider, SIGNAL(valueChanged(int)), this, SLOT(clipSliderValueChanged(int)));
QPushButton *applyButton = new QPushButton(tr("Apply"));
connect(applyButton, SIGNAL(clicked()), this, SLOT(applyClahe()));
_kernelSizeSelect = new QComboBox;
_kernelSizeSelect->addItems({"8", "16", "32", "64", "128", "256"});
QHBoxLayout *claheLayout = new QHBoxLayout;
claheLayout->addWidget(_clipLimitEdit);
claheLayout->addWidget(_clipLimitSlider);
claheLayout->addWidget(_kernelSizeSelect);
claheLayout->addWidget(applyButton);
QDockWidget *claheDock = new QDockWidget(tr("CLAHE"), this);
QWidget *claheWidget = new QWidget(claheDock);
claheDock->setWidget(claheWidget);
claheWidget->setLayout(claheLayout);
addDockWidget(Qt::TopDockWidgetArea, claheDock);
_imageScrollArea = new ImageScrollArea(this);
setCentralWidget(_imageScrollArea);
}
void MainWindow::clipSliderValueChanged(int value)
{
_clipLimitEdit->setText(QString::number(value/100.0));
} }
+11 -1
View File
@@ -3,19 +3,29 @@
#include <QMainWindow> #include <QMainWindow>
#include <QLabel> #include <QLabel>
#include <QComboBox>
#include "clahe.h"
#include "imagescrollarea.h"
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
QLabel *_image; QComboBox *_kernelSizeSelect;
QSlider *_clipLimitSlider;
QLineEdit *_clipLimitEdit;
CLAHE *_clahe;
ImageScrollArea *_imageScrollArea;
public: public:
explicit MainWindow(QWidget *parent = nullptr); explicit MainWindow(QWidget *parent = nullptr);
~MainWindow(); ~MainWindow();
public slots: public slots:
void openFile(); void openFile();
void saveFile(); void saveFile();
void applyClahe();
private: private:
void setupUI(); void setupUI();
private slots:
void clipSliderValueChanged(int value);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H