From fa69f17e5147c7738ec6316aabd12c61224152d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Tue, 14 Nov 2023 12:08:28 +0100 Subject: [PATCH] Support for unlinked stretch --- link.png | Bin 0 -> 2215 bytes resources.qrc | 1 + stretchtoolbar.cpp | 138 ++++++++++++++++++++++++++++----------------- stretchtoolbar.h | 1 + 4 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 link.png diff --git a/link.png b/link.png new file mode 100644 index 0000000000000000000000000000000000000000..b11d3ba4be973a0bab84adb7b6c3800353e74464 GIT binary patch literal 2215 zcmV;Y2w3-tP)EX>4Tx04R}tkv&MmKpe$iTSci=2Rn#3M5s;{#ELj-6^c+H)C#RSm|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfb#YR3krMxx6k5c1aNLh~_a1le0DryARI_6OP&La) zCE`LRyDD_Oq6d8lB8Cx(nfjb4CgC~0?&0I>U6f~epZjz4Dmjw@K7n|a>4rtTK|H-_ z>74h8!>lMN#OK8023?T&k?XR{Z=4Gb`*~*ANT=qB!^A?Njpa6GMMEW?B917kM*04X z%L?Z$&T6^Jn)l={4CSWO9|j z$gzM5R7j2={11M2YvyBOtZfqn+bBaeUO>!00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=L-%BHWnboW=a4602y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00w_aL_t(o!`)WRYh2eAKll6I_o?}Kde+#I>@gY@e=Jm- zO`+{38yiD5P9Z5JH6eurQ)gQm=&H~^Ae2IBi_<27f}t%9PHZI$JB32iLJJL;B9kK7 z79+_WNi*}_n|I$mUDOj)DqC`FZ+hS^-sPP8JNKP)e)mVb83L)M;aNqzN z$Fs))7eX8tLcC81IYbD7@yfDnT?p}KDdk$8=MBafud4sF0V1As&i$(_%RfGDqa6=| zU|A`J#u((Bqm;4`LcHPoelYf1ofbJ(45y`P*$G#HB@$;LTo8WmKP)cELZtljp zbLT!mM6%ZzN~tr9F+fDPKN0`fR|0c$a|ag|7Jg-|{ixgRDoQDYVF;6xlhAIrpQV)k z?eyu>zvy&2$%D?Q*XuJ`mi@q53y26p2vkZf?wJ6k^u(PzcWz8gO}%KXmDXAiLX2+@ zMNz=w;-b8M{rXGYZudqQhDUZO-E6PdyH-_I3jly~4$is1jz*&oADVzt>Ugu+yuuhe zvazuN&bjeED5XFM0ZU6uP!t6K0OWZ-Uscs*t+hWsBT153=iJpW3_FMjgb=8zs&LM| zZmqQsWI`$BF+}`82yrOSb6|`?RaJ2B-aU{~LKH;+0N?2KdUw{=*1oKiVnPV0s%k0- zg8pzg{J7C*%nk;FtHa^2Ln#Hu7*I+}rPOzdqWJ9tsaPr1=A2(a#M!befe-@ye!s}` z{38H3I;Pv(w{PEFSy_3#)oOiKmgRGZNR?8+80(xmb?UvTsj2tx-o4wo-^5_8wVd-; z27|$+|0?s&56|=3ob#&y(00y&5CW{VMOl_F6GC3~eLo)z1|X#b0C+V`({Hb?uD-)L zU(E9y%CZD&?R2BjxY260<|Zd6fiVW7(a23qOuRN64ln&rpY33{Ss}zV=iJdO%ODIx zsH&>)Jny`<_U&G;cZ(46R+^?jDTSgaM3!YgtJP{Bq-k1OYhinP8xRpTH#aAXq5vr+ zlx69ZQWw|P*LP(;3INdQbeMDQQc)Cb002S=Kv)OEZt=VjTe_>%^MQaT!D=UDA&}cNk z7*kP7FC*eJ-EQ~id(!ODqeq$6dbL)ojaAE99LL^%D7xKl&m~E+$~ng*NpOCC9uFTr ze7VtRkbOTgN+}*i5egyD^E`~A=;QswH5!ds#@J2HImU5}Q50d4Btv7&@ke>&XdK6& zwYFMosHzIAwZUFNtyXI`&-1HV>keZKwAO%#ZZsNQ$g=G3kNV7$`T6;qN-4arYKt^Y z=N_VlX5u)$8ATCBQG{ulBBiuaN?rIO0*3+sI_IudRRvmWAcV-_aQI{2_w_FF`$((R zTFmpjgNQI1jlf##j4>DY>h_0P5CmUhjFq0}q3`=>j6vV`Kbe}EI-90xTC3G&rl+Sb z#BsdJIY;03(f56nQra*Kzx$;0{SU{wUTcj)2&9yv)_PnT1OSv$;`H=1N-3@9c~1r$ z0Dv(j>h=0tlv0`E9(l1w<~p4-~m`f3zK2aGXR p2yv_5?_bkef4IE7Jc9oh`!_U+t;0imp%VZA002ovPDHLkV1n+p5!3(x literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index a2e2a7b..b71d1ce 100644 --- a/resources.qrc +++ b/resources.qrc @@ -18,6 +18,7 @@ shaders/debayer.frag shaders/debayer.vert falsecolor.png + link.png about/help_en diff --git a/stretchtoolbar.cpp b/stretchtoolbar.cpp index b4ee306..ade2411 100644 --- a/stretchtoolbar.cpp +++ b/stretchtoolbar.cpp @@ -23,7 +23,7 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") m_stfSlider = new STFSlider(Qt::white, this); vbox1->addWidget(m_stfSlider); - /*m_stfSliderR = new STFSlider(Qt::red, this); + 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); @@ -31,12 +31,12 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") vbox2->setSpacing(0); vbox2->addWidget(m_stfSliderR); vbox2->addWidget(m_stfSliderG); - vbox2->addWidget(m_stfSliderB);*/ + vbox2->addWidget(m_stfSliderB); m_stack = new QStackedWidget(this); m_stack->addWidget(lum); - //m_stack->addWidget(rgb); - //m_stack->setCurrentIndex(0); + m_stack->addWidget(rgb); + m_stack->setCurrentIndex(0); addWidget(m_stack); connect(m_stfSlider, &STFSlider::paramChanged, [this](float blackPoint, float midPoint, float whitePoint){ @@ -45,7 +45,7 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") 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){ + 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; @@ -62,7 +62,11 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") m_mtfParam.midPoint[2] = midPoint; m_mtfParam.whitePoint[2] = whitePoint; emit paramChanged(m_mtfParam); - });*/ + }); + + QAction *rgbStretch = addAction(QIcon(":/link.png"), tr("Linked stretch")); + rgbStretch->setCheckable(true); + connect(rgbStretch, &QAction::toggled, this, &StretchToolbar::unlinkStretch); QAction *autoStretchButton = addAction(QIcon(":/nuke.png"), tr("Auto Stretch F12")); autoStretchButton->setShortcut(Qt::Key_F12); @@ -74,15 +78,15 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") QAction *invertButton = addAction(QIcon(":/invert.png"), tr("Invert colors")); invertButton->setCheckable(true); - connect(invertButton, SIGNAL(toggled(bool)), this, SIGNAL(invert(bool))); + connect(invertButton, &QAction::toggled, this, &StretchToolbar::invert); QAction *falseColorButton = addAction(QIcon(":/falsecolor.png"), tr("False color")); falseColorButton->setCheckable(true); - connect(falseColorButton, SIGNAL(toggled(bool)), this, SIGNAL(falseColor(bool))); + connect(falseColorButton, &QAction::toggled, this, &StretchToolbar::falseColor); QAction *superPixelButton = addAction(QIcon(":/bayer.png"), tr("Debayer CFA")); superPixelButton->setCheckable(true); - connect(superPixelButton, SIGNAL(toggled(bool)), this, SIGNAL(superPixel(bool))); + connect(superPixelButton, &QAction::toggled, this, &StretchToolbar::superPixel); m_autoStretchOnLoad = addAction(QIcon(":/nuke_a.png"), tr("Apply auto stretch on load")); m_autoStretchOnLoad->setCheckable(true); @@ -90,49 +94,52 @@ StretchToolbar::StretchToolbar(QWidget *parent) : QToolBar(tr("Stretch toolbar") void StretchToolbar::stretchImage(Image *img) { - if(img) + if(img && img->rawImage()) { - if(img->rawImage()) + const RawImage::Stats &stats = img->rawImage()->imageStats(); + int ch = img->rawImage()->channels() == 1 ? 1 : 3; + float bp2 = 0; + float mid2 = 0; + float max2 = 0; + for(int i=0; i < ch; i++) { - const RawImage::Stats &stats = img->rawImage()->imageStats(); - int ch = img->rawImage()->channels() == 1 ? 1 : 3; - float bp2 = 0; - float mid2 = 0; - float max2 = 0; - for(int i=0; i < ch; i++) - { - double median, mad, max; - median = stats.m_median[i]; - mad = stats.m_mad[i]; - max = stats.m_max[i]; - median /= img->rawImage()->norm(); - mad /= img->rawImage()->norm(); - max /= img->rawImage()->norm(); - if(max>1.0f)max = 1.0f; - float bp = median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA; - float mid = MTF(median - bp, TARGET_BACKGROUND); - m_mtfParam.blackPoint[i] = bp; - m_mtfParam.midPoint[i] = mid; - m_mtfParam.whitePoint[i] = max; - bp2 += bp; - mid2 += mid; - max2 += max; - } - if(m_stack->currentIndex() == 0) - { - m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = bp2 / ch; - m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = mid2 / ch; - m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = max2 / ch; - 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); + double median, mad, max; + median = stats.m_median[i]; + mad = stats.m_mad[i]; + max = stats.m_max[i]; + median /= img->rawImage()->norm(); + mad /= img->rawImage()->norm(); + max /= img->rawImage()->norm(); + if(max>1.0f)max = 1.0f; + float bp = median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA; + float mid = MTF(median - bp, TARGET_BACKGROUND); + m_mtfParam.blackPoint[i] = bp; + m_mtfParam.midPoint[i] = mid; + m_mtfParam.whitePoint[i] = max; + bp2 += bp; + mid2 += mid; + max2 += max; } + if(ch == 1) + { + m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = m_mtfParam.blackPoint[0]; + m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = m_mtfParam.midPoint[0]; + m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = m_mtfParam.whitePoint[0]; + } + if(m_stack->currentIndex() == 0) + { + m_mtfParam.blackPoint[0] = m_mtfParam.blackPoint[1] = m_mtfParam.blackPoint[2] = bp2 / ch; + m_mtfParam.midPoint[0] = m_mtfParam.midPoint[1] = m_mtfParam.midPoint[2] = mid2 / ch; + m_mtfParam.whitePoint[0] = m_mtfParam.whitePoint[1] = m_mtfParam.whitePoint[2] = max2 / ch; + 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); } } @@ -140,10 +147,16 @@ void StretchToolbar::resetMTF() { MTFParam params; m_mtfParam = params; - m_stfSlider->setMTFParams(0, 0.5, 1); - m_stfSliderR->setMTFParams(0, 0.5, 1); - m_stfSliderG->setMTFParams(0, 0.5, 1); - m_stfSliderB->setMTFParams(0, 0.5, 1); + 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); } @@ -152,3 +165,22 @@ 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); +} diff --git a/stretchtoolbar.h b/stretchtoolbar.h index 3ec895d..8b35b9d 100644 --- a/stretchtoolbar.h +++ b/stretchtoolbar.h @@ -30,6 +30,7 @@ public slots: void stretchImage(Image *img); void resetMTF(); void imageLoaded(Image *img); + void unlinkStretch(bool enable); signals: void paramChanged(const MTFParam ¶ms); void autoStretch();