예제 #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_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_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);
        }
예제 #6
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);
        }
예제 #7
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);
        }