Stretch and calculate stats on demand

This commit is contained in:
2022-04-06 15:49:58 +02:00
parent 2ff1b993a1
commit 023a616fa0
7 changed files with 63 additions and 37 deletions
+3 -5
View File
@@ -257,21 +257,19 @@ void LoadRunable::run()
rawImage = new RawImage(img);
}
if(rawImage)
rawImage->calcStats();
if(rawImage && m_analyzeLevel >= Statistics)
{
double mean, median, min, max;
double mean, median, min, max, mad;
double stdDev;
timer.start();
rawImage->imageStats(&mean, &stdDev, &median, &min, &max);
rawImage->imageStats(&mean, &stdDev, &median, &min, &max, &mad);
qDebug() << "image stats" << timer.restart();
info.append(StringPair(QObject::tr("Mean"), QString::number(mean)));
info.append(StringPair(QObject::tr("Standart deviation"), QString::number(stdDev)));
info.append(StringPair(QObject::tr("Median"), QString::number(median)));
info.append(StringPair(QObject::tr("Minimum"), QString::number(min)));
info.append(StringPair(QObject::tr("Maximum"), QString::number(max)));
info.append(StringPair(QObject::tr("MAD"), QString::number(mad)));
if(m_analyzeLevel >= Peaks)
{
+6 -7
View File
@@ -1,5 +1,4 @@
#include "mainwindow.h"
#include "stretchpanel.h"
#include <QScrollArea>
#include <QDir>
#include <QKeyEvent>
@@ -34,23 +33,24 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
infoDock->setWidget(m_info);
infoDock->setObjectName("infoDock");
addDockWidget(Qt::LeftDockWidgetArea, infoDock);
m_image = new ImageScrollArea(this);
m_image->resize(0,0);
//m_image = new ImageScrollArea(this);
//m_image->resize(0,0);
//setCentralWidget(m_image);
resize(800, 600);
m_imageGL = new ImageScrollAreaGL(this);
setCentralWidget(m_imageGL);
StretchPanel *stretchPanel = new StretchPanel(this);
connect(stretchPanel, SIGNAL(paramChanged(float,float,float)), m_imageGL->imageWidget(), SLOT(setMTFParams(float,float,float)));
m_stretchPanel = new StretchPanel(this);
connect(m_stretchPanel, SIGNAL(paramChanged(float,float,float)), m_imageGL->imageWidget(), SLOT(setMTFParams(float,float,float)));
connect(m_stretchPanel, &StretchPanel::autoStretch, [&](){ m_stretchPanel->stretchImage(m_ringList->currentImage().get()); });
m_ringList = new ImageRingList(this);
m_filesystem = new FilesystemWidget(m_ringList, this);
connect(m_filesystem, SIGNAL(fileSelected(int)), this, SLOT(loadFile(int)));
QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this);
stretchDock->setWidget(stretchPanel);
stretchDock->setWidget(m_stretchPanel);
stretchDock->setObjectName("strechDock");
addDockWidget(Qt::TopDockWidgetArea, stretchDock);
@@ -62,7 +62,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
setWindowTitle(tr("Tenmon"));
connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), this, SLOT(pixmapLoaded(Image*)));
connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), stretchPanel, SLOT(imageLoaded(Image*)));
connect(m_ringList, SIGNAL(currentImageChanged(int)), this, SLOT(updateWindowTitle()));
connect(m_ringList, SIGNAL(infoLoaded(ImageInfoData)), m_info, SLOT(setInfo(ImageInfoData)));
connect(m_ringList, SIGNAL(currentImageChanged(int)), m_filesystem, SLOT(selectFile(int)));
+2
View File
@@ -9,6 +9,7 @@
#include "imageinfo.h"
#include "imagescrollareagl.h"
#include "filesystemwidget.h"
#include "stretchpanel.h"
class MainWindow : public QMainWindow
{
@@ -16,6 +17,7 @@ class MainWindow : public QMainWindow
ImageScrollArea *m_image;
ImageScrollAreaGL *m_imageGL;
ImageRingList *m_ringList;
StretchPanel *m_stretchPanel;
Database *m_database;
ImageInfo *m_info;
FilesystemWidget *m_filesystem;
+37 -16
View File
@@ -52,17 +52,19 @@ int Type2CV(RawImage::ImgType type)
RawImage::RawImage()
{
m_stats = false;
}
RawImage::RawImage(int w, int h, ImgType type)
{
m_img.create(h, w, Type2CV(type));
m_stats = false;
}
RawImage::RawImage(cv::Mat &img)
{
m_img = img;
calcStats();
m_stats = false;
}
RawImage::RawImage(const RawImage &d)
@@ -73,6 +75,8 @@ RawImage::RawImage(const RawImage &d)
m_median = d.m_median;
m_min = d.m_min;
m_max = d.m_max;
m_mad = d.m_mad;
m_stats = d.m_stats;
}
RawImage::RawImage(const QImage &img)
@@ -91,33 +95,44 @@ RawImage::RawImage(const QImage &img)
for(int i=0; i<tmp.height(); i++)
std::memcpy(m_img.ptr(i), tmp.scanLine(i), tmp.width()*3);
}
calcStats();
m_stats = false;
}
bool RawImage::imageStats(double *mean, double *stdDev, double *median, double *min, double *max) const
bool RawImage::imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad)
{
if(!m_stats)calcStats();
if(mean)*mean = m_mean;
if(stdDev)*stdDev = m_stdDev;
if(median)*median = m_median;
if(min)*min = m_min;
if(max)*max = m_max;
if(mad)*mad = m_mad;
return true;
}
void RawImage::calcStats()
{
if(m_stats)return;
m_stats = true;
cv::Scalar meanS, stdDevS;
cv::meanStdDev(m_img, meanS, stdDevS);
cv::minMaxIdx(m_img, &m_min, &m_max);
cv::Mat img;
if(m_img.channels() == 1)img = m_img;
else if (m_img.channels() == 3)cv::cvtColor(m_img, img, cv::COLOR_BGR2GRAY);
else if (m_img.channels() == 4)cv::cvtColor(m_img, img, cv::COLOR_BGRA2GRAY);
int histSize = 256;
if(m_img.type() == CV_16U || m_img.type() == CV_32F)histSize = 65536;
if(img.type() == CV_16U || img.type() == CV_32F)histSize = 65536;
float range[] = {0, (float)histSize};
if(img.type() == CV_32F)range[1] = 1.0f;
const float *ranges[] = {range};
cv::Mat hist;
cv::calcHist(&m_img, 1, nullptr, cv::Mat(), hist, 1, &histSize, ranges);
cv::calcHist(&img, 1, nullptr, cv::Mat(), hist, 1, &histSize, ranges);
m_mean = meanS[0];
m_stdDev = stdDevS[0];
@@ -133,7 +148,7 @@ void RawImage::calcStats()
}
}
cv::Mat absDev;
m_img.convertTo(absDev, CV_32F, 1, -m_median);
img.convertTo(absDev, CV_32F, 1, -m_median);
absDev = cv::abs(absDev);
cv::Mat madHist;
medianSum = 0;
@@ -218,6 +233,22 @@ RawImage::ImgType RawImage::type() const
return CV2Type(m_img.type());
}
uint32_t RawImage::norm() const
{
switch(m_img.type())
{
case CV_8U:
case CV_8UC3:
case CV_8UC4:
return UINT8_MAX;
case CV_16U:
case CV_16UC3:
return UINT16_MAX;
default:
return 1;
}
}
void* RawImage::data()
{
return m_img.ptr();
@@ -227,13 +258,3 @@ const void *RawImage::data() const
{
return m_img.ptr();
}
float RawImage::stretchFactor() const
{
}
double RawImage::MAD() const
{
return m_mad;
}
+3 -3
View File
@@ -35,6 +35,7 @@ class RawImage
{
protected:
cv::Mat m_img;
bool m_stats;
double m_mean;
double m_stdDev;
double m_median;
@@ -58,7 +59,7 @@ public:
RawImage(cv::Mat &img);
RawImage(const RawImage &d);
RawImage(const QImage &img);
bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max) const;
bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max, double *mad);
void calcStats();
void rect(int &x, int &y, int w, int h, std::vector<double> &r) const;
int findPeaks(double background, double distance, std::vector<Peak> &peaks) const;
@@ -68,10 +69,9 @@ public:
uint32_t height() const;
uint32_t size() const;
ImgType type() const;
uint32_t norm() const;
void* data();
const void* data() const;
float stretchFactor() const;
double MAD() const;
};
#endif // RAWIMAGE_H
+10 -5
View File
@@ -28,18 +28,23 @@ StretchPanel::StretchPanel(QWidget *parent) : QWidget(parent)
resetButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
layout->addWidget(resetButton);
connect(resetButton, SIGNAL(pressed()), this, SLOT(resetMTF()));
QPushButton *autoStretchButton = new QPushButton(tr("Autostretch"), this);
autoStretchButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
layout->addWidget(autoStretchButton);
connect(autoStretchButton, SIGNAL(pressed()), this, SIGNAL(autoStretch()));
}
void StretchPanel::imageLoaded(Image *img)
void StretchPanel::stretchImage(Image *img)
{
if(img)
{
if(img->rawImage())
{
double mean, stdDev, median;
img->rawImage()->imageStats(&mean, &stdDev, &median, nullptr, nullptr);
median /= 65536;
double mad = img->rawImage()->MAD() / 65536;
double median, mad;
img->rawImage()->imageStats(nullptr, nullptr, &median, nullptr, nullptr, &mad);
median /= img->rawImage()->norm();
mad /= img->rawImage()->norm();
float bp = median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA;
float mid = MTF(median - bp, TARGET_BACKGROUND);
m_stfSlider->setMTFParams(bp, mid, 1.0f);
+2 -1
View File
@@ -13,10 +13,11 @@ class StretchPanel : public QWidget
public:
explicit StretchPanel(QWidget *parent = nullptr);
public slots:
void imageLoaded(Image *img);
void stretchImage(Image *img);
void resetMTF();
signals:
void paramChanged(float low, float mid, float high);
void autoStretch();
};
#endif // STRETCHPANEL_H