Реализация режима наложения OpenCV: почему, казалось бы, эквивалентные операции дают разные результаты? - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть blendImage, frameImage (из JavaCameraView) и maskImage.Мне нужно смешать blendImage и frameImage, используя режим смешивания Lighten с альфа-каналом, рассчитанным из примененного maskImage.Для этого я предварительно умножаю значение затемненного frameImagePixel и сравниваю его.Однако ...

for (int i = 0; i < blendImage.rows; i++) {
    uchar *blendImagePixel = blendImage.ptr(i);
    uchar *frameImagePixel = frameImage.ptr(i);
    uchar *maskImagePixel = maskImage.ptr(i);
    int channelsToBlend = min(3, blendImage.channels()); //if it exists, never blend alpha channel
    for (int j = 0; j != blendImage.cols * blendImage.channels(); j += blendImage.channels()) {
        uchar adjustedMaskImagePixel = saturate_cast<uchar>( (maskImagePixel[j] * maskContrast) + maskBrightness);
        for (int c = 0; c < channelsToBlend; c++) {

            float alpha = (float) map(adjustedMaskImagePixel, 0, 255, 0, 1); //if black, alpha = 0
            float beta  = (float) 1.0 - alpha;

            switch (blendMode) {
                case LIGHTEN: {

                    /* THIS WORKS AND I DON'T KNOW WHY */
                    frameImagePixel[j + c]  = (uchar) (frameImagePixel[j + c] * alpha);
                    if (blendImagePixel[j + c] > frameImagePixel[j + c])
                        frameImagePixel[j + c] = blendImagePixel[j + c];

                     /* THIS DOESN'T WORK AND I DON'T KNOW WHY
                    uchar darkenedFrameImagePixel = (uchar) (frameImagePixel[j + c] * alpha);
                    if (blendImagePixel[j + c] > darkenedFrameImagePixel )
                        frameImagePixel[j + c] = blendImagePixel[j + c];
                    */

                    break;
                }
            }
        }
    }
}

Когда я вычисляю значение затемненного frameImagePixel и сохраняю его в самом frameImagePixel, окончательное изображение идеально.Тем не менее, когда я вычисляю значение затемненного frameImagePixel, но сохраняю его в uchar и сравниваю с переменной uchar, результат получается шумным с испорченными цветами - по большей части глючный беспорядок.Я не понимаюЭти две фразы кажутся эквивалентными.Почему один работает отлично, а другой ломается?

1 Ответ

1 голос
/ 24 сентября 2019

Операции не эквивалентны.В первом случае

frameImagePixel[j + c] = (uchar) (frameImagePixel[j + c] * alpha); 

изменяется frameImagePixel независимо от

if (blendImagePixel[j + c] > frameImagePixel[j + c]) 

Каждый пиксель умножается на альфа.Во втором случае, если

blendImagePixel[j + c] < darkenedFrameImagePixel 

, ничего не происходит.Не все пиксели умножаются на альфа.Это большая разница.

Пример:

Первый случай

frameImagePixel[j + c] = 10
alpha = 0.5
blendImagePixel[j + c] = 0
=> frameImagePixel[j + c] == 5
=> blendImagePixel[j + c] > frameImagePixel[j + c] == false

Второй случай

frameImagePixel[j + c] = 10
alpha = 0.5
blendImagePixel[j + c] = 0
=> darkenedFrameImagePixel == 5
=> blendImagePixel[j + c] > frameImagePixel[j + c] == false
=> frameImagePixel[j + c] == 10
...