Пример #1
0
        /* WL_FswptMatrix
         *
         * Computes the full decomposition tree for the symmetric wavelet
         *  transform up to the desired level.
         */
        public static int WL_FswptMatrix(double[,] source, ref double[,] dest,
                                         int rows, int cols, int levels,
                                         WL_Filter lowpass, WL_Filter hipass)
        {
            int nRows, nCols;

            double[,] tmp;
            double[,] tmpDest;

            if (levels == 0)
            {
                Array.Copy(source, dest, rows * cols);
                return(0);
            }

            if (WlcSWavelet.WL_FswtMatrix(source, ref dest, rows, cols, 1, lowpass, hipass) != 0)
            {
                return(1);
            }

            nRows   = rows / 2;
            nCols   = cols / 2;
            tmpDest = new double[nRows, nCols];

            tmp = WaveletUtil.WL_Extract2D(dest, 0, 0, nRows, nCols);

            if (WL_FswptMatrix(tmp, ref tmpDest, nRows, nCols, levels - 1, lowpass, hipass) != 0)
            {
                return(1);
            }
            WaveletUtil.WL_Put2D(ref dest, tmpDest, 0, 0, nRows, nCols);

            /* Horizontal */
            tmp = WaveletUtil.WL_Extract2D(dest, 0, nCols, nRows, nCols);

            if (WL_FswptMatrix(tmp, ref tmpDest, nRows, nCols, levels - 1, lowpass, hipass) != 0)
            {
                return(1);
            }
            WaveletUtil.WL_Put2D(ref dest, tmpDest, 0, nCols, nRows, nCols);

            /* Diagonal */
            tmp = WaveletUtil.WL_Extract2D(dest, nRows, nCols, nRows, nCols);

            if (WL_FswptMatrix(tmp, ref tmpDest, nRows, nCols, levels - 1, lowpass, hipass) != 0)
            {
                return(1);
            }
            WaveletUtil.WL_Put2D(ref dest, tmpDest, nRows, nCols, nRows, nCols);

            /* Vertical */
            tmp = WaveletUtil.WL_Extract2D(dest, nRows, 0, nRows, nCols);

            if (WL_FswptMatrix(tmp, ref tmpDest, nRows, nCols, levels - 1, lowpass, hipass) != 0)
            {
                return(1);
            }

            WaveletUtil.WL_Put2D(ref dest, tmpDest, nRows, 0, nRows, nCols);

            return(0);
        }
Пример #2
0
        /* WL_FwtVolume
         *
         * Perform a LEVELS-deep separable forward wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * ROWS and COLS indicate the size of the SOURCE & DEST volume.
         * The transformed coefficients in DEST are stored in the Mallat
         * representation.
         *
         * The edge treatment is to perform periodic extension.
         */
        public static int WL_FwtVolume(double[,,] source, ref double[,,] dest,
                                       int depth, int rows, int cols, int levels,
                                       WL_Filter lowpass, WL_Filter hipass)
        {
            double[] tempSource;
            double[] tempDest;
            int      d, c, r, level;

            /* allocate the temp arrays for columns */
            tempSource = new double[Math.Max(rows, depth)];
            tempDest   = new double[Math.Max(rows, depth)];

            /* copy the source to dest to facilitate multiple levels */
            for (d = 0; d < depth; d++)
            {
                for (r = 0; r < rows; r++)
                {
                    for (int colNum = 0; colNum < cols; colNum++)
                    {
                        dest[d, r, colNum] = source[d, r, colNum];
                    }
                }
            }

            for (level = 0; level < levels; level++, rows /= 2, cols /= 2, depth /= 2)
            {
                /* transform each row */
                for (d = 0; d < depth; d++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        var extract = WaveletUtil.Extract1DArray(dest, d, r, cols);
                        var result  = WL_FwtVector(extract, ref extract, cols, 1, lowpass, hipass);
                        WaveletUtil.Patch1DArray(extract, ref dest, d, r, cols);

                        if (result != 0)
                        {
                            return(1);
                        }
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d ROW:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif

                /* transform each column */
                for (d = 0; d < depth; d++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (r = 0; r < rows; r++)
                        {
                            tempSource[r] = dest[d, r, c];
                        }
                        if (WL_FwtVector(tempSource, ref tempDest, rows, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (r = 0; r < rows; r++)
                        {
                            dest[d, r, c] = tempDest[r];
                        }
                    }
                }

                /* transform each depth line */
                for (r = 0; r < rows; r++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (d = 0; d < depth; d++)
                        {
                            tempSource[d] = dest[d, r, c];
                        }
                        if (WL_FwtVector(tempSource, ref tempDest, depth, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (d = 0; d < depth; d++)
                        {
                            dest[d, r, c] = tempDest[d];
                        }
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d COL:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif
            }

            return(0);
        }
Пример #3
0
        /* WL_IwtVector
         *
         * Perform a LEVELS-deep inverse wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.  Optional
         * arguments indicating how edges should be treated are in ARGV.
         * LENGTH is the length of the SOURCE & DEST vectors.
         * The coefficients in SOURCE are expected to be in the Mallat format.
         */
        public static int WL_IwtVector(double[] source, ref double[] dest, int length,
                                       int levels, WL_Filter lowpass, WL_Filter hipass)
        {
            double[] upLow;        /* extended upsampled low frequency vector */
            double[] upHi;         /* extended upsampled high frequency vector */
            int      i, j, level;
            int      hisize  = hipass.Length;
            int      lowsize = lowpass.Length;

            double[] hicoefs  = hipass.Coefs;
            double[] lowcoefs = lowpass.Coefs;
            double   sum;
            int      left  = Math.Max(lowpass.Offset, hipass.Offset);
            int      right = Math.Max(lowpass.Length - lowpass.Offset - 1,
                                      hipass.Length - hipass.Offset - 1);

            // These are "pointers" into arrays
            int result;
            int hidata;
            int lowdata;

            /* allocate memory for the extended copies of source */
            upLow = new double[length + left + right];
            upHi  = new double[length + left + right];

            length = length / WaveletUtil.WL_pow2(levels - 1);
            /* copy the lowest frequency portion to dest to facilitate multiple levels */
            for (i = 0; i < length; i++)
            {
                dest[i] = source[i];
            }

            for (level = 0; level < levels; level++, length *= 2)
            {
                /* upsample the source data */
                for (i = 0, j = left; i < length / 2; i++)
                {
                    upLow[j] = dest[i];
                    upHi[j]  = source[length / 2 + i];
                    j       += 1;
                    upLow[j] = 0;
                    upHi[j]  = 0;
                    j       += 1;
                }

                j = 0;
                for (i = length - left; i < length; i++, j++)
                {
                    upLow[j] = upLow[left + i];
                    upHi[j]  = upHi[left + i];
                }
                for (i = 0; i < length; i++, j++)
                {
                    upLow[j] = upLow[left + i];
                    upHi[j]  = upHi[left + i];
                }
                for (i = 0; i < right; i++, j++)
                {
                    upLow[j] = upLow[left + i];
                    upHi[j]  = upHi[left + i];
                }

//# ifdef DEBUG
//                fprintf(stderr, "level %d  upLow: ", level);
//                for (i = 0; i < length + left + right; i++)
//                    fprintf(stderr, "%f ", upLow[i]);
//                fprintf(stderr, "\n");
//                fprintf(stderr, "level %d  upHi: ", level);
//                for (i = 0; i < length + left + right; i++)
//                    fprintf(stderr, "%f ", upHi[i]);
//                fprintf(stderr, "\n");
//#endif

                lowdata = left - lowpass.Offset;
                hidata  = left - hipass.Offset;
                result  = 0;

                for (i = 0; i < length; i++, lowdata++, hidata++)
                {
                    sum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        sum += upLow[lowdata + j] * lowcoefs[j];
                    }

                    for (j = 0; j < hisize; j++)
                    {
                        sum += upHi[hidata + j] * hicoefs[j];
                    }

                    dest[result++] = sum;
                }

//# ifdef DEBUG
//                fprintf(stderr, "level %d result: ", level);
//                for (i = 0; i < length; i++) fprintf(stderr, "%f ", dest[i]);
//                fprintf(stderr, "\n");
//#endif
            }

            return(0);
        }
Пример #4
0
        /* WL_IwtMatrix
         *
         * Perform a LEVELS-deep separable inverse wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * ROWS and COLS indicate the size of the SOURCE & DEST matrix.
         * The transformed coefficients in SOURCE must be stored in the Mallat
         * format.
         *
         * The edge treatment is to perform periodic extension.
         */
        public static int WL_IwtMatrix(double[,] source, double[,] dest,
                                       int rows, int cols, int levels,
                                       WL_Filter lowpass, WL_Filter hipass)
        {
            double[] tempSource;
            double[] tempDest;
            int      c, r, level;

            /* allocate the temp arrays for columns */
            tempSource = new double[rows];
            tempDest   = new double[rows];

            /* copy the source to dest to facilitate multiple levels */
            for (r = 0; r < rows; r++)
            {
                Array.Copy(source, r * cols, dest, r * cols, cols);
            }

            rows = rows / WaveletUtil.WL_pow2(levels - 1);
            cols = cols / WaveletUtil.WL_pow2(levels - 1);

            for (level = 0; level < levels; level++, rows *= 2, cols *= 2)
            {
                /* transform each column */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        tempSource[r] = dest[r, c];
                    }

                    if (WL_IwtVector(tempSource, ref tempDest, rows, 1, lowpass, hipass)
                        != 0)
                    {
                        return(1);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        dest[r, c] = tempDest[r];
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d COL:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif


                /* transform each row */
                for (r = 0; r < rows; r++)
                {
                    var extract = WaveletUtil.Extract1DArray(dest, r, cols);
                    var result  = WL_IwtVector(extract, ref extract, cols, 1, lowpass, hipass);
                    WaveletUtil.Patch1DArray(extract, ref dest, r, cols);
                    if (result != 0)
                    {
                        return(1);
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d ROW:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif
            }

            return(0);
        }
Пример #5
0
        /* WL_FwtVector
         *
         * Perform a LEVELS-deep forward wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.  Optional
         * arguments indicating how edges should be treated are in ARGV.
         * LENGTH is the length of the SOURCE & DEST vectors.
         * The transformed coefficients in DEST are stored in the Mallat
         * representation.
         *
         * The default edge treatment is periodic extension. The option
         */
        public static int WL_FwtVector(
            double[] source,
            ref double[] dest,
            int length,
            int levels,
            WL_Filter lowpass,
            WL_Filter hipass
            )
        {
            double[] temp;        /* extended source vector */
            int      i, j, level;
            int      hisize  = hipass.Length;
            int      lowsize = lowpass.Length;

            double[] hicoefs = hipass.Coefs;
            double[] lowcoefs = lowpass.Coefs;
            double   hisum, lowsum;
            int      left  = Math.Max(lowpass.Offset, hipass.Offset);
            int      right = Math.Max(lowpass.Length - lowpass.Offset - 1,
                                      hipass.Length - hipass.Offset - 1);

            // These are "pointers" into arrays
            int hiresult;
            int lowresult;
            int hidata;
            int lowdata;

            /* allocate memory for the extended copy of source */
            temp = new double[length + left + right];

            /* copy source to dest to support doing multiple level transforms */
            Array.Copy(source, dest, length);

            for (level = 0; level < levels; level++, length /= 2)
            {
                j = 0;
                for (i = length - left; i < length; i++)
                {
                    temp[j++] = dest[i];
                }
                for (i = 0; i < length; i++)
                {
                    temp[j++] = dest[i];
                }
                for (i = 0; i < right; i++)
                {
                    temp[j++] = dest[i];
                }

//# ifdef DEBUG
//                fprintf(stderr, "level %d  temp: ", level);
//                for (i = 0; i < length + left + right; i++)
//                    fprintf(stderr, "%f ", temp[i]);
//                fprintf(stderr, "\n");
//#endif

                lowresult = 0;
                hiresult  = length / 2;
                lowdata   = left - lowpass.Offset;
                hidata    = left - hipass.Offset;

                for (i = 0; i < length; i += 2, lowdata += 2, hidata += 2)
                {
                    hisum = lowsum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        lowsum += temp[lowdata + j] * lowcoefs[j];
                    }
                    for (j = 0; j < hisize; j++)
                    {
                        hisum += temp[hidata + j] * hicoefs[j];
                    }
                    dest[lowresult++] = lowsum;
                    dest[hiresult++]  = hisum;
                }

//# ifdef DEBUG
//                fprintf(stderr, "level %d result: ", level);
//                for (i = 0; i < length; i++) fprintf(stderr, "%f ", dest[i]);
//                fprintf(stderr, "\n");
//#endif
            }

            return(0);
        }
Пример #6
0
        /* WL_IswtVector
         *
         * Perform a LEVELS-deep inverse symmetric wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * LENGTH is the length of the SOURCE & DEST vectors.
         * The coefficients in SOURCE are expected to be in the Mallat format.
         */
        public static int WL_IswtVector(
            double[] source,
            ref double[] dest,
            int length,
            int levels,
            WL_Filter lowpass,
            WL_Filter hipass
            )
        {
            int[] sgnpart;
            int   wBound;     /* Current wavelet coefficient boundary */
            int   tmp;

            double[] upLow;        /* extended upsampled low frequency vector */
            double[] upHi;         /* extended upsampled high frequency vector */
            int      i, j, level;
            int      hisize  = hipass.Length;
            int      lowsize = lowpass.Length;

            double[] hicoefs  = hipass.Coefs;
            double[] lowcoefs = lowpass.Coefs;
            double   sum;
            int      left  = Math.Max(lowpass.Offset, hipass.Offset);
            int      right = Math.Max(lowpass.Length - lowpass.Offset - 1,
                                      hipass.Length - hipass.Offset - 1);

            // These are "pointers" into arrays
            int result;
            int hidata;
            int lowdata;

            sgnpart = new int[levels + 1];

            /* allocate memory for the extended copies of source */
            upLow = new double[length + left + right];
            upHi  = new double[length + left + right];

            /* Determine the way the transformed signal is partitioned. */
            for (level = levels, tmp = length; level > 0; level--)
            {
                sgnpart[level] = tmp / 2;
                tmp            = (tmp + 1) / 2;
            }
            sgnpart[0] = tmp;

            /* copy the lowest frequency portion to dest to facilitate multiple levels */
            for (i = 0; i < sgnpart[0] + sgnpart[1]; i++)
            {
                dest[i] = source[i];
            }
            wBound = sgnpart[0];

            for (level = 0; level < levels; level++)
            {
                /* upsample the source data */
                for (i = 0, j = left; i < wBound; i++)
                {
                    upLow[j] = dest[i];
                    j       += 1;
                    upLow[j] = 0;
                    j       += 1;
                }
                for (i = 0, j = left; i < sgnpart[level + 1]; i++)
                {
                    upHi[j] = source[wBound + i];
                    j      += 1;
                    upHi[j] = 0;
                    j      += 1;
                }

                length = wBound + sgnpart[level + 1];

                /* edge extension options */
                if (lowsize % 2 == 1)
                {
                    /* odd length filter (WSS filter) */
                    if (length % 2 == 0)
                    {
                        /* even length signal */
                        /* use E(1,2) for low */
                        for (j = 0, i = 2 * left; i > left; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        for (j = left + length, i = left + length - 2; i > left + length - 2 - right; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        /* use E(2,1) for hi */
                        upHi[left - 1] = 0;
                        for (j = 0, i = 2 * left - 2; i >= left; i--)
                        {
                            upHi[j++] = upHi[i];
                        }
                        for (j = length + left, i = left + length - 4; i > left + length - 4 - right; i--)
                        {
                            upHi[j++] = upHi[i];
                        }
                    }
                    else
                    {
                        /* odd length signal */
                        /* use E(1,1) for low, symmetric */
                        for (j = left - 1, i = left + 1; i <= 2 * left; i++)
                        {
                            upLow[j--] = upLow[i];
                        }
                        for (j = length + left, i = length + left - 2; i > left + length - 2 - right; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        /* use E(2,2) for hi, symmetric */
                        upHi[left - 1] = 0;
                        for (j = left - 2, i = left; i < 2 * left - 1; i++)
                        {
                            upHi[j--] = upHi[i];
                        }
                        upHi[length + left - 1] = upHi[length + left - 3];
                        for (j = length + left, i = length + left - 4; i > left + length - 4 - right; i--)
                        {
                            upHi[j++] = upHi[i];
                        }
                    }
                }
                else
                {
                    /* even length filter (HS filter) */
                    if (length % 2 == 0)
                    {
                        /* even length signal */
                        /* use E(2,2) for low */
                        upLow[left - 1] = 0;
                        for (j = 0, i = 2 * left - 2; i >= left; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        for (j = left + length, i = left + length - 2; i > left + length - 2 - right; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        /* use E(2,2) for hi, antisymmetric */
                        upHi[left - 1] = 0;
                        for (j = 0, i = 2 * left - 2; i >= left; i--)
                        {
                            upHi[j++] = -upHi[i];
                        }
                        for (j = left + length, i = left + length - 2; i > left + length - 2 - right; i--)
                        {
                            upHi[j++] = -upHi[i];
                        }
                    }
                    else
                    {
                        /* odd length signal */
                        /* use E(2,1) for low */
                        upLow[left - 1] = 0;
                        for (j = left - 2, i = left; i < 2 * left - 1; i++)
                        {
                            upLow[j--] = upLow[i];
                        }
                        for (j = length + left, i = length + left - 2; i > left + length - 2 - right; i--)
                        {
                            upLow[j++] = upLow[i];
                        }
                        /* use E(2,1) for hi, antisymmetric */
                        upHi[left - 1] = 0;
                        for (j = left - 2, i = left; i < 2 * left - 1; i++)
                        {
                            upHi[j--] = -upHi[i];
                        }
                        upHi[length + left - 1] = -upHi[length + left - 5];
                        for (j = length + left, i = length + left - 6; i > left + length - 6 - right; i--)
                        {
                            upHi[j++] = -upHi[i];
                        }
                    }
                }

#if false
                printf("\n\n-------------------------\n");
                printf("Length = %d   Left = %d    Right = %d\n", length, left, right);
                printf("upLow = ");
                for (i = 0; i < left; i++)
                {
                    printf("%g ", upLow[i]);
                }
                printf("\n");
                for (i = left; i < length + left; i++)
                {
                    printf("%g ", upLow[i]);
                }
                printf("\n");
                for (i = length + left; i < length + left + right; i++)
                {
                    printf("%g ", upLow[i]);
                }
                printf("\nupHi  = ");
                for (i = 0; i < left; i++)
                {
                    printf("%g ", upHi[i]);
                }
                printf("\n");
                for (i = left; i < length + left; i++)
                {
                    printf("%g ", upHi[i]);
                }
                printf("\n");
                for (i = length + left; i < length + left + right; i++)
                {
                    printf("%g ", upHi[i]);
                }
                printf("\n--------------------------\n\n");
#endif

                /* filter the source vectors */
                lowdata = left - lowpass.Offset;
                hidata  = left - hipass.Offset;
                result  = 0;
                for (i = 0; i < length; i++, lowdata++, hidata++)
                {
                    sum = 0;

                    for (j = 0; j < lowsize; j++)
                    {
                        sum += upLow[lowdata + j] * lowcoefs[j];
                    }

                    for (j = 0; j < hisize; j++)
                    {
                        sum += upHi[hidata + j] * hicoefs[j];
                    }
                    dest[result++] = sum;
                }

                wBound += (sgnpart[level + 1]);
            }

            return(0);
        }
Пример #7
0
        /* WL_IwtVolume
         *
         * Perform a LEVELS-deep separable inverse wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * ROWS and COLS indicate the size of the SOURCE & DEST volume.
         * The transformed coefficients in SOURCE must be stored in the Mallat
         * format.
         *
         * The edge treatment is to perform periodic extension.
         */
        public static int WL_IwtVolume(double[,,] source, ref double[,,] dest,
                                       int depth, int rows, int cols, int levels,
                                       WL_Filter lowpass, WL_Filter hipass)
        {
            double[] tempSource;
            double[] tempDest;
            int      d, c, r, level;

            /* allocate the temp arrays for columns */
            tempSource = new double[Math.Max(rows, depth)];
            tempDest   = new double[Math.Max(rows, depth)];

            /* copy the source to dest to facilitate multiple levels */
            for (d = 0; d < depth; d++)
            {
                for (r = 0; r < rows; r++)
                {
                    for (int colNum = 0; colNum < cols; colNum++)
                    {
                        dest[d, r, colNum] = source[d, r, colNum];
                    }
                }
            }

            rows  = rows / WaveletUtil.WL_pow2(levels - 1);
            cols  = cols / WaveletUtil.WL_pow2(levels - 1);
            depth = depth / WaveletUtil.WL_pow2(levels - 1);

            for (level = 0; level < levels; level++, rows *= 2, cols *= 2, depth *= 2)
            {
                /* transform each column */
                for (d = 0; d < depth; d++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (r = 0; r < rows; r++)
                        {
                            tempSource[r] = dest[d, r, c];
                        }
                        if (WL_IwtVector(tempSource, ref tempDest, rows, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (r = 0; r < rows; r++)
                        {
                            dest[d, r, c] = tempDest[r];
                        }
                    }
                }

                /* transform each row */
                for (d = 0; d < depth; d++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        var extract = WaveletUtil.Extract1DArray(dest, d, r, cols);
                        var result  = WL_IwtVector(extract, ref extract, cols, 1, lowpass, hipass);
                        WaveletUtil.Patch1DArray(extract, ref dest, d, r, cols);

                        if (result != 0)
                        {
                            return(1);
                        }
                    }
                }

                /* transform each depth line */
                for (r = 0; r < rows; r++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (d = 0; d < depth; d++)
                        {
                            tempSource[d] = dest[d, r, c];
                        }
                        if (WL_IwtVector(tempSource, ref tempDest, depth, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (d = 0; d < depth; d++)
                        {
                            dest[d, r, c] = tempDest[d];
                        }
                    }
                }
            }

            return(0);
        }
Пример #8
0
        /* WL_IswtMatrix
         *
         * Perform a LEVELS-deep separable inverse symmetric wavelet
         * transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * ROWS and COLS indicate the size of the SOURCE & DEST vectors.
         * The transformed coefficients in SOURCE must be stored in the Mallat
         * format.
         */
        public static int WL_IswtMatrix(double[,] source, ref double[,] dest,
                                        int rows, int cols, int levels,
                                        WL_Filter lowpass, WL_Filter hipass)
        {
            int[]    rSplit;
            int[]    cSplit;
            double[] tempSource;
            double[] tempDest;
            int      c, r, level;

            rSplit = new int[levels + 1];
            cSplit = new int[levels + 1];

            /* allocate the temp arrays for columns */
            tempSource = new double[rows];
            tempDest   = new double[rows];

            /* copy the source to dest to facilitate multiple levels */
            for (r = 0; r < rows; r++)
            {
                for (int colNum = 0; colNum < cols; colNum++)
                {
                    dest[r, colNum] = source[r, colNum];
                }
            }

            /* Determine the way the dimensions of the signal is partitioned. */
            for (level = levels, c = cols, r = rows; level > 0; level--)
            {
                rSplit[level] = r / 2;
                r             = (r + 1) / 2;
                cSplit[level] = c / 2;
                c             = (c + 1) / 2;
            }
            rSplit[0] = r;
            cSplit[0] = c;

            rows = rSplit[0];
            cols = cSplit[0];

            for (level = 1; level < levels + 1; level++)
            {
                rows += (rSplit[level]);
                cols += (cSplit[level]);

                /* transform each column */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        tempSource[r] = dest[r, c];
                    }
                    if (WL_IswtVector(tempSource, ref tempDest, rows, 1, lowpass, hipass)
                        != 0)
                    {
                        return(1);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        dest[r, c] = tempDest[r];
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d COL:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif

                /* transform each row */
                for (r = 0; r < rows; r++)
                {
                    var extract = WaveletUtil.Extract1DArray(dest, r, cols);
                    var result  = WL_IswtVector(extract, ref extract, cols, 1, lowpass, hipass);
                    WaveletUtil.Patch1DArray(extract, ref dest, r, cols);

                    if (result != 0)
                    {
                        return(1);
                    }
                }

//# ifdef DEBUG_MATRIX
//                fprintf(stderr, "level %d ROW:\n", level);
//                for (r = 0; r < rows; r++)
//                {
//                    for (c = 0; c < cols; c++) fprintf(stderr, "%f ", dest[r][c]);
//                    fprintf(stderr, "\n");
//                }
//#endif
            }

            return(0);
        }
Пример #9
0
        /* WL_FswtVector
         *
         * Perform a LEVELS-deep symmetric forward wavelet transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * LENGTH is the length of the SOURCE & DEST vectors.
         * The transformed coefficients in DEST are stored in the Mallat
         * representation.
         */
        public static int WL_FswtVector(
            double[] source,
            ref double[] dest,
            int length,
            int levels,
            WL_Filter lowpass,
            WL_Filter hipass
            )
        {
            double[] temp;        /* extended source vector */
            int      i, j, level;
            int      hisize  = hipass.Length;
            int      lowsize = lowpass.Length;

            double[] hicoefs = hipass.Coefs;
            double[] lowcoefs = lowpass.Coefs;
            double   hisum, lowsum;
            int      left  = Math.Max(lowpass.Offset, hipass.Offset);
            int      right = Math.Max(lowpass.Length - lowpass.Offset - 1,
                                      hipass.Length - hipass.Offset - 1);

            // These are "pointers" into arrays
            int hiresult;
            int lowresult;
            int hidata;
            int lowdata;

            /* allocate memory for the extended copy of source */
            temp = new double[length + left + right];

            /* copy source to dest to support doing multiple level transforms */
            Array.Copy(source, dest, length);

            for (level = 0; level < levels; level++)
            {
                /* make symmetric extension of dest vector */
                if (lowsize % 2 == 1)
                {
                    /* odd length filter (WSS filter), use E(1,1) extension */
                    j = 0;
                    for (i = left; i > 0; i--)
                    {
                        temp[j++] = dest[i];
                    }
                    for (i = 0; i < length; i++)
                    {
                        temp[j++] = dest[i];
                    }
                    for (i = length - 2; i > length - 2 - right; i--)
                    {
                        temp[j++] = dest[i];
                    }
                }
                else
                {
                    /* even length filter (HS filter), use E(2,2) extension */
                    j = 0;
                    for (i = left - 1; i >= 0; i--)
                    {
                        temp[j++] = dest[i];
                    }
                    for (i = 0; i < length; i++)
                    {
                        temp[j++] = dest[i];
                    }
                    for (i = length - 1; i >= length - right; i--)
                    {
                        temp[j++] = dest[i];
                    }
                }

                /* filter the temp vector */
                lowresult = 0;
                hiresult  = (length + 1) / 2;
                lowdata   = left - lowpass.Offset;
                hidata    = left - hipass.Offset;
                for (i = 0; i < length - 1; i += 2)
                {
                    hisum = lowsum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        lowsum += temp[lowdata + j] * lowcoefs[j];
                    }
                    for (j = 0; j < hisize; j++)
                    {
                        hisum += temp[hidata + j] * hicoefs[j];
                    }
                    dest[lowresult++] = lowsum;
                    dest[hiresult++]  = hisum;
                    lowdata          += 2;
                    hidata           += 2;
                }

                /* Compute extra low-pass coefficient if signal is odd */
                if ((length % 2) != 0)
                {
                    lowsum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        lowsum += temp[lowdata + j] * lowcoefs[j];
                    }
                    dest[lowresult] = lowsum;
                }
                length = (length + 1) / 2;
            }

            return(0);
        }
Пример #10
0
        /* WL_IswtVolume
         *
         * Perform a LEVELS-deep separable inverse symmetric wavelet
         * transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in DEST.
         * DEPTH, ROWS and COLS indicate the size of the SOURCE & DEST volumes.
         * The transformed coefficients in SOURCE must be stored in the Mallat
         * format.
         */
        public static int WL_IswtVolume(double[,,] source, ref double[,,] dest,
                                        int depth, int rows, int cols, int levels,
                                        WL_Filter lowpass, WL_Filter hipass)
        {
            int[]    dSplit;
            int[]    rSplit;
            int[]    cSplit;
            double[] tempSource;
            double[] tempDest;
            int      d, c, r, level;

            rSplit = new int[levels + 1];
            cSplit = new int[levels + 1];
            dSplit = new int[levels + 1];

            /* allocate the temp arrays for columns */
            tempSource = new double[Math.Max(depth, rows)];
            tempDest   = new double[Math.Max(depth, rows)];

            /* copy the source to dest to facilitate multiple levels */
            for (d = 0; d < depth; d++)
            {
                for (r = 0; r < rows; r++)
                {
                    for (int colNum = 0; colNum < cols; colNum++)
                    {
                        dest[d, r, colNum] = source[d, r, colNum];
                    }
                }
            }

            /* Determine the way the dimensions of the signal is partitioned. */
            for (level = levels, c = cols, r = rows, d = depth; level > 0; level--)
            {
                rSplit[level] = r / 2;
                r             = (r + 1) / 2;
                cSplit[level] = c / 2;
                c             = (c + 1) / 2;
                dSplit[level] = d / 2;
                d             = (d + 1) / 2;
            }
            rSplit[0] = r;
            cSplit[0] = c;
            dSplit[0] = d;

            rows  = rSplit[0];
            cols  = cSplit[0];
            depth = dSplit[0];

            for (level = 1; level < levels + 1; level++)
            {
                rows  += (rSplit[level]);
                cols  += (cSplit[level]);
                depth += (dSplit[level]);

                /* transform each row */
                for (d = 0; d < depth; d++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        var extract = WaveletUtil.Extract1DArray(dest, d, r, cols);
                        var result  = WL_IswtVector(extract, ref extract, cols, 1, lowpass, hipass);
                        WaveletUtil.Patch1DArray(extract, ref dest, d, r, cols);

                        if (result != 0)
                        {
                            return(1);
                        }
                    }
                }

                /* transform each column */
                for (d = 0; d < depth; d++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (r = 0; r < rows; r++)
                        {
                            tempSource[r] = dest[d, r, c];
                        }

                        if (WL_IswtVector(tempSource, ref tempDest, rows, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (r = 0; r < rows; r++)
                        {
                            dest[d, r, c] = tempDest[r];
                        }
                    }
                }

                /* transform each depth line */
                for (r = 0; r < rows; r++)
                {
                    for (c = 0; c < cols; c++)
                    {
                        for (d = 0; d < depth; d++)
                        {
                            tempSource[d] = dest[d, r, c];
                        }
                        if (WL_IswtVector(tempSource, ref tempDest, depth, 1, lowpass, hipass)
                            != 0)
                        {
                            return(1);
                        }
                        for (d = 0; d < depth; d++)
                        {
                            dest[d, r, c] = tempDest[d];
                        }
                    }
                }
            }

            return(0);
        }
Пример #11
0
        /********************************************************************
         *
         * Redundant Wavelet Transforms for Vectors
         *
         *******************************************************************/

        /* WL_FrwtVector
         *
         * Perform a levels-deep forward redundant transform of vector SOURCE using
         * the filters HIPASS and LOWPASS, storing results in a matrix DEST.
         * LENGTH is the length of the SOURCE vector & the rows in DEST.printf("here pow2:%d level:%d\n",pow2,level);
         *
         * The transformed coefficients in DEST are stored using an overcomplete
         * representation, each row representing a level in the multiresolution
         * pyramid with coarse approximation in zeroth row and the detail signals
         * at level i in the ith row.
         */
        public static int WL_FrwtVector(
            double[] source,
            ref double[,] dest,
            int length,
            int levels,
            WL_Filter lowpass,
            WL_Filter hipass
            )
        {
            double[] temp;                /* extended source vector */
            int      i, j, level, left, right, pow2;
            int      hisize, lowsize;

            double[] hicoefs;
            double[] lowcoefs;
            int      lowoffset, hioffset;

            // These are "pointers" into arrays
            int hiresult;
            int lowresult;
            int hidata;
            int lowdata;

            /* allocate memory for the extended copy of source */
            pow2      = WaveletUtil.WL_pow2(levels - 1);
            lowoffset = lowpass.Offset * pow2;
            hioffset  = hipass.Offset * pow2;
            lowsize   = (lowpass.Length - 1) * pow2 + 1;
            hisize    = (hipass.Length - 1) * pow2 + 1;
            left      = Math.Max(lowoffset, hioffset);
            right     = Math.Max(lowsize - lowoffset - 1, hisize - hioffset - 1);
            temp      = new double[length + (left + right) * pow2];

            /* allocate memory for the lowpass & highpass filter coefficients */
            hicoefs  = new double[hisize * pow2];
            lowcoefs = new double[lowsize * pow2];

            /* copy source to dest to support doing multiple level transforms */
            for (int z = 0; z < length; z++)
            {
                dest[0, z] = source[z];
            }

            for (pow2 = 1, level = 0; level < levels; level++, pow2 *= 2)
            {
                /* dilate the filters */
                Dilate_filter(lowpass.Coefs, ref lowcoefs, lowpass.Length, level);
                Dilate_filter(hipass.Coefs, ref hicoefs, hipass.Length, level);
                lowoffset = lowpass.Offset * pow2;
                hioffset  = hipass.Offset * pow2;
                lowsize   = (lowpass.Length - 1) * pow2 + 1;
                hisize    = (hipass.Length - 1) * pow2 + 1;
                left      = Math.Max(lowoffset, hioffset);
                right     = Math.Max(lowsize - lowoffset - 1, hisize - hioffset - 1);

                /* make periodic extension of dest vector */
                j = 0;
                for (i = length - left; i < length; i++)
                {
                    temp[j++] = dest[0, i];
                }

                for (i = 0; i < length; i++)
                {
                    temp[j++] = dest[0, i];
                }

                for (i = 0; i < right; i++)
                {
                    temp[j++] = dest[0, i];
                }

                /* convolve the data */
                lowresult = 0;
                hiresult  = 0;
                lowdata   = left - lowoffset;
                hidata    = left - hioffset;
                for (i = 0; i < length; i++, lowdata++, hidata++)
                {
                    double hisum = 0, lowsum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        lowsum += temp[lowdata + j] * lowcoefs[j];
                    }
                    for (j = 0; j < hisize; j++)
                    {
                        hisum += temp[hidata + j] * hicoefs[j];
                    }

                    dest[0, lowresult++]        = lowsum;
                    dest[level + 1, hiresult++] = hisum;
                }
            }

            return(1);
        }
Пример #12
0
        /* WL_IrwtVolume
         *
         * Perform a LEVELS-deep separable inverse redundant transform of SOURCE using
         * the filters HIPASS and LOWPASS,  storing results in matrix DEST.
         * ROWS and COLS indicate the size of the rows and columns of volume SOURCE
         * and the size of matrix DEST.
         * The transformed coefficients in SOURCE are stored using an overcomplete
         * representation, each ROWSxCOLS matrix representing a level in the
         * multiresolution pyramid with coarse approximation in zeroth matrix and
         * the 3 detail signals at level i in matrix 3*i+j, where 1<=j<=3.
         * The input volume SOURCE has depth levels+1.
         */
        public static int WL_IrwtVolume(
            double[,,] source,
            ref double[,] dest,
            int rows,
            int cols,
            int levels,
            WL_Filter lowpass,
            WL_Filter hipass
            )
        {
            double[] tempDest;
            double[,] HighMatrix;
            double[,] RowMatrix;
            double[,] ColMatrix;
            int c, r, level;
            int hori, vert, diag;

            /* allocate the temp arrays to hold 1-D results */
            RowMatrix = new double[2, cols];

            ColMatrix = new double[2, rows];

            HighMatrix = new double[rows, cols];

            tempDest = new double[rows];

            /* copy the source to dest to facilitate multiple levels */
            for (r = 0; r < rows; r++)
            {
                for (int colNum = 0; colNum < cols; colNum++)
                {
                    dest[r, colNum] = source[0, r, colNum];
                }
            }

            for (level = levels; level >= 1; level--)
            {
                /* setup indices to horizontal,vertical & diagonal detail signals */
                vert = 3 * (level - 1) + 1;
                hori = vert + 1;
                diag = hori + 1;

                /* transform each column */
                /* first, run the inverse transform using the lowpass output */
                /* from the 1D forward redundant transform along the columns */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        ColMatrix[0, r] = dest[r, c];
                        ColMatrix[1, r] = source[vert, r, c];
                    }
                    if (WL_IrwtMatrix(ColMatrix, ref tempDest, rows, level, lowpass, hipass) != 1)
                    {
                        return(0);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        dest[r, c] = tempDest[r];
                    }
                }

                /* now, for the high pass output */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        ColMatrix[0, r] = source[hori, r, c];
                        ColMatrix[1, r] = source[diag, r, c];
                    }
                    if (WL_IrwtMatrix(ColMatrix, ref tempDest, rows, level, lowpass, hipass) != 1)
                    {
                        return(0);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        HighMatrix[r, c] = tempDest[r];
                    }
                }

                /* transform each row */
                for (r = 0; r < rows; r++)
                {
                    for (int colNum = 0; colNum < cols; colNum++)
                    {
                        RowMatrix[0, colNum] = dest[r, colNum];
                        RowMatrix[1, colNum] = HighMatrix[r, colNum];
                    }

                    var extract = WaveletUtil.Extract1DArray(dest, r, cols);
                    var result  = WL_IrwtMatrix(RowMatrix, ref extract, cols, level, lowpass, hipass);
                    WaveletUtil.Patch1DArray(extract, ref dest, r, cols);

                    if (result != 1)
                    {
                        return(0);
                    }
                }
            }

            return(1);
        }
Пример #13
0
        /***************************************************************
         *
         * Redundant Wavelet Transforms for Matrices
         *
         **************************************************************/

        /* WL_FrwtMatrix
         *
         * Perform a LEVELS-deep separable forward redundant wavelet transform of
         * SOURCE using the filters HIPASS and LOWPASS, storing results in volume
         * DEST.
         * ROWS and COLS indicate the size of the SOURCE matrix and rows and
         * columns of volume DEST.
         * The transformed coefficients in DEST are stored using an overcomplete
         * representation: each ROWSxCOLS matrix representing a level in the
         * multiresolution pyramid with coarse approximation in zeroth matrix and
         * the 3 detail signals at level i in matrix 3*i+j, where 1<=j<=3.
         * The output volume DEST has depth 3*levels+1.
         */
        public static int WL_FrwtMatrix(double[,] source,
                                        ref double[,,] dest,
                                        int rows,
                                        int cols,
                                        int levels, WL_Filter lowpass, WL_Filter hipass)
        {
            double[] tempSource;
            double[,] RowMatrix;
            double[,] ColMatrix;
            int c, r, level;
            int hori, vert, diag;

            /* allocate the temp arrays to hold 1-D results */
            RowMatrix = new double[2, cols];
            ColMatrix = new double[2, rows];

            tempSource = new double[rows];

            /* copy the source to dest to facilitate multiple levels */
            for (r = 0; r < rows; r++)
            {
                for (int colNum = 0; colNum < cols; colNum++)
                {
                    dest[0, r, colNum] = source[r, colNum];
                }
            }

            for (level = 1; level <= levels; level++)
            {
                /* setup indices to horizontal,vertical & diagonal detail signals */
                vert = 3 * (level - 1) + 1;
                hori = vert + 1;
                diag = hori + 1;

                /* transform each row */
                for (r = 0; r < rows; r++)
                {
                    var extract = WaveletUtil.Extract1DArray(dest, 0, r, cols);
                    var result  = WL_FrwtVector(extract, ref RowMatrix, cols, level, lowpass, hipass);

                    if (result != 1)
                    {
                        return(0);
                    }

                    for (int colNum = 0; colNum < cols; colNum++)
                    {
                        dest[0, r, colNum]    = RowMatrix[0, colNum];
                        dest[hori, r, colNum] = RowMatrix[1, colNum];
                    }
                }

                /* transform each column */
                /* first, run the transform on the lowpass output from the */
                /* frwt algorithm run on the rows */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        tempSource[r] = dest[0, r, c];
                    }
                    if (WL_FrwtVector(tempSource, ref ColMatrix, rows,
                                      level, lowpass, hipass) != 1)
                    {
                        return(0);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        dest[0, r, c]    = ColMatrix[0, r];
                        dest[vert, r, c] = ColMatrix[1, r];
                    }
                }

                /* now, for the high pass output */
                for (c = 0; c < cols; c++)
                {
                    for (r = 0; r < rows; r++)
                    {
                        tempSource[r] = dest[hori, r, c];
                    }
                    if (WL_FrwtVector(tempSource, ref ColMatrix, rows, level, lowpass, hipass) != 1)
                    {
                        return(0);
                    }
                    for (r = 0; r < rows; r++)
                    {
                        dest[hori, r, c] = ColMatrix[0, r];
                        dest[diag, r, c] = ColMatrix[1, r];
                    }
                }
            }

            return(1);
        }
Пример #14
0
        /* WL_IrwtMatrix
         *
         * Perform a LEVELS-deep inverse redundant wavelet transform of matrix SOURCE
         * using the filters HIPASS and LOWPASS, storing results in vector
         * DEST.
         * The coefficients in SOURCE are expected to be stored in the
         * overcomplete representation, each row representing a level in the
         * multiresolution pyramid with coarse approximation in zeroth row and
         * the detail signals at level i in the ith row.
         * LENGTH is the length of the rows of SOURCE & of the vector DEST.
         */
        public static int WL_IrwtMatrix(double[,] source,
                                        ref double[] dest,
                                        int length,
                                        int levels, WL_Filter lowpass, WL_Filter hipass)
        {
            int i, j, level, left, right, pow2;
            int hisize, lowsize;
            int lowoffset, hioffset;

            double[] hitemp;
            double[] lowtemp;                /* extended source vector */
            double[] hicoefs;
            double[] lowcoefs;

            // These are "pointers" into arrays
            int hidata;
            int lowdata;
            int result;

            /* allocate memory for the extended copies of hi & low source vectors */
            pow2      = WaveletUtil.WL_pow2(levels - 1);
            lowoffset = lowpass.Offset * pow2;
            hioffset  = hipass.Offset * pow2;
            lowsize   = (lowpass.Length - 1) * pow2 + 1;
            hisize    = (hipass.Length - 1) * pow2 + 1;
            left      = Math.Max(lowoffset, hioffset);
            right     = Math.Max(lowsize - lowoffset - 1, hisize - hioffset - 1);

            hitemp  = new double[length + (left + right) * pow2];
            lowtemp = new double[length + (left + right) * pow2];

            /* allocate memory for the lowpass & highpass filter coefficients */
            hicoefs  = new double[hisize * pow2];
            lowcoefs = new double[lowsize * pow2];

            /* copy the lowpass signal to dest to facilitate multiple levels */
            for (i = 0; i < length; i++)
            {
                dest[i] = source[0, i];
            }

            for (pow2 = WaveletUtil.WL_pow2(levels - 1), level = levels - 1; level >= 0;
                 level--, pow2 /= 2)
            {
                /* dilate the filters */
                Dilate_filter(lowpass.Coefs, ref lowcoefs, lowpass.Length, level);
                Dilate_filter(hipass.Coefs, ref hicoefs, hipass.Length, level);
                lowoffset = lowpass.Offset * pow2;
                hioffset  = hipass.Offset * pow2;
                lowsize   = (lowpass.Length - 1) * pow2 + 1;
                hisize    = (hipass.Length - 1) * pow2 + 1;
                left      = Math.Max(lowoffset, hioffset);
                right     = Math.Max(lowsize - lowoffset - 1, hisize - hioffset - 1);

                /* make periodic extension of dest vector */
                j = 0;
                for (i = length - left; i < length; i++, j++)
                {
                    lowtemp[j] = dest[i];
                    hitemp[j]  = source[level + 1, i];
                }
                for (i = 0; i < length; i++, j++)
                {
                    lowtemp[j] = dest[i];
                    hitemp[j]  = source[level + 1, i];
                }
                for (i = 0; i < right; i++, j++)
                {
                    lowtemp[j] = dest[i];
                    hitemp[j]  = source[level + 1, i];
                }

                /* convolve the data */
                result  = 0;
                lowdata = left - lowoffset;
                hidata  = left - hioffset;
                for (i = 0; i < length; i++, lowdata++, hidata++)
                {
                    double hisum = 0, lowsum = 0;
                    for (j = 0; j < lowsize; j++)
                    {
                        lowsum += lowtemp[lowdata + j] * lowcoefs[j];
                    }

                    for (j = 0; j < hisize; j++)
                    {
                        hisum += hitemp[hidata + j] * hicoefs[j];
                    }

                    dest[result++] = (lowsum + hisum) * 0.5;
                }
            }

            return(1);
        }