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

C# Tutorial

Histogram Equalization And Magic Behind It

This tutorial is meant to demonstrate how histogram equalization works. This is a continuation on contrast stretch articles I’ve made in the past. An article on histogram...

Posted on by Andraz Krzisnik
Morphological Processes

How To Make Opening And Closing – Morphology With C#

Opening and closing in image processing are morphological operations which are basically sequences of erosion and dilation operations.

Posted on by Andraz Krzisnik