Add histogram
This commit is contained in:
@@ -33,6 +33,7 @@ set(TENMON_SRC
|
||||
databaseview.cpp databaseview.h
|
||||
delete.cpp
|
||||
filesystemwidget.cpp filesystemwidget.h
|
||||
histogram.cpp histogram.h
|
||||
imageinfo.cpp imageinfo.h
|
||||
imageringlist.cpp imageringlist.h
|
||||
imagescrollarea.cpp
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "histogram.h"
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
Histogram::Histogram(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setStyleSheet("QWidget { background: white; color: black; } ");
|
||||
}
|
||||
|
||||
void Histogram::imageLoaded(Image *img)
|
||||
{
|
||||
if(img && img->rawImage())
|
||||
{
|
||||
m_histogram = img->rawImage()->imageStats().m_histogram[0];
|
||||
m_points.clear();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void Histogram::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(rect(), Qt::black);
|
||||
|
||||
uint h = height();
|
||||
uint w = width();
|
||||
|
||||
if(m_histogram.size())
|
||||
{
|
||||
|
||||
if(m_points.size() != w)
|
||||
{
|
||||
m_points.clear();
|
||||
for(uint64_t i = 0; i < w; i++)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
uint64_t start = i * m_histogram.size() / w;
|
||||
uint64_t end =(i+1) * m_histogram.size() / w;
|
||||
for(uint64_t o = start; o < end; o++)
|
||||
sum += m_histogram[o];
|
||||
m_points.push_back(sum);
|
||||
}
|
||||
float scale = *std::max_element(m_points.begin(), m_points.end());
|
||||
if(m_log)
|
||||
{
|
||||
scale = std::log(scale);
|
||||
std::for_each(m_points.begin(), m_points.end(), [scale](float &x){ x = (x > 0 ? std::log(x) : 0.0f) / scale; });
|
||||
}
|
||||
else
|
||||
{
|
||||
std::for_each(m_points.begin(), m_points.end(), [scale](float &x){ x /= scale; });
|
||||
}
|
||||
}
|
||||
std::vector<QPointF> points;
|
||||
points.push_back(QPointF(0, h));
|
||||
for(size_t i = 0; i < m_points.size(); i++)
|
||||
{
|
||||
points.push_back(QPointF(i, h - m_points[i] * h));
|
||||
}
|
||||
points.push_back(QPoint(w, h));
|
||||
painter.setBrush(Qt::gray);
|
||||
painter.setPen(Qt::white);
|
||||
|
||||
painter.drawPolygon(&points[0], points.size());
|
||||
}
|
||||
|
||||
QStyleOptionButton button;
|
||||
button.initFrom(this);
|
||||
button.state = m_log ? QStyle::State_On : QStyle::State_Off;
|
||||
button.text = tr("Logarithmic scale");
|
||||
button.rect = style()->subElementRect(QStyle::SE_CheckBoxClickRect, &button, this);
|
||||
button.rect.moveTop(0);
|
||||
button.rect.moveRight(w);
|
||||
style()->drawControl(QStyle::CE_CheckBox, &button, &painter, this);
|
||||
}
|
||||
|
||||
void Histogram::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
m_log = !m_log;
|
||||
m_points.clear();
|
||||
update();
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#ifndef HISTOGRAM_H
|
||||
#define HISTOGRAM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "imageringlist.h"
|
||||
|
||||
class Histogram : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
std::vector<uint32_t> m_histogram;
|
||||
std::vector<float> m_points;
|
||||
bool m_log = false;
|
||||
public:
|
||||
explicit Histogram(QWidget *parent = nullptr);
|
||||
public slots:
|
||||
void imageLoaded(Image *img);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
};
|
||||
|
||||
#endif // HISTOGRAM_H
|
||||
+1
-1
Submodule libXISF updated: 0b0c865df0...8a1f305cc7
@@ -23,6 +23,7 @@
|
||||
#include "about.h"
|
||||
#include "statusbar.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "histogram.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ioctl.h>
|
||||
@@ -120,6 +121,13 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
databaseViewDock->hide();
|
||||
addDockWidget(Qt::LeftDockWidgetArea, filetreeDock);
|
||||
|
||||
Histogram *histogram = new Histogram(this);
|
||||
QDockWidget *histogramDock = new QDockWidget(tr("Histogram"), this);
|
||||
histogramDock->setWidget(histogram);
|
||||
histogramDock->setObjectName("histogramDock");
|
||||
histogramDock->show();
|
||||
addDockWidget(Qt::LeftDockWidgetArea, histogramDock);
|
||||
|
||||
setWindowTitle(tr("Tenmon"));
|
||||
|
||||
connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), this, SLOT(pixmapLoaded(Image*)));
|
||||
@@ -128,6 +136,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
connect(m_ringList, SIGNAL(currentImageChanged(int)), m_filesystem, SLOT(selectFile(int)));
|
||||
connect(m_ringList, &ImageRingList::thumbnailLoaded, m_imageGL->imageWidget(), &ImageWidget::thumbnailLoaded);
|
||||
connect(m_ringList, &ImageRingList::pixmapLoaded, m_stretchPanel, &StretchToolbar::imageLoaded);
|
||||
connect(m_ringList, &ImageRingList::pixmapLoaded, histogram, &Histogram::imageLoaded);
|
||||
connect(m_imageGL->imageWidget(), &ImageWidget::fileDropped, this, static_cast<void (MainWindow::*)(const QString &)>(&MainWindow::loadFile));
|
||||
|
||||
QMenu *fileMenu = new QMenu(tr("File"), this);
|
||||
@@ -207,6 +216,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
dockMenu->addAction(filesystemDock->toggleViewAction());
|
||||
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
||||
dockMenu->addAction(filetreeDock->toggleViewAction());
|
||||
dockMenu->addAction(histogramDock->toggleViewAction());
|
||||
menuBar()->addMenu(dockMenu);
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("Help"));
|
||||
|
||||
@@ -197,6 +197,9 @@ void calcStats(const T *data, size_t n, RawImage::Stats &stats)
|
||||
stats.m_mad[i] /= 65535.0;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < ch; i++)
|
||||
stats.m_histogram[i] = std::vector<uint32_t>(histogram[i], histogram[i] + histSize);
|
||||
}
|
||||
|
||||
void RawImage::calcStats()
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
double m_max[4] = {0.0};
|
||||
double m_mad[4] = {0.0};
|
||||
uint32_t m_saturated[4] = {0};
|
||||
std::vector<uint32_t> m_histogram[4];
|
||||
};
|
||||
protected:
|
||||
std::unique_ptr<PixelType[]> m_pixels;
|
||||
|
||||
Reference in New Issue
Block a user