I'm trying to recreate an effect used on photoshop called satin effect, which has an option that control the size of the satin, which I think it's just a special blur applied to the satin pattern

So here's an example of the satin pattern of two shapes (apple and rectangle) (with a size of 0) :

satin structure

Increasing the size of the satin

And here's the effect of increasing the size of the satin effect

satin effect


So my question is : is this effect a blur ? If yes, Which type of blur is being applied ?


2 Answers 2


So I tried what has been suggested on this image


Here's the python code :

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)

result = cv2.bitwise_not(cv2.bitwise_and(cv2.bitwise_xor(shift1, shift2), apple))
output = cv2.bitwise_and(result, apple)

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

Applying blur

I tried to apply gaussian blur before the XOR operation by adding those two lines of code before calculating the result

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

and here's what I got :


VS Photoshop result (With approximatively the same configs) :

PS result

So I think that I'm missing an operation to handle the intersection of those 2 shapes (where we got those weird pixels)
Does anyone have an Idea about what I'm missing here ?


I tried another approach:
So instead of using the bitwise XOR operation, I tried to implement the XOR formula (XOR = A.not(B) + not(A).B) by replacing the bitwise AND operation by the MIN and the bitwise OR by the MAX. Here's the lines that I added :

shift2 = ...

# XOR  = A.not(B) + not(A).B
xor_first_term = np.minimum(shift1,(255-shift2))
xor_second_term = np.minimum(shift2,(255-shift1))
xor = (255-np.maximum(xor_first_term, xor_second_term))

result = np.minimum(xor, apple)

And here's the result that I got :


So the result is not perfectly similar to what we got using Photoshop, but at least we got rid of the weird pixels.

Any Idea of what we can add in order to have the exact same result ?

  • $\begingroup$ nice! Have you tried applying the blur after the xor, and using the original image as mask? $\endgroup$ Commented Jul 17, 2022 at 20:37
  • $\begingroup$ Yes I tried it; here's the output, it doesn't seem to work. I think the blurring should be done before but something should be added to handle the intersection between the two shapes $\endgroup$ Commented Jul 17, 2022 at 20:51
  • $\begingroup$ Nice! Shouldn’t you be blurring output rather than shift1 and shift2? The attempt doesn’t look very blurred — too many blocking artifacts. $\endgroup$
    – Peter K.
    Commented Jul 18, 2022 at 2:33
  • $\begingroup$ I don't think that they're using the blur after shifting; I tried this on photoshop, and with a small distance (No overlapping between the two shapes) we can see on this image that only the two shapes (shift1 and shift2) are blured. (See also edited answer, I've tried a new approach even if it's not perfect but it's not bad) $\endgroup$ Commented Jul 18, 2022 at 9:50
  • 1
    $\begingroup$ Try $\operatorname{xor}(a,b) := 1 - |1 - a - b|$. $\endgroup$ Commented Jul 18, 2022 at 13:55

It's not a blur; as you can see in your size=0 example, this has to do something with a cyclic half-image shift of the shape and something like XOR-ing the pattern with itself. Maybe afterwards a blurring is applied, but this can't be inferred from the pictures you shared.

What can be inferred with certainty is that it's not just something that blurs local features.

  • 1
    $\begingroup$ Based on the images shared, I'd say you're correct: the base operation is some combination of multiple-shift-and-XOR. I think the satin size does look like it is controlling a blur, though. $\endgroup$
    – Peter K.
    Commented Jul 17, 2022 at 16:26
  • $\begingroup$ yep, I'd agree; but when I think about how I'd implement a cyclic shift, it'd be through a DCT or DFT and +1,-1,+1,-1… modulation of coefficients; if multiply these with a Gaussian "stamp", then I convolve the time domain, also with a Gaussian of inverse width; so I agree, there is some blurring, but I think the blurring might be a side effect of how that shift is done $\endgroup$ Commented Jul 17, 2022 at 17:54
  • $\begingroup$ Can you please explain what do you mean by convolving the time domain ? $\endgroup$ Commented Jul 17, 2022 at 19:19
  • $\begingroup$ a blur is usually implemented as convolution of a blur kernel with the image. You can do that convolution in time domain, or you can do it in frequency domain by multiplication with the transform of that kernel. $\endgroup$ Commented Jul 17, 2022 at 20:36

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.