How to handle the intersection of the XOR operation

Viewed 55

Context

I'm trying to recreate an effect used on photoshop called satin effect, which creates stainy texture by creating a satin texture (or structure) and applying a blur-like effect.

Example :

Example

I think this effect is achieved by using a double shift of the input pattern from which they apply a XOR operation to get the satin pattern (See Image above - Satin Size 0), then I think they apply a gaussian blur while handling the intersection of the XOR operation.

What I've done so far

I created the first part which consist of shifting the pattern of the satin.
Here's the code :
Image Used : apple.png

apple = cv2.imread('apple.png')
apple = cv2.cvtColor(apple, cv2.COLOR_BGR2GRAY)

# User Inputs (Similar to Photoshop)
angle = 41        # angle of the shift
distance = 100    # distance of the shift

angle = np.deg2rad(180-angle)
tx, ty = (distance*np.cos(angle),distance*np.sin(angle))

# Shifting
shift_matrix1 = np.array([[1,0,tx],[0,1,ty]], dtype=np.float32)
shift_matrix2 = np.array([[1,0,-tx],[0,1,-ty]], dtype=np.float32)

shift1 = cv2.warpAffine(apple, shift_matrix1, apple.shape)
shift2 = cv2.warpAffine(apple,shift_matrix2, apple.shape)

# XOR Operation
xor_result = cv2.bitwise_not(cv2.bitwise_and(cv2.bitwise_xor(shift1, shift2), apple))

output = cv2.bitwise_and(xor_result, apple)

Which gives us the expected result (similar to what we achieve with photoshop) :

result1

Problem :
But the problem emerge when I try to apply the gaussian blur before the XOR operation (Which can be achieved by adding those two lines of code before the XOR operation :

...

shift1 = cv2.GaussianBlur(shift1, (101,101),0)
shift2 = cv2.GaussianBlur(shift2, (101,101),0)

# XOR Operation
xor_result = ...


And her's what I get :

example2


Vs What I get using Photoshop :

example photoshop


Question

So I think that I'm missing an operation to handle the intersection of those 2 shapes (where we got those weird pixels)
So my question is : What operation do you think we should add in order to handle the intersection of the XOR of these two shapes ?

1 Answers

The fuzzy logic version of the Boolean or operator is the max operator, and that of the and is min.

For XOR, the most logical equivalent is max(x-y, y-x), more efficiently written as abs(x-y). This paper describes two other options, but the absolute difference seems to reproduce the Photoshop effect just fine.

I would thus implement your code as:

xor_result = cv2.absdiff(shift1, shift2)
output = np.minimum(255 - xor_result, apple)
Related