Stretch and calculate stats on demand
This commit is contained in:
+3
-5
@@ -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
@@ -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)));
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user