implementieren einer discrete cosine transformation



  • hi leute!
    ich will eine DCT implementieren!
    quelle: [url]http://tan.informatik.tu-chemnitz.de/~jan/MPEG/HTML/mpeg_tech.html
    [/url]
    jedoch hat sich ein mathematischen fehler in den code geschlichen, den ich nicht finde;-(
    als resultat im array IDCT sollte da an pos[0][0] 87 raus kommen...
    vielleicht findet von euch jemand den fehler...

    cu + thx

    #include <string>
    #include <iostream>
    #include <vector>
    #include <cmath>
    #include <boost/array.hpp>
    using namespace std;
    
    const float PI = 3.1415;
    
    int main()
    {
    	typedef boost::array<boost::array<int,8>,8> array8x8;
    
    	// array of arrays of seasons
        array8x8 pixel = {
            { { { 700, 0, 0, 0, 0, 0, 0, 0 } },
              { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
    		  { { 0, 0, 0, 0, 0, 0, 0, 0 } },
            }
        };
    
    	array8x8 IDCT;
    	typedef array8x8::iterator It1;
    	typedef boost::array<int,8>::iterator It2;
    
    	unsigned int Cu = 0;
    	unsigned int Cv = 0;
    	unsigned int u = 0;
    	unsigned int v = 0;
    	int F = 0;
    
    	// Zeilen
    	for (It1 pos1 = IDCT.begin(); pos1 != IDCT.end(); ++pos1)
    	{
    		u++;
    		// Spalten
    		for (It2 pos2=pos1->begin(); pos2 != pos1->end(); ++pos2) 
    		{
    			v++;
    
    			if(u == 0)
    				Cu = static_cast<int>(1 / sqrt (2.0));
    			else
    				Cu = 1;
    
    			if(v == 0)
    				Cv = static_cast<int>(1 / sqrt (2.0));
    			else
    				Cv = 1;
    
    			for(unsigned int x=0; x<=7; x++)
    			{
    				for(unsigned int y=0; y<=7; y++)
    				{
    					F += pixel[x][y] * Cu/2 * Cv/2 * static_cast<int>(cos((2*x + 1) * u * PI) / 16) * static_cast<int>(cos((2*y + 1) * v * PI) / 16);
    				}
    			}
    
    			// F in dft array schreiben
    			(*pos2) =  F;
    
    			F = 0;
    		}
    
    		v = 0;
    	}
    
    	cout << IDCT[0][0] << endl;
    
        cin.get();
    	return 0;
    }
    


  • Hast Du die Rechnung mal auf dem Papier durchgeführt? Und dann mit dem debugger die "Gedankengänge" Deines Rechners verfolgt?



  • > Cu = static_cast<int>(1 / sqrt (2.0));

    Kann nicht funktionieren... 😉

    // if(u == 0)
    //     Cu = static_cast<int>(1 / sqrt (2.0));
    // else
    //     Cu = 1; 
    
    const double InvSqrt2 = 1 / sqrt(2.0);
    
    Cu = (u == 0) ? InvSqrt2 : 1;
    

    Achja, und das boost::array bringt in diesem Falle nicht wirklich was...



  • TrueTom schrieb:

    Achja, und das boost::array bringt in diesem Falle nicht wirklich was...

    Kostet aber auch nicht wirklich was, so what?



  • Walli schrieb:

    TrueTom schrieb:

    Achja, und das boost::array bringt in diesem Falle nicht wirklich was...

    Kostet aber auch nicht wirklich was, so what?

    Kostet schon, und in diesem Falle stört das auch.



  • TrueTom schrieb:

    // if(u == 0)
    //     Cu = static_cast<int>(1 / sqrt (2.0));
    // else
    //     Cu = 1; 
    
    const double InvSqrt2 = 1 / sqrt(2.0);
    
    Cu = (u == 0) ? InvSqrt2 : 1;
    

    Wahnsinn, sieht gleich viel kürzer aus 😃 ! Ne, also wenn einem das obere schon zu lang ist, dann bitte gleich

    Cu = (u == 0) ? sqrt(.5) : 1;
    

    Ist aber auch Blödzinn, weil Cu ein unsigned ist.



  • TrueTom schrieb:

    Kostet schon...

    Höchstens ein wenig Compilezeit. Ich weiß nicht wie die Iteratoren implementiert sind, aber ich kann mir nicht vorstellen, dass es sich signifikant zur Laufzeit bemerkbar macht. Dafür sind die boost-Leute normalerweise zu clever.

    TrueTom schrieb:

    ...stört das auch.

    An dieser Stelle stört es mich auch, aber wenn er es nun lieber mag...



  • Walli schrieb:

    Cu = (u == 0) ? sqrt(.5) : 1;
    

    kann der compiler das sqrt rausoptimieren? denn sonst würde ich mir doch ne konstante dafür überlegen...



  • otze schrieb:

    kann der compiler das sqrt rausoptimieren? denn sonst würde ich mir doch ne konstante dafür überlegen...

    Hatte keine Lust das in den TR einzutippen 😉 .



  • hi!
    doch, musste das wohl eintippen in den taschenrechner;-)
    und nach kleinen änderungen des codes funzt es prima...
    kennt jemand ne bitmap lib, womit ich die farbe jedes pixels ganz einfach auslesen kann?

    cu


Anmelden zum Antworten