Navigation

Related Articles

Back to Latest Articles

How To Make Gamma Noise On Images – C# Guide

Gamma noise is one of the noise models we use to simulate practical data corruption. This guide shows how to apply it on images.


Andraz Krzisnik
How To Make Gamma Noise On Images – C#...

Gamma noise is one of the noise models we can simulate on data. In our particular case, we are going to add noise to an image. Therefore, we will need to use a probability distribution function that makes that noise data.

Most commonly, the reasons for noise in images are low quality equipment and impact of environment conditions. However corruption doesn’t only happen when we’re acquiring the image, it also happens while transmitting it.

Gamma noise

Gamma noise or Erlang noise is very similiar to Rayleigh noise regarding the shape of distribution curve. In essence, it begins with a steep slope and ends smoothly, much like Gaussian does. We can see what we just described in the following graph.

Gamma noise probability distribution graph
Gamma noise probability distribution graph

Let’s clear up a few things first before we move on to the formulation of the probability distribution function of the graph shown above.

Firstly, z axis represents the intensity values along which we distribute the noise pixel values. Secondly, a and b parameters are for shaping the curve. Now that we know what’s what, we can take a look at the function.

Gamma noise probability distribution function
Gamma noise probability distribution function

The ! below the fraction indicates the factorial of the number in the brackets and e is the Eulers constant.

C# code

I’ve written a function that makes noise with probability distribution function. I’ll break it down how it works.

Firstly, it calculates probabilities across all intensities and stores them into array. Secondly, we take those values and create an image histogram. And lastly we take all those distributed pixel values, store them into array and scramble it.

public static Bitmap GammaNoise(this Bitmap image)
     {
         int w = image.Width;
         int h = image.Height;

         BitmapData image_data = image.LockBits(
             new Rectangle(0, 0, w, h),
             ImageLockMode.ReadOnly,
             PixelFormat.Format24bppRgb);

         int bytes = image_data.Stride * image_data.Height;
         byte[] buffer = new byte[bytes];
         byte[] result = new byte[bytes];
         Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
         image.UnlockBits(image_data);

         byte[] noise = new byte[bytes];
         double[] erlang = new double[256];
         double a = 2;
         double b = 10;
         Random rnd = new Random();
         double sum = 0;
         for (int i = 0; i < 256; i++)
         {
             double step = (double)i * 0.1;
             if (step >= 0)
             {
                 erlang[i] = (double)(Math.Exp(-a * step) * (Math.Pow(a, b) * Math.Pow(step, b - 1)) / NoiseDemo.Factorial((int)b - 1));
             }
             else
             {
                 erlang[i] = 0;
             }
             sum += erlang[i];
         }

         for (int i = 0; i < 256; i++)
         {
             erlang[i] /= sum;
             erlang[i] *= bytes;
             erlang[i] = (int)Math.Floor(erlang[i]);
         }

         int count = 0;
         for (int i = 0; i < 256; i++)
         {
             for (int j = 0; j < (int)erlang[i]; j++)
             {
                 noise[j + count] = (byte)i;
             }
             count += (int)erlang[i];
         }

         for (int i = 0; i < bytes - count; i++)
         {
             noise[count + i] = 0;
         }

         noise = noise.OrderBy(x => rnd.Next()).ToArray();

         for (int i = 0; i < bytes; i++)
         {
             result[i] = (byte)(buffer[i] + noise[i]);
         }

         Bitmap result_image = new Bitmap(w, h);
         BitmapData result_data = result_image.LockBits(
             new Rectangle(0, 0, w, h),
             ImageLockMode.WriteOnly,
             PixelFormat.Format24bppRgb);
         Marshal.Copy(result, 0, result_data.Scan0, bytes);
         result_image.UnlockBits(result_data);
         return result_image;
     }

Conclusion

The reason we make noise artificially is to find best restoration and reconstruction techniques on all types of data. You’re able to download the project and examine the code yourself.

Related Articles

Thresholding

How To Make A Basic Global Thresholding Algorithm – C#

This tutorial demonstrates how to get optimal threshold value for basic global thresholding operation for segmentation in image processing.

Posted on by Andraz Krzisnik
Edge Detection

How To Make Marr Hildreth Edge Detection Algorithm In C#

Marr hildreth edge detection process is one of the earliest sophisticated edge detection based segmentation operations in image processing.

Posted on by Andraz Krzisnik