Summe optimieren?



  • Hallo zusammen ...

    Folgendes Problem: Ich habe ein kleines Programm geschrieben, welches von zwei Kameras Bilder empfängt. Diese Bildinformationen liegen dann in Form zweier Matrizen(640x480) vor.
    Ich muss jetzt in beiden Bildern um ein bestimmtes Pixel herum alle Pixelwerte aufsummieren, welche innerhalb bestimmter Integrationsradien liegen.
    Bildlich gesprochen sollen Kreise verschiedener Radien um den Mittelpunkt gezogen werden und alle Pixel darin aufsummiert werden.

    Ich habe das Ganze zZ so gelöst:

    int R1=0, RR=0;
    	int R2=0, RR2=0;
    	int z=0;
    
    	for (n=0; n<480; n++)
    	{
    		for (m=0; m<640; m++)
    		{
    			R1=(n-A1Y)*(n-A1Y)+(m-A1X)*(m-A1X);				// (A1X,A1Y) sind die Koordinaten des zentralen Pixels
    			R2=(n-A1Y-SY)*(n-A1Y-SY)+(m-A1X-SX)*(m-A1X-SX);	// (SX,SY) ist der Versatz der beiden Kameras zueinander 
    
    			for (z=0;z<26;z++)
    			{
    					if (z==0) {RR=0; RR2=-1;}
    					if (z==1) {RR=4; RR2=0;}
    					if (z==2) {RR=25; RR2=4;}
    					if (z==3) {RR=49; RR2=25;}
    					if (z==4) {RR=100; RR2=49;}
    					if (z==5) {RR=121; RR2=100;}
    					if (z==6) {RR=144; RR2=121;}
    					if (z==7) {RR=169; RR2=144;}
    					if (z==8) {RR=196; RR2=169;}
    					if (z==9) {RR=225; RR2=196;}
    					if (z==10) {RR=400; RR2=225;}
    					if (z==11) {RR=900; RR2=400;}
    					if (z==12) {RR=1600; RR2=900;}
    					if (z==13) {RR=2500; RR2=1600;}
    					if (z==14) {RR=3600; RR2=2500;}
    					if (z==15) {RR=4900; RR2=3600;}
    					if (z==16) {RR=6400; RR2=4900;}
    					if (z==17) {RR=8100; RR2=6400;}
    					if (z==18) {RR=10000; RR2=8100;}
    					if (z==19) {RR=14400; RR2=10000;}
    					if (z==20) {RR=19600; RR2=14400;}
    					if (z==21) {RR=25600; RR2=19600;}
    					if (z==22) {RR=32400; RR2=25600;}
    					if (z==23) {RR=40000; RR2=32400;}
    					if (z==24) {RR=48400; RR2=40000;}
    					if (z==25) {RR=57600; RR2=48400;}
    
    					if ((R1<=RR && R1>RR2) && (m<640-abs(dX)) && (n<480-abs(dY)))	{IntRT1[z]=IntRT1[z]+Matrix1[m][n];}	
    					//IntRT1[z] ist ein 26-Zeilen-Vektor. In jede Zeile kommt dann der aufsummierte Wert eines Integrationsradius
    					if ((R2<=RR && R2>RR2) && (m<640-abs(dX)) && (n<480-abs(dY)))	{IntRT2[z]=IntRT2[z]+Matrix2[m][n];}
    
    			}			
    		}
    			i++;
    	}
    
    	for(n=1;n<26;n++)
    	{
    		IntRT1[n]=IntRT1[n]+IntRT1[n-1];
    		IntRT2[n]=IntRT2[n]+IntRT2[n-1];
    	}
    

    Um an die Gesamtintensität innerhalb eines größeren Radius zu kommen, summiere ich also immer die Pixel, die ich beim letzt kleinere nicht mitgenommen habe und addiere dann die Gesamtintensität des letzt kleineren dazu.

    Das Ganze dauert aber trotz meines Core2Quad(2,4GHz) um die 300ms. Das klingt zwar nicht soooo viel, aber ich muss mindestens 10 Bilder pro Sekunde schaffen. Die Zeit sollte sich also mindestens dritteln.

    Kann man da noch irgendwas optimieren?

    Danke schonmal für euere Hilfe! 🙂



  • Wenn du einen QuadCore hast, kannst du doch 4 Bilder gleichzeitig rechnen 😉

    Dann hättest du deine 10 Bilder/sec 🙂



  • Für sowas hier:

    if (z==0) {RR=0; RR2=-1;}
    if (z==1) {RR=4; RR2=0;}
    ...

    hat man eigentlich mal Arrays erfunden. 😉



  • Wenn man digitale Bildverarbeitung machen will, sollte man schon ein wenig Ahnung vom Programmieren haben.
    Hier sind ein paar Optimierungsansätze, allerdings ohne groß über den Algorithmus nachgedacht zu haben:

    int R1=0, RR=0;
        int R2=0, RR2=0;
    
    	const int RR_MAP[26] = { 0, 4, 25, 49, 100, 121, 144, 169, 196, 225, 400, 900, 1600, 2500, 3600, 4900, 6400, 8100, 10000, 14400, 19600, 25600, 32400, 40000, 48400, 57600 };
    	const int RR2_MAP[26] = { -1, 0, 4, 25, 49, 100, 121, 144, 169, 196, 225, 400, 900, 1600, 2500, 3600, 4900, 6400, 8100, 10000, 14400, 19600, 25600, 32400, 40000, 48400 };
    
        for (n=0; n<480; n++)
        {
    	    const int N2 = (n - A1Y) * (n - A1Y); // nur 480 mal berechnen statt 307200 mal!
    		const int NS2 = (n - A1Y - SY) * (n - A1Y - SY); // nur 480 mal berechnen statt 307200 mal!
            for (m=0; m<640; m++)
            {
                R1=N2+(m-A1X)*(m-A1X); 
                R2=NS2+(m-A1X-SX)*(m-A1X-SX);
    
                for (int z=0; z<26; z++)
                {
    				RR = RR_MAP[z];
    				RR2 = RR2_MAP[z];
    
                    if ((R1<=RR && R1>RR2) && (m<640-abs(dX)) && (n<480-abs(dY))) // wo kommen dX und dY her?! tests auf dX und dY können schon viel früher gemacht werden!
    				{
    				    IntRT1[z]=IntRT1[z]+Matrix1[m][n]; // du solltest Matrix1 vorher transponieren für schnelleren speicherzugriff!
    				}
    
                    //IntRT1[z] ist ein 26-Zeilen-Vektor. In jede Zeile kommt dann der aufsummierte Wert eines Integrationsradius
                    if ((R2<=RR && R2>RR2) && (m<640-abs(dX)) && (n<480-abs(dY))) // wo kommen dX und dY her?! tests auf dX und dY können schon viel früher gemacht werden!
    				{
    					IntRT2[z]=IntRT2[z]+Matrix2[m][n]; // du solltest Matrix2 vorher transponieren für schnelleren speicherzugriff!
    				}
    
                }           
            }
                i++; // wo kommt das i plötzlich her?!
        }
    
        for(n=1;n<26;n++)
        {
            IntRT1[n]=IntRT1[n]+IntRT1[n-1];
            IntRT2[n]=IntRT2[n]+IntRT2[n-1];
        }
    

Anmelden zum Antworten