Exemple #1
0
        /// <summary>
        /// Compute the Forward DCT
        /// </summary>
        /// <param name="imgBuffer">f(x, y); source image</param>
        /// <param name="dctBuffer">F(u, v); DCT coefficients</param>
        /// <param name="fBasis">DCT basis functions</param>
        public PixelArray ForwardDCT(PixelArray imgBuffer)
        {
            int N = fBlockSize;

            // extract the dimensions of the image
            int width = imgBuffer.Width;
            int height = imgBuffer.Height;

            // Create the array of DCT coefficients 
            PixelArray<RGBd> dctBuffer = new PixelArray<RGBd>(width, height);

            // intermediate result (an NxN block)
            PixelArray<RGBd> dctBlock = new PixelArray<RGBd>(N, N);

            //
            // for every NxN block of the image
            //
            for (int y = 0; y < height; y += N)
            {
                for (int x = 0; x < width; x += N)
                {
                    //
                    // do the first matrix multiplication
                    // ([fBasis]' [imgBuffer])
                    // and store the results in dctBlock
                    //
                    for (int col = 0; col < N; ++col)
                    {
                        for (int row = 0; row < N; ++row)
                        {
                            RGBd result = new RGBd(0.0, 0.0, 0.0);
                            for (int index = 0; index < N; ++index)
                            {
                                BGRb pixel = new BGRb(imgBuffer.GetPixelBytes(x + index, y + row));
                                double cosVal_transpose = fBasis[index, col];

                                result.red += cosVal_transpose * pixel.Red;
                                result.green += cosVal_transpose * pixel.Green;
                                result.blue += cosVal_transpose * pixel.Blue;
                            }
                            dctBlock.SetPixel(col, row, result);
                        }
                    }

                    //
                    // do the second matrix multiplication
                    // ([dctBlock] [fBasis])
                    // and store the results in dctBuffer
                    //
                    for (int col2 = 0; col2 < N; ++col2)
                    {
                        for (int row2 = 0; row2 < N; ++row2)
                        {
                            RGBd result = new RGBd(0.0, 0.0, 0.0);
                            for (int index = 0; index < N; ++index)
                            {
                                RGBd coeff = new RGBd(dctBlock.GetPixelBytes(col2, index));
                                double cosVal = fBasis[index, row2];

                                result.red += coeff.Red * cosVal;
                                result.green += coeff.Green * cosVal;
                                result.blue += coeff.Blue * cosVal;
                            }
                            dctBuffer.SetPixel(x + col2, y + row2, result);
                        }
                    }
                }
            }

            return dctBuffer;
        }
Exemple #2
0
        /// <summary>
        /// Compute the Inverse DCT
        /// </summary>
        /// <param name="dctBuffer">F(u, v); DCT coefficients</param>
        /// <param name="fBasis">DCT basis functions</param>
        /// <param name="imgBuffer">f(x, y); destination image</param>
        public PixelArray InverseDCT(PixelArray dctBuffer)
        {
            //int N = fBlockSize;

            // extract the dimensions of the DCT buffer
            int width = dctBuffer.Width;
            int height = dctBuffer.Height;

            PixelArray imgBuffer = new PixelArray(width, height, PixelType.BGRb, PixmapOrientation.TopToBottom, 1);

            // intermediate result (an NxN block)
            PixelArray dctBlock = new PixelArray(fBlockSize, fBlockSize, PixelType.RGBd, PixmapOrientation.TopToBottom, 1);

            //
            // for every NxN block of the coefficients
            //
            for (int y = 0; y < height; y += fBlockSize)
            {
                for (int x = 0; x < width; x += fBlockSize)
                {
                    //
                    // do the first matrix multiplication
                    // ([fBasis][dctBuffer])
                    // and store the results in dctBlock
                    //
                    for (int col = 0; col < fBlockSize; ++col)
                    {
                        for (int row = 0; row < fBlockSize; ++row)
                        {
                            RGBd result = new RGBd(0.0, 0.0, 0.0);
                            for (int index = 0; index < fBlockSize; ++index)
                            {
                                RGBd coeff = new RGBd();
                                coeff.SetBytes(dctBuffer.GetPixelBytes(x + index, y + row));
                                double cosVal = fBasis[col, index];

                                result.red += cosVal * coeff.Red;
                                result.green += cosVal * coeff.Green;
                                result.blue += cosVal * coeff.Blue;
                            }
                            dctBlock.SetPixel(col, row, result);
                        }
                    }

                    //
                    // do the second matrix multiplication
                    // ([dctBlock][fBasis]')
                    // and store the results in imgBuffer
                    //
                    for (int col2 = 0; col2 < fBlockSize; ++col2)
                    {
                        for (int row2 = 0; row2 < fBlockSize; ++row2)
                        {
                            RGBd result = new RGBd(0.0, 0.0, 0.0);
                            for (int index = 0; index < fBlockSize; ++index)
                            {
                                RGBd coeff = new RGBd();
                                coeff.SetBytes(dctBlock.GetPixelBytes(col2, index));
                                double cosVal_transpose = fBasis[row2, index];

                                result.red += coeff.Red * cosVal_transpose;
                                result.green += coeff.Green * cosVal_transpose;
                                result.blue += coeff.Blue * cosVal_transpose;
                            }

                            //
                            // assign the computed value back to the image
                            //
                            byte red = (byte)Math.Floor(result.Red + 0.5);
                            byte green = (byte)Math.Floor(result.Green + 0.5);
                            byte blue = (byte)Math.Floor(result.Blue + 0.5);

                            BGRb new_pixel = new BGRb(red, green, blue);
                            imgBuffer.SetPixel(x + col2, y + row2, new_pixel);
                        }
                    }
                }
            }

            return imgBuffer;
        }