Diskreetne koosinusteisendus c#

Diskreetne koosinusteisendus on üks Fourieri laadseid teisendusi, mis esitab funktsiooni koosinuste summana. DCT-d kasutatakse kadudega pakkimisel  näiteks JPEG standardis. Kirjutasin kiire DCT üles c# keeles mängimiseks. Ajaline keerukus ei ole FFT tasemel aga koodi keerukus on hea.

2d DCT on 1d DCT igale reale ja veerule, algselt üritasin kadudega teksti pakkida selle koodiga, mis on naljakas ettevõtmine iseenesest ja töötab. Esimene funktsioonid annab koefitsiendid, teine algsed arvud, et pakkimiseks kasutada tuleb koefitsiendid ümardada mingile maani. Suurim arv(esimene arv massiivis) on DC koefitsient.


static double[] DCT1D(double[] pt)
        {
            const int size = 8;
            if (pt.Length != size)
                return null;
            double sqrt = Math.Sqrt((double)2 / size);
            double[] coefficients = new double[size];
            double sqrt2 = (double)1 / Math.Sqrt((double)2);
            for (int coef = 0; coef < size; coef++)
            {
                for (int i = 0; i < size; i++)
                {
                    coefficients[coef] += pt[i] * Math.Cos( ((2.0 * (double)i + 1.0) * (double)coef * Math.PI) / (double)(2.0 * (double)size));
                }
                if (coef > 0)
                    coefficients[coef] *= sqrt * 1;
                else
                    coefficients[coef] *= sqrt * sqrt2;
            }
            return coefficients;
        }

static double[] IDCT1D(double[] coeffs)
        {
            const int size = 8;
            if (coeffs.Length != size)
                return null;
            double sqrt = Math.Sqrt((double)2 / size);
            double[] pts = new double[size];
            double sqrt2 = (double)1 / Math.Sqrt((double)2);
            for (int pt = 0; pt < size; pt++)
            {
                for (int i = 0; i < size; i++)
                {
                    double cj = 0;
                    if (i > 0)
                        cj = 1;
                    else
                        cj = sqrt2;
                    pts[pt] += cj * coeffs[i] * Math.Cos(((2.0 * (double)pt + 1.0) * (double)i * Math.PI) / (double)(2.0 * (double)size));
                }
                    pts[pt] *= sqrt;
            }
            return pts;
        }


return pts;
}

 

Advertisements