Measure or calculate blur amount (σ) of Gaussian blur algorithm

Discuss digital image processing techniques and algorithms. We encourage its application to ImageMagick but you can discuss any software solutions here.
Post Reply
cult
Posts: 3
Joined: 2018-08-02T01:05:07-07:00
Authentication code: 1152

Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by cult »

Hi community,

I'm generating blurred images with different blur amounts in Unity but I don't know how much blur (spoken in absolute values or in Sigma σ) is produced. Do you know any tool which allows measuring the blur amount of an image when the original image and the blurred version is provided?

However, I would prefer if I could calculate the exact Sigma values my Gaussian blur implementation produces in order to compare absolute blur values between different images. I halfway understand the theoretical background of the Gaussian blur but I didn't write the whole implementation I use by myself, so I have a hard time to understand how the Gaussian formula is applied in this implementation and which Sigma values it produces. Can you help me with this?

I'll provide the relevant code lines which are written in C# for Unity.

Code: Select all

// ...
int iterations = 2;   // increase to get more blur
float interpolation = 2f;  // increase to get more blur
int kernel = 4;

var rt2 = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);

for (int i = 0; i < iterations; i++)
	{
		float radius = (float)i * interpolation + interpolation;   // I think this is the crucial line affecting resulting Sigma value (?)
		blurMaterial.SetFloat(Uniforms._Radius, radius);

		Graphics.Blit(source, rt2, blurMaterial, 1 + kernel);
		source.DiscardContents();

		// is it a last iteration? If so, then blit to destination
		if (i == iterations - 1)
		{
			Graphics.Blit(rt2, destination, blurMaterial, 2 + kernel);
		} else {
			Graphics.Blit(rt2, source, blurMaterial, 2 + kernel);
			rt2.DiscardContents();
		}
	}
	RenderTexture.ReleaseTemporary(rt2);
}
// ...
I don't know if it is important for you but I also provide a small (and I think the only relevant) part of the shader (written in HLSL) which uses parameters of the C# script for rendering the blur on the textures.

Code: Select all

// ...
output_13tap vert13Horizontal (vertexInput IN)
{
	output_13tap OUT;

	OUT.vertex = UnityObjectToClipPos(IN.vertex);

	float2 offset1 = float2(_MainTex_TexelSize.x * _Radius * 1.41176470, 0.0); 
	float2 offset2 = float2(_MainTex_TexelSize.x * _Radius * 3.29411764, 0.0);
	float2 offset3 = float2(_MainTex_TexelSize.x * _Radius * 5.17647058, 0.0);

#if UNITY_VERSION >= 540
	float2 uv = UnityStereoScreenSpaceUVAdjust(IN.uv, _MainTex_ST);
#else
	float2 uv = IN.uv;
#endif

	OUT.texcoord = uv;
	OUT.blurTexcoord[0].xy = uv + offset1;
	OUT.blurTexcoord[0].zw = uv - offset1;
	OUT.blurTexcoord[1].xy = uv + offset2;
	OUT.blurTexcoord[1].zw = uv - offset2;
	OUT.blurTexcoord[2].xy = uv + offset3;
	OUT.blurTexcoord[2].zw = uv - offset3;

	return OUT;
}
// Does the same again with _MainTex_TexelSize.y for vertically blurring the image
// ...
I appreciate any kind of help very much.
Cult
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by snibgo »

If we have a source image, and a Gaussian blur of that source, can we find the sigma used for the blur? I don't know of a direct method. We can find a solution iteratively, of course:

1. Find a sigma that is too small.
2. Find a sigma that is too large.
3. If the sigmas are sufficiently close, end algorithm.
4. The correct sigma is somewhere in the middle. Guess at, say, the mean.
5. If the guess is too small, replace the number from (1), otherwise replace the number from (2).
6. Repeat from 3.

I'm not familiar with the library used in your code, so I don't know if it would make a Gaussian blur. But it seems strange: a Gaussian blur can be implemented by convolving an image with a kernel just once. Building the kernel by iteration is possible. But iterating over the entire image is expensive when the image is many times larger than the kernel.
snibgo's IM pages: im.snibgo.com
cult
Posts: 3
Joined: 2018-08-02T01:05:07-07:00
Authentication code: 1152

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by cult »

Thanks for your answer! How would you even find a sigma that is too small or too large? Can you provide more detail?
You're right, now I also wonder why it is implemented in such an inefficient way that it will be iterated several times over the image. I do know which purpose the iterations have here though:
If you have one iteration and just increase float(interpolation) you get more blur but it doesn't look smooth but rather cut, like you have a large blur with a low sigma, so f.e. just use the center rectangle of a discrete kernel in this picture as sigma (if this makes sense?).

Image

With more iterations you can give float(interpolation) a low value but get a large smooth blur effect.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by fmw42 »

Basically what I think the process is:

1) pick a very small blur sigma
2) apply to unblurred image
3) do an IM compare and get the, for example, rmse metric value

4) Repeat above for a very large blur

5) If the new blur metric is closer to the small value, then try a blur between the two

6) If the new blur metrics is closer to the large value, then try a blur between the two

7) Keep repeating until the two blur metrics are a close as desired.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by fmw42 »

Another way is to least square fit the histogram of the blurred image to gaussian function and measure for the mean and sigma as functions of the gaussian. See https://en.wikipedia.org/wiki/Normal_distribution
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by snibgo »

I suspect the quoted Unity code gives a true Gaussian blur only when "iterations" is infinite. However, the result will be "good enough" at some smaller number of iterations.
cult wrote:How would you even find a sigma that is too small or too large? Can you provide more detail?
Standard deviation (SD) is a measure of blurriness of an image. It has a scale of 0.0 to 0.5, where 0.0 is a total blur (a constant colour) and 0.5 is as sharp as possible.

If we have an input image, and a blurred version of that image, we can calculate the SD of each: call these SDI and SDB. SDB < SDI.

For any trial sigma, blur the input image and calculate the SD; call this SDT.

Code: Select all

magick toes.png -blur 0x1 -format %[fx:standard_deviation] info:

0.150146
If SDT < SDB, the trial sigma is too large.

If SDT > SDB, the trial sigma is too small.

Numerical stability may be lost when SDT and SDB are very close, so we should really test for SDT < SDB-d and SDT > SDB+d where d is a small number eg 0.001.
snibgo's IM pages: im.snibgo.com
cult
Posts: 3
Joined: 2018-08-02T01:05:07-07:00
Authentication code: 1152

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by cult »

snibgo wrote: 2018-08-03T04:21:33-07:00
Standard deviation (SD) is a measure of blurriness of an image. It has a scale of 0.0 to 0.5, where 0.0 is a total blur (a constant colour) and 0.5 is as sharp as possible.
Thank you, this helps a lot! I'm just wondering if ImageMagick (don't have access to it due to issues with my Linux, I'm on Windows now) or any other program for measuring blur would always measure the same SD if I generate different image with various content applying always the same blur amount in my Unity-script. Is it reliable? I'm just sceptical because I tried a similar approach for MATLAB which measures the blur amount: https://www.mathworks.com/matlabcentral ... lur-metric
This didn't work since images with larger blur would sometimes have lower and sometimes higher output values than a less blurred version of the image.
I guess since your approach uses the non-blurred version as a reference, it should be reliable, right? But is the resulting sigma comparable to any blurred image the sigma value is known of, f.e. in images blurred with other applications/scripts?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by fmw42 »

One potential issue is that out-of-focus blur is not uniform over the image. You are proposing a uniform and constant blur situation. So the out-of-focus situation likely does not apply.

The other potential issue is that the image statistics (standard deviation) measures the image distribution and the blur. Using the standard deviation as the blur assumes the statistics are Gaussian. I doubt that all image statistics will be perfectly Gaussian. However with significant Gaussian blur, it should cause the image distribution to conform more to a Gaussian distribution so that the standard deviation is a reasonable estimate of the Gaussian blur sigma.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by snibgo »

cult wrote:This didn't work since images with larger blur would sometimes have lower and sometimes higher output values than a less blurred version of the image.
As far as I can see, if we blur an image twice with different sigmas, and calculate SD for each, the blur with the greatest sigma will always have the smaller SD. If you have any counter-examples, I'd like to see them.

The method of blur shouldn't matter, provided the same method is used for each. Similarly the method of SD calculation.
(IM's SD calculation changed fairly recently, and now weirdly assumes the image is a sample of some larger image, and the number we get is the "unbiased estimate of the population standard deviation", ie an estimate of the SD of this larger image.)

Of course there will be edge cases, eg the input image was already so blurred that blurring again makes no difference, and all the SD values are more or less zero.

If you start from different images, the overall SD is not a good measure of whether the image is "in focus". If the images start with different SDs, applying the same "-blur 0xN" to each will give results with different SDs.

Different blurring methods are possible, and in different colorspaces (eg linear RGB, or L channel of LAB). The algorithm I outline above will find the "-blur 0xN" (which is a Gaussian blur, almost exactly, or use "-gaussian-blur" if you want exactness at the expense of time) that makes an image that most closely matches a target blurred image, however that target was made. "Closely matches" is measured by SD, and other measures are possible, eg RMSE. Would RMSE give significantly different results? I don't know.
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Measure or calculate blur amount (σ) of Gaussian blur algorithm

Post by snibgo »

cult wrote:I tried a similar approach for MATLAB which measures the blur amount: https://www.mathworks.com/matlabcentral ... lur-metric
That mathworks page cites a paper by Crete et al, which gives an algorithm for calculating blurriness on a scale of 0.0 to 1.0 for any image, without reference to a "sharp" original image. I've implemented that as an IM command, and compared it to my more usual standard deviation metrics. See my Measuring blur page.
snibgo's IM pages: im.snibgo.com
Post Reply