/// <summary> /// Mel Scale Haar Wavelet Transform /// </summary> /// <param name="m">matrix (stftdata)</param> /// <returns>matrix mel scaled and wavelet'ed</returns> public Matrix ApplyMelScaleWaveletPadding(ref Matrix m) { using (new DebugTimer("ApplyMelScaleWaveletPadding(m)")) { // 4. Mel Scale Filterbank // Mel-frequency is proportional to the logarithm of the linear frequency, // reflecting similar effects in the human's subjective aural perception) Matrix mel = filterWeights * m; // 5. Take Logarithm for (int i = 0; i < mel.Rows; i++) { for (int j = 0; j < mel.Columns; j++) { mel.MatrixData[i][j] = (mel.MatrixData[i][j] < 1.0 ? 0 : (20.0 * Math.Log10(mel.MatrixData[i][j]))); } } // 6. Wavelet Transform // make sure the matrix is square before transforming (by zero padding) Matrix resizedMatrix; if (!mel.IsSymmetric() || !MathUtils.IsPowerOfTwo(mel.Rows)) { int size = (mel.Rows > mel.Columns ? mel.Rows : mel.Columns); int sizePow2 = MathUtils.NextPowerOfTwo(size); resizedMatrix = mel.Resize(sizePow2, sizePow2); } else { resizedMatrix = mel; } Matrix wavelet = WaveletUtils.HaarWaveletTransform2D(resizedMatrix.MatrixData, true); return(wavelet); } }
public static void TestDenoise(string imageInPath) { var image = ReadImageGrayscale(imageInPath); // 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(); var normalizedMatrix = new Matrix(imageNormalized); 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)); RandomUtils.Seed(Guid.NewGuid().GetHashCode()); double[][] imageNoisy = imageNormalized.Select(i => i.Select(j => j + (0.2 * RandomUtils.NextDouble())).ToArray()).ToArray(); var matrixNoisy = new Matrix(imageNoisy); matrixNoisy.DrawMatrixImage("lena-noisy.png", -1, -1, false); // Haar Wavelet Transform Matrix haarMatrix = WaveletUtils.HaarWaveletTransform2D(imageNoisy); // Thresholding const double threshold = 0.10; // 0.15 seems to work well with the noise added above, 0.1 var yHard = Thresholding.PerformHardThresholding(haarMatrix.MatrixData, threshold); var ySoft = Thresholding.PerformSoftThresholding(haarMatrix.MatrixData, threshold); var ySemisoft = Thresholding.PerformSemisoftThresholding(haarMatrix.MatrixData, threshold, threshold * 2); var ySemisoft2 = Thresholding.PerformSemisoftThresholding(haarMatrix.MatrixData, threshold, threshold * 4); var yStrict = Thresholding.PerformStrictThresholding(haarMatrix.MatrixData, 100); // Inverse 2D Haar Wavelet Transform Matrix zHard = WaveletUtils.InverseHaarWaveletTransform2D(yHard); Matrix zSoft = WaveletUtils.InverseHaarWaveletTransform2D(ySoft); Matrix zSemisoft = WaveletUtils.InverseHaarWaveletTransform2D(ySemisoft); Matrix zSemisoft2 = WaveletUtils.InverseHaarWaveletTransform2D(ySemisoft2); Matrix zStrict = WaveletUtils.InverseHaarWaveletTransform2D(yStrict); // 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); }
public static Matrix GetWaveletTransformedMatrix(double[][] image, WaveletMethod waveletMethod) { int width = image[0].Length; int height = image.Length; Matrix dwtMatrix = null; Stopwatch stopWatch = Stopwatch.StartNew(); long startS = stopWatch.ElapsedTicks; switch (waveletMethod) { case WaveletMethod.Haar: Haar.Haar2D(image, height, width); dwtMatrix = new Matrix(image); break; case WaveletMethod.HaarTransformTensor: // This is using the tensor product layout dwtMatrix = WaveletUtils.HaarWaveletTransform2D(image); break; case WaveletMethod.HaarWaveletDecompositionTensor: // This is using the tensor product layout var haar = new StandardHaarWaveletDecomposition(); haar.DecomposeImageInPlace(image); dwtMatrix = new Matrix(image); break; case WaveletMethod.NonStandardHaarWaveletDecomposition: // JPEG 2000 var haarNonStandard = new NonStandardHaarWaveletDecomposition(); haarNonStandard.DecomposeImageInPlace(image); dwtMatrix = new Matrix(image); break; case WaveletMethod.HaarCSharp: ForwardWaveletTransform.Transform2D(image, false, 2); dwtMatrix = new Matrix(image); break; case WaveletMethod.HaarWaveletCompress: int lastHeight = 0; int lastWidth = 0; WaveletCompress.HaarTransform2D(image, 10000, out lastHeight, out lastWidth); dwtMatrix = new Matrix(image); break; default: break; } long endS = stopWatch.ElapsedTicks; Console.WriteLine("WaveletMethod: {0} Time in ticks: {1}", Enum.GetName(typeof(WaveletMethod), waveletMethod), (endS - startS)); // increase all values const int mul = 50; double[][] haarImageNormalized5k = dwtMatrix.MatrixData.Select(i => i.Select(j => j * mul).ToArray()).ToArray(); // convert to byte values (0 - 255) // duplicate the octave/ matlab method uint8 var uint8 = new double[haarImageNormalized5k.Length][]; for (int i = 0; i < haarImageNormalized5k.Length; i++) { uint8[i] = new double[haarImageNormalized5k.Length]; for (int j = 0; j < haarImageNormalized5k[i].Length; j++) { double v = haarImageNormalized5k[i][j]; if (v > 255) { uint8[i][j] = 255; } else if (v < 0) { uint8[i][j] = 0; } else { uint8[i][j] = (byte)haarImageNormalized5k[i][j]; } } } var uint8Matrix = new Matrix(uint8); return(uint8Matrix); }