/// <summary> /// Perform an inverse haar wavelet mel scaled transform. E.g. perform an ihaar2d and inverse Mel Filterbands and return stftdata /// </summary> /// <param name="wavelet">wavelet matrix</param> /// <returns>matrix inverse wavelet'ed and mel removed (e.g. stftdata)</returns> public Matrix InverseMelScaleWaveletPadding(ref Matrix wavelet) { using (new DebugTimer("InverseMelScaleWaveletPadding(wavelet)")) { // 6. Perform the Inverse Wavelet Transform Matrix mel = WaveletUtils.InverseHaarWaveletTransform2D(wavelet.MatrixData); // Resize (remove padding) mel = mel.Resize(melScaleFreqsIndex.Length - 2, wavelet.Columns); // 5. Take Inverse Logarithm // Divide with first triangle height in order to scale properly for (int i = 0; i < mel.Rows; i++) { for (int j = 0; j < mel.Columns; j++) { mel.MatrixData[i][j] = Math.Pow(10, (mel.MatrixData[i][j] / 20)) / melScaleTriangleHeights[0]; } } // 4. Inverse Mel Scale using interpolation // i.e. from e.g. // mel=Rows: 40, Columns: 165 (average freq, time slice) // to // m=Rows: 1024, Columns: 165 (freq, time slice) //Matrix m = filterWeights.Transpose() * mel; var m = new Matrix(filterWeights.Columns, mel.Columns); InverseMelScaling(mel, m); return(m); } }
/// <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); } }
/// <summary> /// Perform an inverse haar wavelet mel scaled transform. E.g. perform an ihaar2d and inverse Mel Filterbands and return stftdata /// </summary> /// <param name="wavelet">wavelet matrix</param> /// <returns>matrix inverse wavelet'ed and mel removed (e.g. stftdata)</returns> public Matrix InverseMelScaleWaveletPadding(ref Matrix wavelet) { Mirage.DbgTimer t = new Mirage.DbgTimer(); t.Start(); // 6. Perform the Inverse Wavelet Transform Matrix mel = WaveletUtils.InverseHaarWaveletTransform(wavelet.MatrixData); // Resize (remove padding) mel = mel.Resize(melScaleFreqsIndex.Length - 2, wavelet.Columns); // 5. Take Inverse Logarithm // Divide with first triangle height in order to scale properly for (int i = 0; i < mel.Rows; i++) { for (int j = 0; j < mel.Columns; j++) { mel.MatrixData[i][j] = Math.Pow(10, (mel.MatrixData[i][j] / 20)) / melScaleTriangleHeights[0]; } } // 4. Inverse Mel Scale using interpolation // i.e. from e.g. // mel=Rows: 40, Columns: 165 (average freq, time slice) // to // m=Rows: 1024, Columns: 165 (freq, time slice) //Matrix m = filterWeights.Transpose() * mel; Matrix m = new Matrix(filterWeights.Columns, mel.Columns); InverseMelScaling(mel, m); Mirage.Dbg.WriteLine("Inverse Mel Scale And Wavelet Compression Padding - Execution Time: " + t.Stop().TotalMilliseconds + " ms"); return(m); }
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); }
/// <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) { Mirage.DbgTimer t = new Mirage.DbgTimer(); t.Start(); // 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.HaarWaveletTransform(resizedMatrix.MatrixData, true); Mirage.Dbg.WriteLine("Wavelet Mel Scale And Wavelet Compression Padding - Execution Time: " + t.Stop().TotalMilliseconds + " ms"); return(wavelet); }
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); }