2
\$\begingroup\$

I don't have a strong mathematics/Matlab background. I would like to convert this Black level correction function from Matlab to C++. Please comment about on the code style and correctness of my equation.

Matlab

   function output = calculateBlackLevel(blStruct, AG, ET)
    blLut = zeros(length(blStruct), size(blStruct{1}.black_level,2));
    etLut = zeros(length(blStruct), 1);

    for k = 1 : length(blStruct)
        bl = blStruct{k};

        if length(bl.analog_gain) == 1
            blLut(k, :) = bl.black_level;
        elseif AG > max(bl.analog_gain) || AG < min(bl.analog_gain)
            blLut(k, :) = interp1(bl.analog_gain, bl.black_level, AG, 'nearest', 'extrap');
        else
            blLut(k, :) = interp1(bl.analog_gain, bl.black_level, AG);
        end

        etLut(k) = bl.exposure_time;
    end

    if length(etLut) == 1
        output = blLut;
    elseif ET > max(etLut) || ET < min(etLut)
        output = interp1(etLut, blLut, ET, 'nearest', 'extrap');
    else
        output = interp1(etLut, blLut, ET);
    end
 end

C++

void Preprocessor::CalculateBlackLevel(black_level* blackLevelDataNative, double analogGain, double exposureTime, double output[])
{
    const int NUMBER_OF_CHANNELS = 4;
    std::vector<double> exposureTimeLut;    
    std::vector<std::array<int, NUMBER_OF_CHANNELS> > blackLevelLut;

    if (blackLevelDataNative->num_bl_luts == 1 )
    {
        std::array<int, NUMBER_OF_CHANNELS> arr;
        arr[0] = blackLevelDataNative->black_level_luts[0]->black_level[0];
        arr[1] = blackLevelDataNative->black_level_luts[0]->black_level[1];
        arr[2] = blackLevelDataNative->black_level_luts[0]->black_level[2];
        arr[3] = blackLevelDataNative->black_level_luts[0]->black_level[3];
        blackLevelLut.push_back(arr);
    }       
    else           
    {
        double maxAnalogGain = blackLevelDataNative->black_level_luts[0]->analog_gain;
        double minAnalogGain = blackLevelDataNative->black_level_luts[0]->analog_gain;
        for (int num = 0; num < blackLevelDataNative->num_bl_luts; num++)
        {
            maxAnalogGain = std::max(maxAnalogGain, blackLevelDataNative->black_level_luts[num]->analog_gain);
            minAnalogGain = std::min(minAnalogGain, blackLevelDataNative->black_level_luts[num]->analog_gain);
        }
        if (analogGain >= maxAnalogGain || analogGain <= minAnalogGain)
        {
            for (int k = 0; k < blackLevelDataNative->num_bl_luts; k++)
            {
                //find which points you need to interpolate
                if(analogGain >= blackLevelDataNative->black_level_luts[k]->analog_gain && analogGain <=blackLevelDataNative->black_level_luts[k+1]->analog_gain)
                {
                    std::array<int, NUMBER_OF_CHANNELS> arr;
                    for (int ch = 0; ch < NUMBER_OF_CHANNELS; ch++)
                    {
                        //y = y0 + (y1-y0)*(x-x0)/(x1-x0);
                        double y0 = blackLevelDataNative->black_level_luts[k]->black_level[ch];
                        double y1 = blackLevelDataNative->black_level_luts[k+1]->black_level[ch];
                        double x = analogGain;
                        double x0 = blackLevelDataNative->black_level_luts[k]->analog_gain;
                        double x1 = blackLevelDataNative->black_level_luts[k + 1]->analog_gain;
                        arr[ch] =  y0 + (y1-y0)*(x-x0)/(x1-x0);
                    }
                    blackLevelLut.push_back(arr);
                    //if the vector does not contains the exposure, add if to the vector
                    if (std::find(exposureTimeLut.begin(), exposureTimeLut.end(), blackLevelDataNative->black_level_luts[k]->exposure_time) == exposureTimeLut.end())
                    {
                        exposureTimeLut.push_back(blackLevelDataNative->black_level_luts[k]->exposure_time);
                    }
                }
            }
        }
        else //extrapolate nearest neighbor
        {            
            for (int k = 0; k < blackLevelDataNative->num_bl_luts; k++)
            {
                if (analogGain > maxAnalogGain)
                {
                    if(blackLevelDataNative->black_level_luts[k]->analog_gain == maxAnalogGain)
                    {
                        std::array<int, NUMBER_OF_CHANNELS> arr;
                        for (int ch = 0; ch < NUMBER_OF_CHANNELS; ch++)
                        {
                            arr[ch] =  blackLevelDataNative->black_level_luts[k]->black_level[ch];
                        }
                        blackLevelLut.push_back(arr);
                        //if the vector does not contains the exposure, add if to the vector
                        if (std::find(exposureTimeLut.begin(), exposureTimeLut.end(), blackLevelDataNative->black_level_luts[k]->exposure_time) == exposureTimeLut.end())
                        {
                            exposureTimeLut.push_back(blackLevelDataNative->black_level_luts[k]->exposure_time);
                        }
                    }
                }
                else //analogGain < minAnalogGain
                {
                    if(blackLevelDataNative->black_level_luts[k]->analog_gain == minAnalogGain)
                    {
                        std::array<int, NUMBER_OF_CHANNELS> arr;
                        for (int ch = 0; ch < NUMBER_OF_CHANNELS; ch++)
                        {
                            arr[ch] =  arr[ch] =  blackLevelDataNative->black_level_luts[k]->black_level[ch];
                        }
                        blackLevelLut.push_back(arr);
                        //if the vector does not contains the exposure, add if to the vector
                        if (std::find(exposureTimeLut.begin(), exposureTimeLut.end(), blackLevelDataNative->black_level_luts[k]->exposure_time) == exposureTimeLut.end())
                        {
                            exposureTimeLut.push_back(blackLevelDataNative->black_level_luts[k]->exposure_time);
                        }
                    }
                }

            }
        }
    }

    if(exposureTimeLut.size() == 1 )
    {
        return;
    }
    else
    {

        std::vector<double>::iterator iterMax = std::max_element(exposureTimeLut.begin(), exposureTimeLut.end());
        std::vector<double>::iterator iterMin = std::min_element(exposureTimeLut.begin(), exposureTimeLut.end());

        for (int k = 0; k < exposureTimeLut.size(); k++)
        {
            if(exposureTime <= *iterMax && exposureTime >= *iterMin ) //interpolate
            {
                //find which points you need to interpolate
                if(exposureTime >= exposureTimeLut[k] && exposureTime <= exposureTimeLut[k+1])
                {
                    for (int ch = 0; ch < NUMBER_OF_CHANNELS; ch++)
                    {
                        //y = y0 + (y1-y0)*(x-x0)/(x1-x0);
                        double y0 = blackLevelLut[k][ch];
                        double y1 = blackLevelLut[k+1][ch];
                        double x = exposureTime;
                        double x0 = exposureTimeLut[k];
                        double x1 = exposureTimeLut[k +1];
                        output[ch] =  y0 + (y1-y0)*(x-x0)/(x1-x0);
                    }
                    return; //break the loop
                }             
            }
            else //extrapolate nearest neighbor
            {
                for (int ch = 0; ch < NUMBER_OF_CHANNELS; ch++)
                {
                    if(exposureTime > *iterMax )
                    {                    
                        output[ch] = blackLevelLut[exposureTimeLut.size()-1][ch];     
                    }
                    else
                    {
                        output[ch] = blackLevelLut[0][ch];
                    }                    
                }
                return;
            }
        }        
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ Does the code produce the correct output? \$\endgroup\$ Commented Nov 1, 2015 at 14:33
  • \$\begingroup\$ yes I have checked it for a few inputs. not all of the types \$\endgroup\$ Commented Nov 1, 2015 at 20:11

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.