effizient programmieren - suche tips...



  • na des mach ich doch auch...
    nur das es nicht ganz so einfach ist, da ich die dunklen werte gesondert behandeln muss. das histogram hat ne ziemlich charakteristische kurve, bei der erst ein haufen schwarze werte auftauchen, dann geht das histogram zurück und hat dann erst wieder bei den relevanten grauwerten größere werte.
    mit dem geglätteten histogram such ich dann nach dem minimum. alle werte darunter bekommen den neuen wert 0, den rest teil ich gleichmäßig von 1-31 auf.
    sinn des ganzen? schwarzabstufungen sind in der weiterverabreitung störend, da sie zum inhalt des bildes nix beitragen.
    tja, dadurch ist die zuordnung nich ganz so einfach. ich merk mir dann halt in einem array die grenzen und such dann unter welcher grenze der jeweilig grauwert liegt.
    alles in allem brauch mein rechi wohl so an die 4 minuten um 1 (!) bild umzurechnen und das mal 64... gute nacht...



  • vielleicht würde es ja (etwas zumindest) bringen, wenn ich mir vorher ein array anlege, dass auf den indizees (0-255) den passenden grauwert speichert. da müsste ich nicht jedesmal umständlich ermitteln, mit welchem wert ich ersetzen muss...
    wird aber schon wieder komplizierter, wenn es auch negative grauwerte gibt...



  • Servus,

    da ich derzeit eine ähnliche Problemstellung hatte, erstmal meine Skalierungsfunktion

    void BuildLinearScale(const double ValMin, const double ValMax, const int iDisc, double *dDisc)
    	{
    		double Bandwidth;
    		double Delta;
    		int i;
    
    		Bandwidth=0.;
    		Bandwidth+=fabs(ValMax);
    		Bandwidth-=fabs(ValMin);
    		Delta=Bandwidth/iDisc;
    
    		for(i=0;i<iDisc;i++) dDisc[i]=ValMin+i*Delta;		
    	}
    

    Die Anzahl der Diskretisierungen "iDisc" ist freiwählbar. Mit dieser Funktion untersuche ich mein 4D Array (!), 3 für den Raum und eine für die Zeit nach Werten in dieser Skala.

    for(i=0;i<iXCells;i++)
    	for(j=0;j<iYCells;j++)
    		for(k=0;k<iZCells;k++)
    			{
    				for(n=0;n<iNDumps;n++)
    					{
    						for(l=0;l<iDisc-11;l+=10)
    							{
    								if ((TFx(n,i,j,k)<=dDisc[l+1]) && (dDisc[l]>=TFx(n,i,j,k))) TP(l,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+1]) && (dDisc[l]>=TFy(n,i,j,k))) TP(l,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+1]) && (dDisc[l]>=TFz(n,i,j,k))) TP(l,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+2]) && (dDisc[l+1]>=TFx(n,i,j,k))) TP(l+1,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+2]) && (dDisc[l+1]>=TFy(n,i,j,k))) TP(l+1,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+2]) && (dDisc[l+1]>=TFz(n,i,j,k))) TP(l+1,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+3]) && (dDisc[l+2]>=TFx(n,i,j,k))) TP(l+2,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+3]) && (dDisc[l+2]>=TFy(n,i,j,k))) TP(l+2,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+3]) && (dDisc[l+2]>=TFz(n,i,j,k))) TP(l+2,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+4]) && (dDisc[l+3]>=TFx(n,i,j,k))) TP(l+3,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+4]) && (dDisc[l+3]>=TFy(n,i,j,k))) TP(l+3,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+4]) && (dDisc[l+3]>=TFz(n,i,j,k))) TP(l+3,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+5]) && (dDisc[l+4]>=TFx(n,i,j,k))) TP(l+4,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+5]) && (dDisc[l+4]>=TFy(n,i,j,k))) TP(l+4,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+5]) && (dDisc[l+4]>=TFz(n,i,j,k))) TP(l+4,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+6]) && (dDisc[l+5]>=TFx(n,i,j,k))) TP(l+5,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+6]) && (dDisc[l+5]>=TFy(n,i,j,k))) TP(l+5,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+6]) && (dDisc[l+5]>=TFz(n,i,j,k))) TP(l+5,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+7]) && (dDisc[l+6]>=TFx(n,i,j,k))) TP(l+6,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+7]) && (dDisc[l+6]>=TFy(n,i,j,k))) TP(l+6,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+7]) && (dDisc[l+6]>=TFz(n,i,j,k))) TP(l+6,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+8]) && (dDisc[l+7]>=TFx(n,i,j,k))) TP(l+7,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+8]) && (dDisc[l+7]>=TFy(n,i,j,k))) TP(l+7,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+8]) && (dDisc[l+7]>=TFz(n,i,j,k))) TP(l+7,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+9]) && (dDisc[l+8]>=TFx(n,i,j,k))) TP(l+8,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+9]) && (dDisc[l+8]>=TFy(n,i,j,k))) TP(l+8,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+9]) && (dDisc[l+8]>=TFz(n,i,j,k))) TP(l+8,i,j,k)+=1.;
    
    								if ((TFx(n,i,j,k)<=dDisc[l+10]) && (dDisc[l+9]>=TFx(n,i,j,k))) TP(l+9,i,j,k)+=1.;
    								if ((TFy(n,i,j,k)<=dDisc[l+10]) && (dDisc[l+9]>=TFy(n,i,j,k))) TP(l+9,i,j,k)+=1.;
    								if ((TFz(n,i,j,k)<=dDisc[l+10]) && (dDisc[l+9]>=TFz(n,i,j,k))) TP(l+9,i,j,k)+=1.;
    							}
    
    						qty=(n+1)*iXCells*iYCells*iZCells;
    						for(l=0;l<iDisc-1;l++) TP(l,i,j,k)/=qty;
    						for(l=0;l<iDisc-1;l++) TE(n,i,j,k)+=CalcSingleEntropy(TP(l,i,j,k));
    						for(l=0;l<iDisc-1;l++) TP(l,i,j,k)*=qty;
    					}
    				PrintProgress(now,end);	
    				now+=1.;
    			}
    

    n=Zeitschritt
    i,j,k=x,y,z Koordinate
    TFX,TFy,TFz mein 4D Array

    Dieser Schreibaufwand in der letzten For-Schleife hat für deutlichen Schub gesorgt, der Prozessor kann dadurch ungestörter seine eigentliche Arbeit leisten, anstatt die Zählvariablen zu inkrementieren und nach größer kleiner zu prüfen.

    Winn



  • musicman schrieb:

    July schrieb:

    was verstehst du unter "umskalierung von grauwerten"? das ist doch das, was ich machen will und was ich die ganze zeit zu erklären versuche, oder nicht???

    Genau, und das macht der Algo den ich grad gepostet habe.

    Glaube ich nicht. Ich glaube, dass der Code, den du da gepostet hast, nur Unsinn macht. 😉



  • @Winn:

    das heißt, du testet deine grenzen in 10er-schritten ab, wenn ich das richtig verstehe. hmm, schon möglich, dass es effizienter ist, als alle grenzen einzeln durchlaufen zu lassen...
    allerdings, was wäre im vergleich zu der idee mir halt vorher schon ein array anzulegen, welches über den index (=alter grauwert) zum neuen grauwert führt?
    so bräuchte ich gar keine tests wegen der grenzen mehr machen, sondern würde einfach den wert jedes voxels (v-alt) mit dem wert des arrays an der stelle v-alt ersetzen...
    oder lahmt das ebenfalls?



  • July schrieb:

    @Winn:

    das heißt, du testet deine grenzen in 10er-schritten ab, wenn ich das richtig verstehe. hmm, schon möglich, dass es effizienter ist, als alle grenzen einzeln durchlaufen zu lassen...
    allerdings, was wäre im vergleich zu der idee mir halt vorher schon ein array anzulegen, welches über den index (=alter grauwert) zum neuen grauwert führt?
    so bräuchte ich gar keine tests wegen der grenzen mehr machen, sondern würde einfach den wert jedes voxels (v-alt) mit dem wert des arrays an der stelle v-alt ersetzen...oder lahmt das ebenfalls?

    Also ich denke, daß es vom Prinzip meinem Beispiel gleicht. Das Array "ALT" wird durch ein Array "NEU" neu kategorisiert. Das entspricht einer linearen Skalierung oder Quantisierung (Abstände $$\Delta_i=\Delta_{i+1}$$). Bei der Überprüfung oder beim Schreiben der "NEUEN" Werte in die "ALTEN" Werte wirst Du wahrscheinlich ähnliche Prüfungsroutinen (Setze NEU Werte, wenn ALT Wert in einem Interval [a,b] liegt) haben, die wenn Du sie in einem 10er Block zusammenführst, schneller sind. Hab ich das richtig verstanden ?



  • Bei der Überprüfung oder beim Schreiben der "NEUEN" Werte in die "ALTEN" Werte wirst Du wahrscheinlich ähnliche Prüfungsroutinen (Setze NEU Werte, wenn ALT Wert in einem Interval [a,b] liegt) haben, die wenn Du sie in einem 10er Block zusammenführst, schneller sind. Hab ich das richtig verstanden ?

    na ja, ich spar mir eigentlich die prüfroutinen. wenn mein alter wertebereich von 0-255 geht und ich meine intervallgrenzen berechnet habe (sind ja nicht ganz linear über den wertebereich verteilt), dann leg ich mir erstmal ein array mit 256 einträgen an und jeder eintrag enthält den meinen intervallgrenzen entsprechenden neuen wert, d.h angenommen array[180] = 7 (--> alter wert 180 entspricht neuem wert 7)
    nun kann ich meinen voxelhaufen durchlaufen und brauch für jeden punkt nur noch:

    img(x,y,z) = array[img(x,y,z)]

    damit sollte ich mir jede menge vergleiche sparen, denke ich...

    (übrigens hat sich mein geschwindigkeitsproblem irgendwie in luft aufgelöst... kann es mir nur so erklären, dass die einführung des arrays und das löschen ein paar ziemlich dämlicher statements ausschlaggebend was. hatte ja vorher in meinen for-schleifen noch eine weitere for-schleife zum auffinden des neuen wertes + 3 weitere statements. jetzt steht in meinen for-schleifen nur noch 1 statement 👍 )



  • Gregor_ schrieb:

    musicman schrieb:

    July schrieb:

    was verstehst du unter "umskalierung von grauwerten"? das ist doch das, was ich machen will und was ich die ganze zeit zu erklären versuche, oder nicht???

    Genau, und das macht der Algo den ich grad gepostet habe.

    Glaube ich nicht. Ich glaube, dass der Code, den du da gepostet hast, nur Unsinn macht. 😉

    😕 😕
    Ich denke, der Algorithmus macht genau eine lineare Skalierung eines Arrays, oder??



  • musicman schrieb:

    Gregor_ schrieb:

    musicman schrieb:

    July schrieb:

    was verstehst du unter "umskalierung von grauwerten"? das ist doch das, was ich machen will und was ich die ganze zeit zu erklären versuche, oder nicht???

    Genau, und das macht der Algo den ich grad gepostet habe.

    Glaube ich nicht. Ich glaube, dass der Code, den du da gepostet hast, nur Unsinn macht. 😉

    😕 😕
    Ich denke, der Algorithmus macht genau eine lineare Skalierung eines Arrays, oder??

    Ja, ok. Das stimmt natürlich schon. Es wird aber nicht auf die angesprochenen 32 Werte skaliert, sondern etwas ganz anderes gemacht.

    Was ist denn dein maxVal? Der maximale Wert, der im alten Bild auftauchen kann? Gehen wir mal davon aus, dass das 255 ist und gehen wir auch davon aus, dass oldVal[i] für ein i 255 ist. Dann ist der neue Wert 255*255/32=2032,03125. Oder soll maxVal der neue maximale Wert sein? Dann wäre bei oldVal[i]=255 der neue Wert (mit maxVal=32) 255*32/32=255. Dann würde also garnichts passieren. Die Formel sollte eher folgendermaßen aussehen:

    neuerWert = alterWert*neuerMaximalwert/alterMaximalwert.



  • @Gregor:
    Ok, sorry, da hab ich wohl was anderes getippt als ich eigentlich gemeint hab. Bei mir aufm Schmierzettel steht es immer noch korrekt 😉
    Im Beitrag hab ich's jetzt auch korrigiert.


Anmelden zum Antworten