public static void TestDenoise(string imageInPath) {
			
			// Read Image
			Image img = Image.FromFile(imageInPath);
			Bitmap bmp = new Bitmap(img);
			double[][] image = new double[bmp.Height][];
			for (int i = 0; i < bmp.Height; i++)
			{
				image[i] = new double[bmp.Width];
				for (int j = 0; j < bmp.Width; j++) {
					//image[i][j] = bmp.GetPixel(j, i).ToArgb();
					image[i][j] = bmp.GetPixel(j, i).B; // use only blue channel
				}
			}

			//Matrix imageMatrix = new Matrix(image);
			//imageMatrix.WriteCSV("lena-blue.csv", ";");

			// Normalize the pixel values to the range 0..1.0. It does this by dividing all pixel values by the max value.
			double max = image.Max((b) => b.Max((v) => Math.Abs(v)));
			double[][] imageNormalized = image.Select(i => i.Select(j => j/max).ToArray()).ToArray();
			
			Matrix normalizedMatrix = new Matrix(imageNormalized);
			//normalizedMatrix.WriteCSV("lena-normalized.csv", ";");
			normalizedMatrix.DrawMatrixImage("lena-original.png", -1, -1, false);

			// Add Noise using normally distributed pseudorandom numbers
			// image_noisy = image_normalized + 0.1 * randn(size(image_normalized));
			TestSimpleRNG.SimpleRNG.SetSeedFromSystemTime();
			double[][] imageNoisy = imageNormalized.Select(i => i.Select(j => j + (0.1 * TestSimpleRNG.SimpleRNG.GetNormal())).ToArray()).ToArray();
			Matrix matrixNoisy = new Matrix(imageNoisy);
			matrixNoisy.DrawMatrixImage("lena-noisy.png", -1, -1, false);

			// Haar Wavelet Transform
			Matrix haarMatrix = HaarWaveletTransform(imageNoisy);

			// Thresholding
			double threshold = 0.15; // 0.15 seems to work well with the noise added above, 0.1
			double[][] yHard = Thresholding.perform_hard_thresholding(haarMatrix.MatrixData, threshold);
			double[][] ySoft = Thresholding.perform_soft_thresholding(haarMatrix.MatrixData, threshold);
			double[][] ySemisoft = Thresholding.perform_semisoft_thresholding(haarMatrix.MatrixData, threshold, threshold*2);
			double[][] ySemisoft2 = Thresholding.perform_semisoft_thresholding(haarMatrix.MatrixData, threshold, threshold*4);
			double[][] yStrict = Thresholding.perform_strict_thresholding(haarMatrix.MatrixData, 10);
			
			// Inverse 2D Haar Wavelet Transform
			Matrix zHard = InverseHaarWaveletTransform(yHard);
			Matrix zSoft = InverseHaarWaveletTransform(ySoft);
			Matrix zSemisoft = InverseHaarWaveletTransform(ySemisoft);
			Matrix zSemisoft2 = InverseHaarWaveletTransform(ySemisoft2);
			Matrix zStrict = InverseHaarWaveletTransform(yStrict);
			
			//zHard.WriteCSV("lena-thresholding-hard.csv", ";");

			// Output the images
			zHard.DrawMatrixImage("lena-thresholding-hard.png", -1, -1, false);
			zSoft.DrawMatrixImage("lena-thresholding-soft.png", -1, -1, false);
			zSemisoft.DrawMatrixImage("lena-thresholding-semisoft.png", -1, -1, false);
			zSemisoft2.DrawMatrixImage("lena-thresholding-semisoft2.png", -1, -1, false);
			zStrict.DrawMatrixImage("lena-thresholding-strict.png", -1, -1, false);
		}