## The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

### The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Hello,

Has anyone succeeded replicating Photoshop's Gaussian Blur and Unsharp Mask?

When I say replicating, I mean up to a rounding error or something like that.

It looks like Photoshop is doing something beyond the classic and I want to know what exactly to be able to reproduce things I do in Photoshop using ImageMagick.

I wrote about it here:

http://registry.gimp.org/node/32018

Thank You.

Has anyone succeeded replicating Photoshop's Gaussian Blur and Unsharp Mask?

When I say replicating, I mean up to a rounding error or something like that.

It looks like Photoshop is doing something beyond the classic and I want to know what exactly to be able to reproduce things I do in Photoshop using ImageMagick.

I wrote about it here:

http://registry.gimp.org/node/32018

Thank You.

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask CORRECTED

Your conclusion is not correct. The equivalent is not 3*O+2*GB.Now, the Unsharp Mask of 'O' is given by 'O+(O-GB)-inv(O+inv(GB))'.

You can do that by 'Apply Image'.

Remembering inv(Layer) = 1 - Layer (I assume image is [0, 1) yields something interesting.

It means, at the end USM(O) = 3O - 2B.

it is 2*O + inv(O) - GB - inv(inv(GB))

inv(O) is not the same as -O and inv(GB) is not the same as -GB.

inv(O) = 1-O and inv(GB) is 1-GB for normalized images in the range of 0 to 1

or

inv(O) = 255-O and inv(GB) is 255-GB for normalized images in the range of 0 to 255

Thus

O+(O-GB)-inv(O+inv(GB)) = O+(O-GB)-inv(O)-inv(inv(GB)) = 2*O - GB - (1-O) - (1-(1-GB)) = 2*O -GB -1 +O -GB = -1+3*O-2*GB

Thus, this should be correct(?)

**O+(O-GB)-inv(O+inv(GB)) = 3*O -white - 2*GB**

Edited to correct earlier mistakes

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Bl

Let's try it again.

Can wee agree that inv(L) = White - L?

USM(O) = O + (O - B) - inv(O + inv(B)) = 2O - B - (White - (O + (White - B))) = 2O - B - (White - (O + White - B)) = 2O - B - (White - O - White + B) = 2O - B - White + O + White - B = 3O - 2B.

So I was right whether it is a [0, 1] image or [0 255] image.

It has to be the same.

I think you were wrong in:

inv(O + inv(B)) = inv(O) + inv(inv(B))

Let's see:

inv(O + inv(B)) = White - (O + (White - B)) = White - O - White + B = B - O.

But,

If you do 3O - 2B in Photoshop you won't get the expected result.

I think it has to do with clipping at each step because you only can calculate O and (O - B) and then add twice (O-B) to O.

Can wee agree that inv(L) = White - L?

USM(O) = O + (O - B) - inv(O + inv(B)) = 2O - B - (White - (O + (White - B))) = 2O - B - (White - (O + White - B)) = 2O - B - (White - O - White + B) = 2O - B - White + O + White - B = 3O - 2B.

So I was right whether it is a [0, 1] image or [0 255] image.

It has to be the same.

I think you were wrong in:

inv(O + inv(B)) = inv(O) + inv(inv(B))

Let's see:

inv(O + inv(B)) = White - (O + (White - B)) = White - O - White + B = B - O.

But,

If you do 3O - 2B in Photoshop you won't get the expected result.

I think it has to do with clipping at each step because you only can calculate O and (O - B) and then add twice (O-B) to O.

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Bl

I have corrected my computations earlier as I made a sign mistake.

Your notes said

O+(O-GB)

But I had mistakenly scripted:

O+(O-GB)

So correcting the script gives:

Input:

To be compared with PS

PS r=3, amount=100, thresh=25

PS r=7, amount=100, thresh=25

Edit:

Your notes said

O+(O-GB)

**-**inv(O+inv(GB))But I had mistakenly scripted:

O+(O-GB)

**+**inv(O+inv(GB))So correcting the script gives:

Input:

Code: Select all

```
thresh=9.8
convert lena3.png \
\( -clone 0 -gaussian-blur 0x3 \) \
\( -clone 0 -clone 1 +swap -compose minus -composite \) \
\( -clone 1 -negate \) \
\( -clone 0 -clone 3 -compose plus -composite -negate \) \
-delete 1,3 \
\( -clone 1 -clone 2 +swap -compose minus -composite \) \
-delete 1,2 \
\( -clone 1 -threshold $thresh% -negate \) \
-compose plus -composite lena3_im_us_script3_3gx9p8x1.png
```

To be compared with PS

PS r=3, amount=100, thresh=25

PS r=7, amount=100, thresh=25

Edit:

Yes, I think you are right. But I scripted from your original equation and not the simplified one. I think you are correct that clipping is needed between steps of your processing and you cannot do the breakdown by simple math.Drazick wrote:I think you were wrong in:

inv(O + inv(B)) = inv(O) + inv(inv(B))

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Bl

Thank You for the simulations.

Yet again, what's interesting here is why Photoshop does it and why the direct calculation is different from the "Long Calculation"?

Yet again, what's interesting here is why Photoshop does it and why the direct calculation is different from the "Long Calculation"?

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Bl

It turns out the magic happens when after each addition / subtraction operation you clip the image into its range.

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

You corrected your answer after I wrote that the magic happens due to clipping in each step.

Yet clipping, since it is Non Linear, must be done at each iteration and not like you wrote.

Try it by yourself.

Yet clipping, since it is Non Linear, must be done at each iteration and not like you wrote.

Try it by yourself.

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Turning clamping off, makes the results worse.

Clamp On (by default)

thresh=9.8

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -compose minus -composite \) \

-delete 1,2 \

\( -clone 1 -threshold $thresh% -negate \) \

-compose plus -composite lena3_im_us_script3_3gx9p8x1a.png

Clamp Off:

thresh=9.8

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -define compose:clamp=off -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -define compose:clamp=off -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose minus -composite \) \

-delete 1,2 \

\( -clone 1 -threshold $thresh% -negate \) \

-define compose:clamp=off -compose plus -composite lena3_im_us_script3_3gx9p8x1b.png

compare -metric rmse lena3_im_us_script3_3gx9p8x1a.png lena3_im_us_script3_3gx9p8x1b.png null:

3940.39 (0.0601265)

Clamp On (by default)

thresh=9.8

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -compose minus -composite \) \

-delete 1,2 \

\( -clone 1 -threshold $thresh% -negate \) \

-compose plus -composite lena3_im_us_script3_3gx9p8x1a.png

Clamp Off:

thresh=9.8

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -define compose:clamp=off -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -define compose:clamp=off -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose minus -composite \) \

-delete 1,2 \

\( -clone 1 -threshold $thresh% -negate \) \

-define compose:clamp=off -compose plus -composite lena3_im_us_script3_3gx9p8x1b.png

compare -metric rmse lena3_im_us_script3_3gx9p8x1a.png lena3_im_us_script3_3gx9p8x1b.png null:

3940.39 (0.0601265)

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

If you remove the thresholding and clamp (clip) in HDRI, you get

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -compose minus -composite \) \

-delete 1,2 \

-compose plus -composite lena3_im_us_script3_3gx9p8x1c.png

IM internal unsharp:

im6937hdri convert lena3.png -unsharp 0x3 lena3_im_uns_0x3.png

PS r=3, amount=100, thresh=25

PS r=7, amount=100, thresh=25

Differences may be in the quality or argument interpetation of the gaussian blur(?) It is also possible that PS adds some slight smoothing of some kind to the result.

im6937hdri convert lena3.png \

\( -clone 0 -gaussian-blur 0x3 \) \

\( -clone 0 -clone 1 +swap -compose minus -composite \) \

\( -clone 1 -negate \) \

\( -clone 0 -clone 3 -compose plus -composite -negate \) \

-delete 1,3 \

\( -clone 1 -clone 2 +swap -compose minus -composite \) \

-delete 1,2 \

-compose plus -composite lena3_im_us_script3_3gx9p8x1c.png

IM internal unsharp:

im6937hdri convert lena3.png -unsharp 0x3 lena3_im_uns_0x3.png

PS r=3, amount=100, thresh=25

PS r=7, amount=100, thresh=25

Differences may be in the quality or argument interpetation of the gaussian blur(?) It is also possible that PS adds some slight smoothing of some kind to the result.

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Here's the image manually applying the operations in Photoshop, no threshold, using PS Gaussian Blur with radius 3.

It's strange that this image is not identical to the one made with ImageMagic.

Actually we need a sample from IM _without_ any threshold to be absolutely sure, but it already looks like

they're still going to be different..which is a bit strange. Perhaps Gaussian Blur is not calculated the same

on PS and IM, or the radius value is used differently(?)

It's strange that this image is not identical to the one made with ImageMagic.

Actually we need a sample from IM _without_ any threshold to be absolutely sure, but it already looks like

they're still going to be different..which is a bit strange. Perhaps Gaussian Blur is not calculated the same

on PS and IM, or the radius value is used differently(?)

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Interesting..this seems to be the best match to the image I posted above, but it's still not as good as the PS version.fmw42 wrote: IM internal unsharp:

im6937hdri convert lena3.png -unsharp 0x3 lena3_im_uns_0x3.png

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

I do not see you posted image or its PS argument values.

Edit: Sorry, we must have posted at about the same time. I see your image above.

Edit: Sorry, we must have posted at about the same time. I see your image above.

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Sorry. Not sure why it's not showing up for you. This is the URL:

http://i.imgur.com/ZKwoD4L.png

Can you open that one?

I did these steps in PS:

O+(O-GB)-inv(O+inv(GB))

For GB I used radius 3.

http://i.imgur.com/ZKwoD4L.png

Can you open that one?

I did these steps in PS:

O+(O-GB)-inv(O+inv(GB))

For GB I used radius 3.

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

One of the issues is interpreting the PS arguments. It has 3 and IM has 4. The main question is what is radius for photoshop and how does that map to IM radiusxsigma. Is the PS radius the radius or the sigma value or some combination. This affects the gaussian blur significantly. With IM you can use 0xsigma and it will compute the appropriate radius. So is radius 3 in PS the same IM radius or IM sigma?

- fmw42
**Posts:**26383**Joined:**2007-07-02T17:14:51-07:00**Authentication code:**1152**Location:**Sunnyvale, California, USA

### Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur

Casper wrote:Sorry. Not sure why it's not showing up for you. This is the URL:

http://i.imgur.com/ZKwoD4L.png

Can you open that one?

I did these steps in PS:

O+(O-GB)-inv(O+inv(GB))

For GB I used radius 3.

Can you reproduce that using PS unsharp mask and if so what values are you using. Presumably the above formula would be for amount=100, and threshold=0. But I do not know what radius 3 means in terms of a gaussian blur the uses radius x sigma values.