#include "stretchtoolbar.h" #include #include #include #include #include #include "imageringlist.h" const float BLACK_POINT_SIGMA = -2.8f; const float MAD_TO_SIGMA = 1.4826f; const float TARGET_BACKGROUND = 0.25f; float MTF(float x, float m) { if(x < 0)return 0; if(x > 1)return 1; return ((m - 1) * x) / ((2 * m - 1) * x - m); } StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar"), parent) { setObjectName("stretchtoolbar"); QWidget *lum = new QWidget(this); QVBoxLayout *vbox1 = new QVBoxLayout(lum); m_stfSlider = new STFSlider(Qt::white, this); vbox1->addWidget(m_stfSlider); m_stfSliderR = new STFSlider(Qt::red, this); m_stfSliderG = new STFSlider(Qt::green, this); m_stfSliderB = new STFSlider(Qt::blue, this); QWidget *rgb = new QWidget(this); QVBoxLayout *vbox2 = new QVBoxLayout(rgb); vbox2->setSpacing(0); vbox2->addWidget(m_stfSliderR); vbox2->addWidget(m_stfSliderG); vbox2->addWidget(m_stfSliderB); m_stack = new QStackedWidget(this); m_stack->addWidget(lum); m_stack->addWidget(rgb); m_stack->setCurrentIndex(0); addWidget(m_stack); connect(m_stfSlider, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){ m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = blackPoint; m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = midPoint; m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = whitePoint; emit paramChanged(m_mtfParam); }); connect(m_stfSliderR, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){ m_mtfParam.blackPoint[0] = blackPoint; m_mtfParam.midPoint[0] = midPoint; m_mtfParam.whitePoint[0] = whitePoint; emit paramChanged(m_mtfParam); }); connect(m_stfSliderG, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){ m_mtfParam.blackPoint[1] = blackPoint; m_mtfParam.midPoint[1] = midPoint; m_mtfParam.whitePoint[1] = whitePoint; emit paramChanged(m_mtfParam); }); connect(m_stfSliderB, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){ m_mtfParam.blackPoint[2] = blackPoint; m_mtfParam.midPoint[2] = midPoint; m_mtfParam.whitePoint[2] = whitePoint; emit paramChanged(m_mtfParam); }); QAction *rgbStretch = addAction(QIcon(":/link.png"), tr("Linked channels")); rgbStretch->setCheckable(true); rgbStretch->setChecked(true); connect(rgbStretch, &QAction::toggled, this, &StretchToolbar::unlinkStretch); QAction *autoStretchButton = addAction(QIcon(":/nuke.png"), tr("Auto Stretch F12")); autoStretchButton->setShortcut(Qt::Key_F12); connect(autoStretchButton, &QAction::triggered, this, &StretchToolbar::autoStretch); QAction *resetButton = addAction(style()->standardIcon(QStyle::SP_DialogResetButton), tr("Reset Screen Transfer Function F11")); resetButton->setShortcut(Qt::Key_F11); connect(resetButton, &QAction::triggered, this, &StretchToolbar::resetMTF); QAction *invertButton = addAction(QIcon(":/invert.png"), tr("Invert colors")); invertButton->setCheckable(true); connect(invertButton, &QAction::toggled, this, &StretchToolbar::invert); QAction *falseColorButton = addAction(QIcon(":/falsecolor.png"), tr("False colors")); falseColorButton->setCheckable(true); connect(falseColorButton, &QAction::toggled, this, &StretchToolbar::falseColor); m_debayer = addAction(QIcon(":/bayer.png"), tr("Debayer CFA")); m_debayer->setCheckable(true); connect(m_debayer, &QAction::toggled, this, &StretchToolbar::superPixel); m_autoStretchOnLoad = addAction(QIcon(":/nuke_a.png"), tr("Apply auto stretch on load")); m_autoStretchOnLoad->setCheckable(true); QSettings settings; m_autoStretchOnLoad->setChecked(settings.value("stretchtoolbar/autostretch", false).toBool()); } StretchToolbar::~StretchToolbar() { QSettings settings; settings.setValue("stretchtoolbar/autostretch", m_autoStretchOnLoad->isChecked()); } void StretchToolbar::stretchImage(Image *img) { if(img && img->rawImage()) { m_mtfParam = img->rawImage()->calcMTFParams(m_stack->currentIndex() == 0, m_stack->currentIndex() == 1 && img->rawImage()->channels() == 1 && m_debayer->isChecked()); if(m_stack->currentIndex() == 0) { m_stfSlider->setMTFParams(m_mtfParam.blackPoint[0], m_mtfParam.midPoint[0], m_mtfParam.whitePoint[0]); } else { m_stfSliderR->setMTFParams(m_mtfParam.blackPoint[0], m_mtfParam.midPoint[0], m_mtfParam.whitePoint[0]); m_stfSliderG->setMTFParams(m_mtfParam.blackPoint[1], m_mtfParam.midPoint[1], m_mtfParam.whitePoint[1]); m_stfSliderB->setMTFParams(m_mtfParam.blackPoint[2], m_mtfParam.midPoint[2], m_mtfParam.whitePoint[2]); } emit paramChanged(m_mtfParam); } } void StretchToolbar::resetMTF() { MTFParam params; m_mtfParam = params; if(m_stack->currentIndex() == 0) { m_stfSlider->setMTFParams(0, 0.5, 1); } else { m_stfSliderR->setMTFParams(0, 0.5, 1); m_stfSliderG->setMTFParams(0, 0.5, 1); m_stfSliderB->setMTFParams(0, 0.5, 1); } emit paramChanged(params); } void StretchToolbar::imageLoaded(Image *img) { if(m_autoStretchOnLoad->isChecked()) stretchImage(img); } void StretchToolbar::unlinkStretch(bool enable) { if(!enable) { m_stack->setCurrentIndex(1); m_mtfParam.blackPoint[0] = m_stfSliderR->blackPoint(); m_mtfParam.midPoint[0] = m_stfSliderR->midPoint(); m_mtfParam.whitePoint[0] = m_stfSliderR->whitePoint(); m_mtfParam.blackPoint[1] = m_stfSliderG->blackPoint(); m_mtfParam.midPoint[1] = m_stfSliderG->midPoint(); m_mtfParam.whitePoint[1] = m_stfSliderG->whitePoint(); m_mtfParam.blackPoint[2] = m_stfSliderB->blackPoint(); m_mtfParam.midPoint[2] = m_stfSliderB->midPoint(); m_mtfParam.whitePoint[2] = m_stfSliderB->whitePoint(); } else { m_stack->setCurrentIndex(0); m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = m_stfSlider->blackPoint(); m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = m_stfSlider->midPoint(); m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = m_mtfParam.whitePoint[2] = m_stfSlider->whitePoint(); } emit paramChanged(m_mtfParam); }