Image Restoration and Reconstruction

Modified on 2010/08/06 14:58 by Administrator — Categorized as: Digital Image Processing

Arithmetic mean filter

Gaussian Noise

Image

Salt-and-Pepper Noise

Image

Gaussian Noise & Salt-and-Pepper Noise

Image

Code

public override Bitmap Process(Bitmap input)
{
	if (input.PixelFormat != PixelFormat.Format8bppIndexed)
		throw new NotSupportedException();

	Bitmap output = (Bitmap)input.Clone();

	int rm = M / 2;
	int rn = N / 2;

	int width = output.Width;
	int height = output.Height;

	int mn = M * N;

	BitmapData inputData = input.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
	BitmapData outputData = output.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

	unsafe
	{
		byte* inputPtr = (byte*)inputData.Scan0.ToPointer();
		byte* outputPtr = (byte*)outputData.Scan0.ToPointer();

		for (int i = 0; i < width * height; i++)
		{
			int x = i % width;
			int y = i / width;

			if (x >= rm && y >= rn && x < width - rm && y < height - rn)
			{
				int sum = 0;
				for (int tx = -rm; tx <= rm; tx++)
					for (int ty = -rn; ty <= rn; ty++)
					{
						sum += inputPtr[i + tx + ty * width];
					}
				outputPtr[i] = (byte)(sum / mn);
			}
		}
	}

	output.UnlockBits(outputData);
	input.UnlockBits(inputData);

	return output;
}




Median filter

Gaussian Noise

Image

Salt-and-Pepper Noise

Image

Gaussian Noise & Salt-and-Pepper Noise

Image

Code

public override Bitmap Process(Bitmap input)
{
	if (input.PixelFormat != PixelFormat.Format8bppIndexed)
		throw new NotSupportedException();

	Bitmap output = (Bitmap)input.Clone();

	int rm = M / 2;
	int rn = N / 2;

	int width = output.Width;
	int height = output.Height;

	int mn = M * N;

	BitmapData inputData = input.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
	BitmapData outputData = output.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

	unsafe
	{
		byte* inputPtr = (byte*)inputData.Scan0.ToPointer();
		byte* outputPtr = (byte*)outputData.Scan0.ToPointer();

		for (int i = 0; i < width * height; i++)
		{
			int x = i % width;
			int y = i / width;

			if (x >= rm && y >= rn && x < width - rm && y < height - rn)
			{
				List<byte> sequence = new List<byte>(mn);
				for (int tx = -rm; tx <= rm; tx++)
					for (int ty = -rn; ty <= rn; ty++)
					{
						sequence.Add(inputPtr[i + tx + ty * width]);
					}
				sequence.Sort();
				outputPtr[i] = sequence[mn / 2];
			}
		}
	}

	output.UnlockBits(outputData);
	input.UnlockBits(inputData);

	return output;
}





Adaptive, local noise reduction filter

Gaussian Noise

Image

Salt-and-Pepper Noise

Image

Gaussian Noise & Salt-and-Pepper Noise

Image

Code

public override Bitmap Process(Bitmap input)
{
	if (input.PixelFormat != PixelFormat.Format8bppIndexed)
		throw new NotSupportedException();

	Bitmap output = (Bitmap)input.Clone();

	int rm = M / 2;
	int rn = N / 2;

	int width = output.Width;
	int height = output.Height;

	int mn = M * N;

	BitmapData inputData = input.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
	BitmapData outputData = output.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

	unsafe
	{
		byte* inputPtr = (byte*)inputData.Scan0.ToPointer();
		byte* outputPtr = (byte*)outputData.Scan0.ToPointer();

		for (int i = 0; i < width * height; i++)
		{
			int x = i % width;
			int y = i / width;

			if (x >= rm && y >= rn && x < width - rm && y < height - rn)
			{
				double mL = 0; // mean
				List<byte> sequence = new List<byte>(mn);
				for (int tx = -rm; tx <= rm; tx++)
					for (int ty = -rn; ty <= rn; ty++)
					{
						sequence.Add(inputPtr[i + tx + ty * width]);
						mL += inputPtr[i + tx + ty * width];
					}
				mL /= mn;

				double σL2 = 0;
				foreach (byte pixel in sequence)
				{
					σL2 += Math.Pow(mL - pixel, 2);
				}
				σL2 /= mn;

				double gxy = inputPtr[i];

				outputPtr[i] = (byte)(gxy - Math.Min(1.0, _ση2 / σL2) * (gxy - mL));
			}
		}
	}

	output.UnlockBits(outputData);
	input.UnlockBits(inputData);

	return output;
}





Adaptive median filter

Gaussian Noise

Image

Salt-and-Pepper Noise

Image

Gaussian Noise & Salt-and-Pepper Noise

Image

Code

public Bitmap Process(Bitmap input)
{
	if (input.PixelFormat != PixelFormat.Format8bppIndexed)
		throw new NotSupportedException();

	Bitmap output = (Bitmap)input.Clone();

	int width = output.Width;
	int height = output.Height;

	int scurr = 3;
	int smax_local = 3;


	BitmapData inputData = input.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
	BitmapData outputData = output.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

	unsafe
	{
		byte* inputPtr = (byte*)inputData.Scan0.ToPointer();
		byte* outputPtr = (byte*)outputData.Scan0.ToPointer();

		for (int i = 0; i < width * height; i++)
		{
			int x = i % width;
			int y = i / width;

			if (x >= 1 && y >= 1 && x < width - 1 && y < height - 1) // minimum 3x3 area
			{
				scurr = 3;

				// if we are close to border, we cannot go beyond it
				smax_local = Math.Min(x * 2 + 1, Smax);
				smax_local = Math.Min(y * 2 + 1, smax_local);
				smax_local = Math.Min((width - 1 - x) * 2 + 1, smax_local);
				smax_local = Math.Min((height - 1 - y) * 2 + 1, smax_local);

				do
				{
					int rm = scurr / 2;
					int rn = scurr / 2;
					int mn = scurr * scurr;

					List<byte> sequence = new List<byte>(mn);
					for (int tx = -rm; tx <= rm; tx++)
						for (int ty = -rn; ty <= rn; ty++)
						{
							sequence.Add(inputPtr[i + tx + ty * width]);
						}
					sequence.Sort();

					byte zmin = sequence[0];
					byte zmax = sequence[mn - 1];
					byte zmed = sequence[mn / 2];
					byte zxy = inputPtr[i];

					int A1 = zmed - zmin;
					int A2 = zmed - zmax;
					if (A1 > 0 && A2 < 0)
					{
						int B1 = zxy - zmin;
						int B2 = zxy - zmax;
						if (B1 > 0 && B2 < 0)
						{
							outputPtr[i] = zxy;
							break;
						}
						else
						{
							outputPtr[i] = zmed;
							break;
						}
					}
					else
					{
						scurr += 2;
						if (scurr > smax_local)
						{
							outputPtr[i] = zmed;
							break;
						}
					}
				} while (true);
			}
		}
	}

	output.UnlockBits(outputData);
	input.UnlockBits(inputData);

	return output;
}