Add autotrech to conversion

This commit is contained in:
2025-03-01 14:24:28 +01:00
parent 617abf7afe
commit 13e1abf07e
5 changed files with 122 additions and 47 deletions
+107 -1
View File
@@ -759,7 +759,7 @@ void integerResample(uint32_t w, uint32_t h, uint32_t ch, uint32_t oldw, uint32_
{
const T *in = reinterpret_cast<const T*>(in_);
T *out = reinterpret_cast<T*>(out_);
uint32_t down2 = down * down;
const uint32_t down2 = down * down;
U m = std::numeric_limits<T>::max();
if constexpr(std::is_floating_point_v<T>)m = down2;
@@ -1104,6 +1104,112 @@ void RawImage::generateLUT()
cmsCloseProfile(outProfile);
}
void RawImage::applySTF(const MTFParam &mtfParams)
{
auto applyMTF = [&](auto *src) -> void
{
float s = 1.0f;
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)
s = (float)std::numeric_limits<std::remove_reference_t<decltype(*src)>>::max();
float iscale = 1.0f / s;
size_t len = size() * m_ch;
for(size_t i = 0; i < len; i++)
{
float x = src[i] * iscale;
x = (x - mtfParams.blackPoint[0]) / (mtfParams.whitePoint[0] - mtfParams.blackPoint[0]);
x = std::clamp(x, 0.0f, 1.0f);
x = ((mtfParams.midPoint[0] - 1.0f) * x) / ((2.0f * mtfParams.midPoint[0] - 1.0f) * x - mtfParams.midPoint[0]);
src[i] = x * s;
}
};
switch(m_type)
{
case UINT8:
applyMTF(reinterpret_cast<uint8_t*>(m_pixels.get()));
break;
case UINT16:
applyMTF(reinterpret_cast<uint16_t*>(m_pixels.get()));
break;
case UINT32:
applyMTF(reinterpret_cast<uint32_t*>(m_pixels.get()));
break;
case FLOAT32:
applyMTF(reinterpret_cast<float*>(m_pixels.get()));
break;
case FLOAT64:
applyMTF(reinterpret_cast<double*>(m_pixels.get()));
break;
default:
break;
}
}
MTFParam RawImage::calcMTFParams(bool linked, bool debayer) const
{
const float BLACK_POINT_SIGMA = -2.8f;
const float MAD_TO_SIGMA = 1.4826f;
const float TARGET_BACKGROUND = 0.25f;
auto MTF = [](float x, float m)
{
if(x < 0)return 0.0f;
if(x > 1)return 1.0f;
return ((m - 1) * x) / ((2 * m - 1) * x - m);
};
MTFParam mtfParam;
int i = 0;
int ch = m_channels;
int o = 0;
if(debayer)
{
i = 1;
ch = 4;
o = 1;
}
float bp2 = 0;
float mid2 = 0;
float max2 = 0;
for(; i < ch; i++)
{
double median, mad, max;
median = m_stats.m_median[i];
mad = m_stats.m_mad[i];
median /= norm();
bool a = median > 0.5 ? true : false;
mad /= norm();
max = 1.0f;
float bp = a || mad == 0.0f ? 0.0f : std::clamp(median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA, 0.0, 1.0);
if(a && mad != 0.0f)
max = std::clamp(median - mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA, 0.0, 1.0);
float mid = !a ? MTF(median - bp, TARGET_BACKGROUND) : MTF(TARGET_BACKGROUND, max - median);
mtfParam.blackPoint[i-o] = bp;
mtfParam.midPoint[i-o] = mid;
mtfParam.whitePoint[i-o] = max;
bp2 += bp;
mid2 += mid;
max2 = max > max2 ? max : max2;
}
if(ch == 1)
{
mtfParam.blackPoint[1] = mtfParam.blackPoint[2] = mtfParam.blackPoint[0];
mtfParam.midPoint[1] = mtfParam.midPoint[2] = mtfParam.midPoint[0];
mtfParam.whitePoint[1] = mtfParam.whitePoint[2] = mtfParam.whitePoint[0];
}
if(linked)
{
mtfParam.blackPoint[0] = mtfParam.blackPoint[1] = mtfParam.blackPoint[2] = bp2 / ch;
mtfParam.midPoint[0] = mtfParam.midPoint[1] = mtfParam.midPoint[2] = mid2 / ch;
mtfParam.whitePoint[0] = mtfParam.whitePoint[1] = mtfParam.whitePoint[2] = max2;
}
return mtfParam;
}
const std::vector<uint16_t> &RawImage::getLUT() const
{
return m_lut;