diff --git a/image.frag b/image.frag index 40b9836..6e4a59f 100644 --- a/image.frag +++ b/image.frag @@ -12,7 +12,7 @@ void main(void) vec4 color = texture2D(qt_Texture0, qt_TexCoord0); if(bw)color = color.rrra; color = color*scale.x + scale.y; - max(color, vec4(0.0f)); + color = max(color, vec4(0.0f)); switch(stretch) { @@ -30,7 +30,7 @@ void main(void) case 4: { //float l = color.r*0.2126f + color.g*0.7152f + color.b*0.0722f; - float l = (color.r+color.g+color.b)*0.33333f; + float l = (color.r+color.g+color.b)*0.33333; float k = asinh(l*a)/(l*asinh(a)); color *= k; } @@ -39,5 +39,7 @@ void main(void) //color = color*scale.x + scale.y; //float color = pow(c, 0.4545); + if(any(lessThan(qt_TexCoord0, vec2(0.0))) || any(greaterThan(qt_TexCoord0, vec2(1.0)))) + color = vec4(0.0); gl_FragColor = color; } diff --git a/imagescrollareagl.cpp b/imagescrollareagl.cpp index 1ef3a78..238760c 100644 --- a/imagescrollareagl.cpp +++ b/imagescrollareagl.cpp @@ -20,6 +20,7 @@ const RawImageType rawImageTypes[] = { {QOpenGLTexture::Red, QOpenGLTexture::R16_UNorm, QOpenGLTexture::UInt16, true}, {QOpenGLTexture::Red, QOpenGLTexture::R32F, QOpenGLTexture::Float32, true}, {QOpenGLTexture::RGB, QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, false}, + {QOpenGLTexture::BGRA,QOpenGLTexture::RGB8_UNorm, QOpenGLTexture::UInt8, false}, {QOpenGLTexture::RGB, QOpenGLTexture::RGB16_UNorm, QOpenGLTexture::UInt16, false}, {QOpenGLTexture::RGB, QOpenGLTexture::RGB32F, QOpenGLTexture::Float32, false} }; @@ -68,7 +69,7 @@ void ImageWidget::setImage(RawImage *image) m_image->setSize(image->width(), image->height()); m_image->allocateStorage(); m_image->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear); - m_image->setWrapMode(QOpenGLTexture::ClampToBorder); + m_image->setWrapMode(QOpenGLTexture::ClampToEdge); m_image->setBorderColor(0, 0, 0, 0); m_image->setData(0, rawImageType.pixelFormat, rawImageType.dataType, image->data(), m_transferOptions.get()); m_image->generateMipMaps(); @@ -241,6 +242,7 @@ void ImageWidget::initializeGL() m_program->setUniformValue("scale", 1.0f, 0.0f); m_image = std::unique_ptr(new QOpenGLTexture(QOpenGLTexture::Target2D)); + m_image->setFormat(QOpenGLTexture::RGB8U); m_image->allocateStorage(); m_image->bind(0); m_image->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); diff --git a/loadrunable.cpp b/loadrunable.cpp index 38352fa..169868c 100644 --- a/loadrunable.cpp +++ b/loadrunable.cpp @@ -257,6 +257,9 @@ void LoadRunable::run() rawImage = new RawImage(img); } + if(rawImage) + rawImage->calcStats(); + if(rawImage && m_analyzeLevel >= Statistics) { double mean, median, min, max; diff --git a/mainwindow.cpp b/mainwindow.cpp index 4539e25..1218e67 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -65,6 +65,7 @@ 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))); diff --git a/rawimage.cpp b/rawimage.cpp index c1075ec..c2fd18c 100644 --- a/rawimage.cpp +++ b/rawimage.cpp @@ -14,6 +14,8 @@ RawImage::ImgType CV2Type(int cvtype) return RawImage::FLOAT32; case CV_8UC3: return RawImage::UINT8C3; + case CV_8UC4: + return RawImage::UINT8C4; case CV_16UC3: return RawImage::UINT16C3; case CV_32FC3: @@ -35,6 +37,8 @@ int Type2CV(RawImage::ImgType type) return CV_32F; case RawImage::UINT8C3: return CV_8UC3; + case RawImage::UINT8C4: + return CV_8UC4; case RawImage::UINT16C3: return CV_16UC3; case RawImage::FLOAT32C3: @@ -58,29 +62,56 @@ RawImage::RawImage(int w, int h, ImgType type) RawImage::RawImage(cv::Mat &img) { m_img = img; + calcStats(); } RawImage::RawImage(const RawImage &d) { d.m_img.copyTo(m_img); + m_mean = d.m_mean; + m_stdDev = d.m_stdDev; + m_median = d.m_median; + m_min = d.m_min; + m_max = d.m_max; } RawImage::RawImage(const QImage &img) { - QImage tmp = img.convertToFormat(QImage::Format_RGB888); - m_img.create(img.height(), img.width(), CV_8UC3); + if(img.format() == QImage::Format_RGB32) + { + m_img.create(img.height(), img.width(), CV_8UC4); + for(int i=0; i(0, i); + if(medianSum >= halfImageSize) { - medianSum += hist.at(0, i); - if(medianSum >= halfImageSize) - { - *median = i; - break; - } + m_median = i; + break; + } + } + cv::Mat absDev = cv::abs(m_img-m_median); + cv::Mat madHist; + medianSum = 0; + cv::calcHist(&absDev, 1, nullptr, cv::Mat(), madHist, 1, &histSize, ranges); + for(int i=0; i < histSize; i++) + { + medianSum += madHist.at(0, i); + if(medianSum >= halfImageSize) + { + m_mad = i; + break; } } - - return true; } void RawImage::rect(int &x, int &y, int w, int h, std::vector &r) const @@ -187,3 +226,13 @@ const void *RawImage::data() const { return m_img.ptr(); } + +float RawImage::stretchFactor() const +{ + +} + +double RawImage::MAD() const +{ + return m_mad; +} diff --git a/rawimage.h b/rawimage.h index 6ac1042..25f82f2 100644 --- a/rawimage.h +++ b/rawimage.h @@ -35,6 +35,12 @@ class RawImage { protected: cv::Mat m_img; + double m_mean; + double m_stdDev; + double m_median; + double m_min; + double m_max; + double m_mad; public: enum ImgType { @@ -42,6 +48,7 @@ public: UINT16, FLOAT32, UINT8C3, + UINT8C4, UINT16C3, FLOAT32C3, UNKNOWN, @@ -52,6 +59,7 @@ public: RawImage(const RawImage &d); RawImage(const QImage &img); bool imageStats(double *mean, double *stdDev, double *median, double *min, double *max) const; + void calcStats(); void rect(int &x, int &y, int w, int h, std::vector &r) const; int findPeaks(double background, double distance, std::vector &peaks) const; RawImage* medianFilter() const; @@ -62,6 +70,8 @@ public: ImgType type() const; void* data(); const void* data() const; + float stretchFactor() const; + double MAD() const; }; #endif // RAWIMAGE_H diff --git a/stretchpanel.cpp b/stretchpanel.cpp index 3132ef0..e36ce25 100644 --- a/stretchpanel.cpp +++ b/stretchpanel.cpp @@ -1,5 +1,7 @@ #include "stretchpanel.h" #include +#include "imageringlist.h" +#include StretchPanel::StretchPanel(QWidget *parent) : QWidget(parent) { @@ -33,6 +35,24 @@ StretchPanel::StretchPanel(QWidget *parent) : QWidget(parent) connect(m_stretchSelect, SIGNAL(activated(int)), this, SLOT(calculateParam())); } +void StretchPanel::imageLoaded(Image *img) +{ + if(img) + { + if(img->rawImage()) + { + double mean, stdDev, median; + img->rawImage()->imageStats(&mean, &stdDev, &median, nullptr, nullptr); + double mad = img->rawImage()->MAD(); + float l = median - mad; + m_lowSlider->setValue(l); + float p = std::log(0.25)/std::log(mean/UINT16_MAX); + m_paramSlider->setValue(p * UINT16_MAX); + qDebug() << "Low" << l << p; + } + } +} + void StretchPanel::calculateParam() { float val = m_paramSlider->value(); @@ -40,14 +60,16 @@ void StretchPanel::calculateParam() switch(m_stretchSelect->currentIndex()) { case 2: - param = val*100/UINT16_MAX; + param = val/UINT16_MAX; + param = 1.0f / (param * 5.0f + 1); break; case 3: param = val; break; case 4: - val += 100; - param = val/100.0f; + param = 1.0f/std::max(0.00001f, 1.0f-(val/UINT16_MAX)); + //val += 100; + //param = val/100.0f; break; default: return; diff --git a/stretchpanel.h b/stretchpanel.h index eeb0bc5..09b0b88 100644 --- a/stretchpanel.h +++ b/stretchpanel.h @@ -5,6 +5,8 @@ #include #include +class Image; + class StretchPanel : public QWidget { Q_OBJECT @@ -14,6 +16,8 @@ class StretchPanel : public QWidget QComboBox *m_stretchSelect; public: explicit StretchPanel(QWidget *parent = nullptr); +public slots: + void imageLoaded(Image *img); signals: void lowChanged(int low); void highChanged(int high);