/// <summary>
		/// Inverse Haar Transform of a 2D image to a Matrix.
		/// This is using the tensor product layout.
		/// Performance is also quite fast.
		/// Note that the input array must be a square matrix of dimension 2n x 2n where n is an integer
		/// </summary>
		/// <param name="image">2D array</param>
		/// <param name="disableMatrixDimensionCheck">True if matrix dimension check should be turned off</param>
		/// <returns>Matrix with inverse haar transform</returns>
		public static Matrix InverseHaarWaveletTransform(double[][] image, bool disableMatrixDimensionCheck=false) {
			Matrix imageMatrix = new Matrix(image);

			// Check that the input matrix is a square matrix of dimension 2n x 2n (where n is an integer)
			if (!disableMatrixDimensionCheck && !imageMatrix.IsSymmetric() && !MathUtils.IsPowerOfTwo(image.Length)) {
				throw new Exception("Input matrix is not symmetric or has dimensions that are a power of two!");
			}

			double[] imagePacked = imageMatrix.GetColumnPackedCopy();
			HaarTransform.haar_2d_inverse(imageMatrix.Rows, imageMatrix.Columns, imagePacked);
			Matrix inverseHaarMatrix = new Matrix(imagePacked, imageMatrix.Rows);
			return inverseHaarMatrix;
		}
		public static void TestHaarTransform() {
			
			double[][] mat = Get2DTestData();
			Matrix matrix = new Matrix(mat);
			//matrix.Print();
			
			double[] packed = matrix.GetColumnPackedCopy();
			HaarTransform.r8mat_print (matrix.Rows, matrix.Columns, packed, "  Input array packed:");

			HaarTransform.haar_2d(matrix.Rows, matrix.Columns, packed);
			HaarTransform.r8mat_print (matrix.Rows, matrix.Columns, packed, "  Transformed array packed:");
			
			double[] w = HaarTransform.r8mat_copy_new(matrix.Rows, matrix.Columns, packed);

			HaarTransform.haar_2d_inverse (matrix.Rows, matrix.Columns, w);
			HaarTransform.r8mat_print (matrix.Rows, matrix.Columns, w, "  Recovered array W:");
			
			Matrix m = new Matrix(w, matrix.Rows);
			//m.Print();
		}
Exemple #3
0
		/// <summary>
		/// Transforms one window of MFCCs. The following steps are
		/// performed: <br>
		/// <br>
		/// (1) normalized power fft with hanning window function<br>
		/// (2) convert to Mel scale by applying a mel filter bank<br>
		/// (3) convertion to db<br>
		/// (4) finally a DCT is performed to get the mfcc<br>
		///<br>
		/// This process is mathematical identical with the process described in [1].
		/// </summary>
		/// <param name="window">double[] data to be converted, must contain enough data for
		///                        one window</param>
		/// <param name="start">int start index of the window data</param>
		/// <returns>double[] the window representation in Sone</returns>
		public double[] ProcessWindow(double[] window, int start)
		{
			//number of unique coefficients, and the rest are symmetrically redundant
			int fftSize = (windowSize / 2) + 1;

			//check start
			if(start < 0)
				throw new Exception("start must be a positive value");

			//check window size
			if(window == null || window.Length - start < windowSize)
				throw new Exception("the given data array must not be a null value and must contain data for one window");

			//just copy to buffer
			for (int j = 0; j < windowSize; j++)
				buffer[j] = window[j + start];

			//perform power fft
			normalizedPowerFFT.Transform(buffer, null);

			//use all coefficient up to the nequist frequency (ceil((fftSize+1)/2))
			Matrix x = new Matrix(buffer, windowSize);
			x = x.GetMatrix(0, fftSize-1, 0, 0); //fftSize-1 is the index of the nyquist frequency

			//apply mel filter banks
			x = melFilterBanks.Times(x);

			//to db
			double log10 = 10 * (1 / Math.Log(10)); // log for base 10 and scale by factor 10
			x.ThrunkAtLowerBoundary(1);
			x.LogEquals();
			x.TimesEquals(log10);

			//compute DCT
			x = dctMatrix.Times(x);

			return x.GetColumnPackedCopy();
		}