示例#1
0
        /* DILATE_FILTER
         *
         * Dilates the input vector SOURCE by INDEX, storing the result in DEST.
         * The length of the SOURCE vector is LENGTH.
         */
        public static void Dilate_filter(double[] source, ref double[] dest, int length, int index)
        {
            int i, j, k, power;

            power = WaveletUtil.WL_pow2(index);

            for (i = 0, j = 0; i < length; i++)
            {
                dest[j++] = source[i];
                for (k = 1; k < power; k++)
                {
                    dest[j++] = (double)0;
                }
            }
        }
示例#2
0
        /******************************************************************************
        *
        * MALLAT STORAGE FORMAT DATA STRUCTURE UTILITIES
        *
        ******************************************************************************/

        /* BoundingBox
         *
         * Calculates the left, right, top, and bottom boundary of the
         * detail signal for the described image.
         *
         *  ROWS   the number of rows in the full image
         *  COLS   the number of columns in the full image
         *  LEVEL  the level of the detail signal in question
         *  DETAIL the id of the detail signal in question
         *  LEFT, RIGHT, TOP, BOTTOM   the sides of the detail signal, calculated
         *                             by this function
         */
        public static int WL_BoundingBox(int rows, int cols, int level, int detail,
                                         out int left, out int right, out int top, out int bottom)
        {
            int rowSize;        /* size of each row at this level */
            int colSize;        /* size of each column at this level */

            /* compute bounding box of gamma quadrant */
            rowSize = cols / WaveletUtil.WL_pow2(level);
            colSize = rows / WaveletUtil.WL_pow2(level);

            left = right = top = bottom = 0;
            switch (detail)
            {
            case 0:
                /* upper right quadrant */
                left   = rowSize;
                right  = 2 * rowSize;
                top    = 0;
                bottom = colSize;
                break;

            case 1:
                /* lower left quadrant */
                left   = 0;
                right  = rowSize;
                top    = colSize;
                bottom = 2 * colSize;
                break;

            case 2:
                /* lower right quadrant */
                left   = rowSize;
                right  = 2 * rowSize;
                top    = colSize;
                bottom = 2 * colSize;
                break;

            default:
                Trace.WriteLine("WL_BoundingBox: unexpected detail value.");
                return(1);
            }
            return(0);
        }
示例#3
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);
        }
示例#4
0
        /* WL_SBFilterLoad
         *
         * Loads a subband filter from a data file.
         */
        public static int WL_SBFilterLoad(string fileName, string filterName, WL_SubbandFilter[,] newFilter)
        {
            int length, rows, cols;

            double[] data;

            // "Pointer" into data
            int d;
            int i;
            int coef;

            /* read in the data */
            if (WaveletUtil.WL_ReadAsciiDataFile(fileName, out rows, out cols, out data) != 0)
            {
                return(1);
            }

            length = rows * cols;
            d      = 0;

            /* create a new filter */
            WL_SubbandFilter filter = new WL_SubbandFilter
            {
                Info = new WL_Struct
                {
                    Name  = filterName,
                    Type  = "sbfilter",
                    PList = null
                }
            };

            /* fill in the data for the four filters */
            for (i = 0; i < 4; i++)
            {
                /* is there header data for a filter ? */
                if (length - 2 < 0)
                {
                    Trace.WriteLine("WL_SBFilterLoad : Bad descriptor file: not enough data");
                    return(1);
                }

                filter.Filters[i].Length = (int)(data[d++] + 0.5);
                filter.Filters[i].Offset = (int)(data[d++] + 0.5);
                length -= 2;
                /* is the offset legal? */
                if ((filter.Filters[i].Offset < 0) ||
                    (filter.Filters[i].Offset > filter.Filters[i].Length))
                {
                    Trace.WriteLine("WL_SBFilterLoad : Bad descriptor file: not enough data");
                    return(1);
                }
                /* is there enough data left for this filter? */
                if (length < filter.Filters[i].Length)
                {
                    throw new Exception("WL_SBFilterLoad : Bad descriptor file: not enough data");
                }

                /* store the filter coefficients into an array */
                filter.Filters[i].Coefs = new double[filter.Filters[i].Length];

                for (coef = 0; coef < filter.Filters[i].Length; coef++)
                {
                    filter.Filters[i].Coefs[coef] = data[d++];
                    length--;
                }
            }

            return(0);
        }
示例#5
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);
        }
示例#6
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);
        }
示例#7
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);
        }
示例#8
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);
        }
示例#9
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);
        }
示例#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);
        }