2

Regarding to this post on StackOverflow (and this too) I'm taking one normal image of a flower, then a white image and then I apply the SoftLight.

These are the images (flower and white image):

enter image description here

The result should be something similar of what I've got in GIMP:

enter image description here

but it's finally a white image.

enter image description here

I modified the code in order to put it inside a function, and this is my code:

// function
uint convSoftLight(int A, int B) {

    return ((uint)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))));
}

void function() {
    Mat flower = imread("/Users/rafaelruizmunoz/Desktop/flower.jpg");
    Mat white_flower = Mat::zeros(Size(flower.cols, flower.rows), flower.type());
    Mat mix = Mat::zeros(Size(flower.cols, flower.rows), flower.type());

    for (int i = 0; i < white_flower.rows; i++) {
        for (int j = 0; j < white_flower.cols; j++) {
            white_flower.at<Vec3b>(i,j) = Vec3b(255,255,255);
        }
    }

    imshow("flower", flower);
    imshow("mask_white", white_flower);

    for (int i = 0; i < mix.rows; i++) {
        for (int j = 0; j < mix.cols; j++) {
            Vec3b vec = flower.at<Vec3b>(i,j);
            vec[0] = convSoftLight(vec[0], 255); // 255 or just the white_flower pixel at (i,j)
            vec[1] = convSoftLight(vec[1], 255); // 255 or just the white_flower pixel at (i,j)
            vec[2] = convSoftLight(vec[2], 255); // 255 or just the white_flower pixel at (i,j)
            mix.at<Vec3b>(i,j) = vec;
        }
    }


    imshow("mix", mix);
}

What am I doing wrong?

Thank you.


EDIT: I've tried to flip the order (convSoftLight(B,A); instead convSoftLight(A,B)), but nothing happened (black image)

Community
  • 1
  • 1
Rafael Ruiz Muñoz
  • 5,333
  • 6
  • 46
  • 92

2 Answers2

2

Based on the blender definitions: I rewrote my function:

uint convSoftLight(int A, int B) {

    float a = (float)A / 255;
    float b = (float)B / 255;
    float result = 0;

    if (b < 0.5)
        result = 2 * a * b + pow(a,2) * (1 - 2*b);
    else
        result = 2 * a * (1-b) + sqrt(a) * (2*b - 1);

    return (uint)255* result;
}
Rafael Ruiz Muñoz
  • 5,333
  • 6
  • 46
  • 92
2

Here's how soft light might be implemented in Python (with OpenCV and NumPy):

import numpy as np

def applySoftLight(bottom, top, mask):
    """ Apply soft light blending
    """

    assert all(image.dtype == np.float32 for image in [bottom, top, mask])

    blend = np.zeros(bottom.shape, dtype=np.float32)

    low = np.where((top < 0.5) & (mask > 0))
    blend[low] = 2 * bottom[low] * top[low] + bottom[low] * bottom[low] * (1 - 2 * top[low])

    high = np.where((top >= 0.5) & (mask > 0))
    blend[high] = 2 * bottom[high] * (1 - top[high]) + np.sqrt(bottom[high]) * (2 * top[high] - 1)

    # alpha blending accroding to mask
    result = bottom * (1 - mask) + blend * mask

    return result

All matrices must be single channel 2D matrices converted into type np.float32. Mask is a "layer mask" in terms of GIMP/Photoshop.

Maksym Ganenko
  • 1,288
  • 15
  • 11