예제 #1
0
        /// <summary>
        /// Generate non-overlapping random patches from a matrix
        /// </summary>
        private static List <double[]> GetRandomPatches(double[,] matrix, int patchWidth, int patchHeight, int numberOfPatches)
        {
            int             seed         = 100;
            Random          randomNumber = new Random(seed);
            List <double[]> patches      = new List <double[]>();

            int rows    = matrix.GetLength(0);
            int columns = matrix.GetLength(1);

            for (int i = 0; i < numberOfPatches; i++)
            {
                // selecting a random number from the height of the matrix
                int rowRandomNumber = randomNumber.Next(0, rows - patchHeight);

                // selecting a random number from the width of the matrix
                int columnRandomNumber = randomNumber.Next(0, columns - patchWidth);
                double[,] submatrix = MatrixTools.Submatrix(matrix, rowRandomNumber, columnRandomNumber,
                                                            rowRandomNumber + patchHeight - 1, columnRandomNumber + patchWidth - 1);

                // convert a matrix to a vector by concatenating columns and
                // store it to the array of vectors
                patches.Add(MatrixTools.Matrix2Array(submatrix));
            }

            return(patches);
        }
        /// <summary>
        /// WARNING!!: This method implements a convolution and like all convolutions is very slow (unless it can be fully parellised);
        ///            Consider using another noise normalisation method such as in the class NoiseRemoval_Briggs.
        ///
        /// This method does local contrast normalisation. Typically LCN normalises by division only and is motivated by what is known
        /// to happen in the visual cortext.
        /// Every matrix element or pixel value is divided by the (scaled) standard deviation of pixel values
        /// in a local field centred on the pixel. Scaling affects the severity of the normalisation.
        /// There are several ways of doing LCN. That is can divide by the local sum of squares. Or can calculate the local z-score
        /// which effectively normalises by both subtraction and division.
        /// This method is based on formula given by LeCun. Python code at the bottom of this class is the actual
        /// code used by LeCun which appears to do something different.
        /// Wish I knew Python!
        ///
        /// </summary>
        /// <param name="inputM"></param>
        /// <param name="fieldSize"></param>
        /// <returns></returns>
        public static double[,] ComputeLCN(double[,] inputM, int fieldSize)
        {
            /*
             * // FOLLOWING LINES ARE FOR DEBUGGING AND TESTING
             * var inputM2 = MatrixTools.MatrixRotate90Anticlockwise(inputM);
             * ImageTools.DrawReversedMatrix(inputM2, @"C:\SensorNetworks\Output\Sonograms\TESTMATRIX0.png");
             * double fractionalStretching = 0.05;
             * inputM2 = ImageTools.ContrastStretching(inputM2, fractionalStretching);
             * ImageTools.DrawReversedMatrix(inputM2, @"C:\SensorNetworks\Output\Sonograms\TESTMATRIX1.png");
             * */

            int rowCount = inputM.GetLength(0);
            int colCount = inputM.GetLength(1);

            int frameWidth = fieldSize / 2;

            /// add frame around matrix to compensate for edge effects.
            double[,] framedM = MatrixTools.FrameMatrixWithZeros(inputM, frameWidth);

            // output matrix is same size as input.
            double[,] outputM = new double[rowCount, colCount];
            double[,] subMatrix;
            double NSquared = fieldSize * fieldSize;

            // alpha is a scaling factor. LeCun set it = 0.00001. Here set much higher to have a noticeable effect!
            double alpha = 1.0;

            // convolve gaussian with the matrix
            for (int r1 = 0; r1 < rowCount; r1++)
            {
                for (int c1 = 0; c1 < colCount; c1++)
                {
                    // get field
                    int r2 = r1 + fieldSize - 1;
                    int c2 = c1 + fieldSize - 1;
                    subMatrix = MatrixTools.Submatrix(framedM, r1, c1, r2, c2);
                    double[] V = MatrixTools.Matrix2Array(subMatrix);
                    double   av, variance;
                    NormalDist.AverageAndVariance(V, out av, out variance);

                    double numerator = inputM[r1, c1];

                    //double numerator = (inputM[r1, c1] - av);
                    double denominator = Math.Sqrt(1 + (alpha * variance));
                    outputM[r1, c1] = numerator / denominator;
                }
            }

            // FOLLOWING LINES ARE FOR DEBUGGING AND TESTING

            /*
             * outputM = MatrixTools.MatrixRotate90Anticlockwise(outputM);
             * ImageTools.DrawReversedMatrix(outputM, @"C:\SensorNetworks\Output\Sonograms\TESTMATRIX2.png");
             * double fractionalStretching = 0.05;
             * outputM = ImageTools.ContrastStretching(outputM, fractionalStretching);
             * ImageTools.DrawReversedMatrix(outputM, @"C:\SensorNetworks\Output\Sonograms\TESTMATRIX3.png");
             */

            return(outputM);
        }
예제 #3
0
        /// <summary>
        /// METHOD to TEST the FFT2D.
        /// </summary>
        public static void TestFFT2D()
        {
            string imageFilePath = @"C:\SensorNetworks\Output\FFT2D\test5.png";
            bool   reversed      = false;

            double[,] matrix = GetImageDataAsGrayIntensity(imageFilePath, reversed);

            //matrix = MatrixTools.NormaliseMatrixValues(matrix);
            double[,] output = FFT2Dimensional(matrix);
            Console.WriteLine("Sum={0}", MatrixTools.Matrix2Array(output).Sum());

            //draws matrix after normalisation with white=low and black=high
            ImageTools.DrawReversedMatrix(output, @"C:\SensorNetworks\Output\FFT2D\test5_2DFFT.png");
        }
예제 #4
0
        /// <summary>
        /// Generate overlapped random patches from a matrix
        /// </summary>
        private static List <double[]> GetOverlappedRandomPatches(double[,] matrix, int patchWidth, int patchHeight, int numberOfPatches)
        {
            int             seed         = 100;
            Random          randomNumber = new Random(seed);
            List <double[]> patches      = new List <double[]>();

            int rows    = matrix.GetLength(0);
            int columns = matrix.GetLength(1);
            int no      = 0;

            while (no < numberOfPatches)
            {
                // First select a random patch
                // selecting a random number from the height of the matrix
                int rowRandomNumber = randomNumber.Next(0, rows - patchHeight);

                // selecting a random number from the width of the matrix
                int columnRandomNumber = randomNumber.Next(0, columns - patchWidth);
                double[,] submatrix = MatrixTools.Submatrix(matrix, rowRandomNumber, columnRandomNumber,
                                                            rowRandomNumber + patchHeight - 1, columnRandomNumber + patchWidth - 1);

                // convert a matrix to a vector by concatenating columns and
                // store it to the array of vectors
                patches.Add(MatrixTools.Matrix2Array(submatrix));
                no++;

                // shifting the row by one
                // note that if we select full band patches, then we don't need to shift the column.
                rowRandomNumber = rowRandomNumber + 1;

                // Second, slide the patch window (rowRandomNumber + 1) to select the next patch
                double[,] submatrix2 = MatrixTools.Submatrix(matrix, rowRandomNumber, columnRandomNumber,
                                                             rowRandomNumber + patchHeight - 1, columnRandomNumber + patchWidth - 1);
                patches.Add(MatrixTools.Matrix2Array(submatrix2));
                no++;

                // The below commented code can be used when shifting the row by three

                /*
                 * rInt = rInt + 2;
                 * // Second, slide the patch window (rowRandomNumber+1) to select the next patch
                 * double[,] submatrix3 = MatrixTools.Submatrix(spectrogram, rowRandomNumber, columnRandomNumber,
                 *  rowRandomNumber + patchHeight - 1, columnRandomNumber + patchWidth - 1);
                 * patches.Add(MatrixTools.MatrixToArray(submatrix3));
                 * no++;
                 */
            }

            return(patches);
        }
예제 #5
0
        /// <summary>
        /// Generate non-overlapping sequential patches from a <paramref name="matrix"/>
        /// </summary>
        private static List <double[]> GetSequentialPatches(double[,] matrix, int patchWidth, int patchHeight)
        {
            List <double[]> patches = new List <double[]>();

            int rows    = matrix.GetLength(0);
            int columns = matrix.GetLength(1);

            for (int r = 0; r < rows / patchHeight; r++)
            {
                for (int c = 0; c < columns / patchWidth; c++)
                {
                    double[,] submatrix = MatrixTools.Submatrix(matrix, r * patchHeight, c * patchWidth,
                                                                (r * patchHeight) + patchHeight - 1, (c * patchWidth) + patchWidth - 1);

                    // convert a matrix to a vector by concatenating columns and
                    // store it to the array of vectors
                    patches.Add(MatrixTools.Matrix2Array(submatrix));
                }
            }

            return(patches);
        }
예제 #6
0
        /// <summary>
        /// Generate non-overlapping random patches from a matrix
        /// </summary>
        private static List <double[]> GetRandomPatches(double[,] matrix, int patchWidth, int patchHeight, int numberOfPatches)
        {
            // Note: to make the method more flexible in terms of selecting a random patch with any height and width,
            // first a random number generator is defined for both patchHeight and patchWidth.
            // However, the possibility of selecting duplicates especially when selecting too many random numbers from
            // a range (e.g., 1000 out of 1440) is high with a a random generator.
            // Since, we are mostly interested in full-band patches, i.e., patchWidth = (maxFreqBin - minFreqBin + 1) / numFreqBand,
            // it is important to select non-duplicate patchHeights. Hence, instead of a random generator for patchHeight,
            // a better solution is to make a sequence of numbers to be selected, shuffle them, and
            // finally, a first n (number of required patches) numbers could be selected.

            int rows    = matrix.GetLength(0);
            int columns = matrix.GetLength(1);

            int    seed         = 100;
            Random randomNumber = new Random(seed);

            // not sure whether it is better to use new Guid() instead of randomNumber.Next()
            var             randomRowNumbers = Enumerable.Range(0, rows - patchHeight).OrderBy(x => randomNumber.Next()).Take(numberOfPatches).ToList();
            List <double[]> patches          = new List <double[]>();

            for (int i = 0; i < randomRowNumbers.Count; i++)
            {
                // selecting a random number from the height of the matrix
                //int rowRandomNumber = randomNumber.Next(0, rows - patchHeight);

                // selecting a random number from the width of the matrix
                int columnRandomNumber = randomNumber.Next(0, columns - patchWidth);

                double[,] submatrix = MatrixTools.Submatrix(matrix, randomRowNumbers[i], columnRandomNumber,
                                                            randomRowNumbers[i] + patchHeight - 1, columnRandomNumber + patchWidth - 1);

                // convert a matrix to a vector by concatenating columns and
                // store it to the array of vectors
                patches.Add(MatrixTools.Matrix2Array(submatrix));
            }

            return(patches);
        }