Add histogram

This commit is contained in:
2023-11-13 21:12:23 +01:00
parent 0a803ace10
commit 46b0210078
7 changed files with 122 additions and 1 deletions
+1
View File
@@ -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
+84
View File
@@ -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
View File
@@ -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
+10
View File
@@ -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"));
+3
View File
@@ -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()
+1
View File
@@ -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;