Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
isp:sample_awb_implementation_in_c [2018/06/14 22:26] – [AWB::_correctGains()] Igor Yefmov | isp:sample_awb_implementation_in_c [2018/06/16 03:40] – [AWB::_resetRed()] Igor Yefmov |
---|
* ''%%S2R::enum HIST_TYPE%%'' - a helper enum used as an index into histogram data arrays | * ''%%S2R::enum HIST_TYPE%%'' - a helper enum used as an index into histogram data arrays |
| |
The code below conforms to C++14 standard but it is recommended to use the C++17 toolchain as this is the version the [[code::SUB2r-lib]] is targetting. | The code below conforms to C++17 standard and it is recommended to use the C++17 toolchain as this is the version the [[code::SUB2r-lib]] is targetting. |
| |
====== Helper one-liners ====== | ====== Helper one-liners ====== |
A few short functions for code readability, put into a local anonymous namespace (effectively making these function ''static'' and making sure we don't pollute/collide with the global namespace). | A few short functions for code readability, put into a local anonymous namespace (effectively making these function ''static'' and making sure we don't pollute/collide with the global namespace). |
| |
| Side note: I'm fully aware of the ''std::clamp()'' template yet using my own ''_box()'' because of type conversions I need. In one case I'm limiting a ''double'' into an ''int'' range, returning an ''int'' result. In the second case the range is specified by ''[[#PerPart]]'' values that would otherwise need to be explicitly cast to ''double'' which looked too ugly, TBH. |
| |
<code c++>namespace{ | <code c++>namespace{ |
===== Constructor AWB::AWB ===== | ===== Constructor AWB::AWB ===== |
| |
A bulk of (quite simplistic) calculations is performed with data in ''_stats'' and the results are stored in the ''m_vars'' struct; | A bulk of (quite simplistic) calculations is performed with data in ''_stats'' and the results are stored in the ''m_vars'' struct: |
| |
<code c++>AWB::AWB(IImgSensor * _ov, LumaCalc _alg, const ImgStats & _stats, const PerPart & _satTH) | <code c++>AWB::AWB(IImgSensor * _ov, LumaCalc _alg, const ImgStats & _stats, const PerPart & _satTH) |
<code c++>void AWB::_resetRed() | <code c++>void AWB::_resetRed() |
{ | { |
const int gainG = m_ov[Val::GAIN_G]; | const int gainG = m_ov[Val::gain_g]; |
const int gainR = m_ov[Val::GAIN_R]; | const int gainR = m_ov[Val::gain_r]; |
if(gainR > gainG){ | if(gainR > gainG){ |
const auto diff = (gainG - gainR) * 5 / 8; // 62.5% closer to green gain value | const auto diff = (gainG - gainR) * 5 / 8; // 62.5% closer to green gain value |
m_ov[Val::GAIN_R] = gainR + diff; | m_ov[Val::gain_r] = gainR + diff; |
} | } |
}</code> | }</code> |
In cases when our stats collection yielded too little or too much data we need to adjust the "saturation tolerance" accordingly and try to bring the amount of collected data into a reasonable range. Experimentally we've determined that such range is [''16''..''35'']% which we try to reach by using a 'saturation tolerance" in [''1''..''60'']% range. | In cases when our stats collection yielded too little or too much data we need to adjust the "saturation tolerance" accordingly and try to bring the amount of collected data into a reasonable range. Experimentally we've determined that such range is [''16''..''35'']% which we try to reach by using a 'saturation tolerance" in [''1''..''60'']% range. |
| |
<code c++>void S2R::AWB::_adjTol(long double _adj) | <code c++>void AWB::_adjTol(long double _adj) |
{ | { |
auto diff = _adj * m_satTH; // adjust proportionally to current Saturation tolerance | auto diff = _adj * m_satTH; // adjust proportionally to current Saturation tolerance |