The Math Behind Photoshop's Unsharp Mask and Gaussian Blur
- fmw42
- Posts: 25562
- 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
Yes, I have the order correct for subtraction. If you do multiple composites, each gets its own clamping. That is why I though of doing the 3 adds in one operation and not two. My guess is that there is different clamping in IM as separate operations than is what is done in the -unsharp command. Or perhaps PS only clamps one side, say negatives, but does not clamp for values over 255? I really do not know.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur
If we want the long-winded form of "-unsharp", then:
The difference is:
The second convert needs HDRI.
Note that everything is clamped except the minus operation.
Code: Select all
set SRC=lena3.png
%IM%convert %SRC% -unsharp 0x3+1+0 u0.png
rem out = O + (O-GB)
%IMDEV%convert ^
-define compose:clamp=off ^
%SRC% ^
( -clone 0 -gaussian-blur 0x3 -clamp ) ^
( -clone 0-1 -compose MinusSrc -composite ) ^
-delete 1 ^
-compose Plus -composite ^
-clamp ^
u1.png
%IM%compare -metric RMSE u0.png u1.png NULL:
Code: Select all
37.9088 (0.000578452)
Note that everything is clamped except the minus operation.
snibgo's IM pages: im.snibgo.com
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur
We can avoid the need for HDRI by using "-compose Mathematics":
Code: Select all
%IM%convert ^
%SRC% ^
( -clone 0 -gaussian-blur 0x3 ) ^
-compose Mathematics -define compose:args=0,-1,2,0 -composite ^
+depth ^
u2.tiff
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- 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
Snibgo, in your -compose mathematics, you are processing O + (O - GB) as 2*O-GB with no clamping. Strange that works. But the claim was that PS is using O+(O-GB)-inv(O+inv(GB)). My guess is that the third term is getting parts missed by clamping O-GB. Nevertheless, when I computed O+(O-GB) in my script above using clamp=off in HDRI, it did not work. You seems to imply that it is the gaussian blur that needs clamping. But a gaussian has no negative values and should not exceed values in the original, unless the computation has not properly normalized it.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: The Math Behind Photoshop's Unsharp Mask and Gaussian Blur
I think clamping after the blur makes no difference. The important part is that (O-GB) may be negative, so that mustn't be clamped. "-compose Mathematics" works pixel-by-pixel, with each calculation in floating point, though each result here is then written to Q16 integer.
The formula USM='O+(O-GB)-inv(O+inv(GB))' seems to have come from Gimp, which I think records pixel values as 0..255 only. So, when O<GB, (O-GB) is clamped to zero. To compensate, we need to subtract something, and that's what "-inv(O+inv(GB))" is for.
For example, suppose O=33 and GB=44.
USM = 33 + (33-44) - inv(33+inv(44))
Negative values are clamped to zero, and inv(X) = 255-X, so
USM = 33 + (0) - (255- (33+(255-44)))
= 33 - (255 - (33 + (211)))
= 33 - (255 - 244)
= 33 - 11
= 22.
We get the same result from USM = 2*O-GB = 2*33-44 = 66-44 = 22.
Internally, the IM USM takes a longer route because it uses (O-GB) for the threshold:
USM = O + (O-GB) = 33 + (33-44) = 33 + (-11) = 22.
Internally, (O-GB) is stored as a floating point.
Yes.fmw42 wrote:My guess is that the third term is getting parts missed by clamping O-GB.
The formula USM='O+(O-GB)-inv(O+inv(GB))' seems to have come from Gimp, which I think records pixel values as 0..255 only. So, when O<GB, (O-GB) is clamped to zero. To compensate, we need to subtract something, and that's what "-inv(O+inv(GB))" is for.
For example, suppose O=33 and GB=44.
USM = 33 + (33-44) - inv(33+inv(44))
Negative values are clamped to zero, and inv(X) = 255-X, so
USM = 33 + (0) - (255- (33+(255-44)))
= 33 - (255 - (33 + (211)))
= 33 - (255 - 244)
= 33 - 11
= 22.
We get the same result from USM = 2*O-GB = 2*33-44 = 66-44 = 22.
Internally, the IM USM takes a longer route because it uses (O-GB) for the threshold:
USM = O + (O-GB) = 33 + (33-44) = 33 + (-11) = 22.
Internally, (O-GB) is stored as a floating point.
I'm unsure which of your scripts you mean. When you use "-evaluate-sequence add" to add O and GB and the third term, all three terms are always positive, so you need to subtract the third term.fmw42 wrote:Nevertheless, when I computed O+(O-GB) in my script above using clamp=off in HDRI, it did not work.
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- 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 had one computation earlier on where I added -define clamp=off but had added the third term. But I now see that I had added a small threshold term. So the comparison with -unsharp is not appropriate for both reasons.I'm unsure which of your scripts you mean. When you use "-evaluate-sequence add" to add O and GB and the third term, all three terms are always positive, so you need to subtract the third term.
I also computed O + (O-GB), but in that computation I had clamping on. So my comparison for that would not be appropriate either.
Thanks for doing the comparison properly.