Problem mit einem dynamischen Array



  • Ich habe nun das Problem, dass mein Programm nicht so will wie ich es möchte. Mein Problem ist wie folgt, ich möchte 1000 Farb-Histogramm erstellen, nur leider scheint er mir irgendwie einen seltsamen Wert zurück zugeben, welcher nicht sein kann.
    Denn mein Bildvektor für das erste Bild sieht bei allen Positionen gleich aus, was eigentlich nicht möglich ist, da jeder Pixel einen anderen Wert in der jeweiligen Position haben sollte.

    Die größe des Vektores eines Bildes berechne ich wie folgt:
    -Benutzer gibt quantum (z.B 32)ein
    - Farben sind immer 256
    256/32 = 8

    Das ergebnis wird dann hoch 3 genommen, wegen den Farben Rot, Grün, Blau
    also 8*8*8 = 512

    Soweit stimmt es ja alles.

    Nun zu den jeweiligen Pixel.
    Ich muss je nach ausgesuchten quantum, die Pixel mit dem Wert teilen:
    also für die den ersten Pixel:

    Rot 67/32= 2 * 8² = 128 (das ergebnis von vorhin also 256 Farben / 32 quantum)
    Grün 125/32 = 3 * 8 = 24
    Blau 113/32 =3

    Nun müssen wir alles zusammen zählen um die Position des vektors zu ermitteln für unser Bild = 128+24+3 = 155

    Also auf der Position 155 haben wir schon den ersten Wert gefunden:
    position[0,1,155,..., 512]
    Wert [x,x,1,...,x]

    Fall er wieder eine 155 findet soll er das dazu zählen:
    Sprich:
    position[0,1,155,..., 512]
    Wert [x,x,2,...,x]

    Das mache ich über:

    int posicionVector = ((Red/quantum) * pow((float)resQuantum, 2)) + ((Green / quantum) * resQuantum) + (Blue/quantum); 						vectorresQuantum[posicionVector]++;
    

    Nur leider sieht meine Datei ganz anders aus als sie eigentlich sollte:

    0   -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 -4.31602e+008 ... (bis 512)
    

    Ich suche nach dem Fehler schon wie eine Wahnsinnige und weiss nicht wo es genau schief geht :(!

    Der ganze quelltext

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <sstream>
    #include <fstream>
    #include <string>
    #include <math.h>
    #include <array>
    
    using namespace std;
    
    int resQuantum=0;
    int height, width;
    float *vectorresQuantum;
    
    string filepath;
    //
    int quantum=0;
    //stringstream ss (stringstream::in | stringstream::out);
    
    void wait()
    {
        cin.clear();
        cin.ignore(cin.rdbuf()->in_avail());
        cin.get(); 	
    }
    
    void SaveResultOfEachVectorImage(int imageclass, int quantumeUsed, float *vp, int arraysize)
    {
    	stringstream savefile_path;
    	string path;
    	savefile_path << "result/quantum" << quantumeUsed << ".txt";
    	path = savefile_path.str();
    
    	ofstream SaveFile;
    	SaveFile.open(path.c_str(), fstream::app);
    
    	if (SaveFile.is_open())
    	{
    		SaveFile << imageclass << "  ";
    
    		for(int pos=0; pos < arraysize; pos++ )
    		{
    				SaveFile  << " " << vp[pos];
    		}
    
    		SaveFile.close();
    	}
    	else cerr << "Unable to write in File" << endl;
    }
    
    void readFile(string file, int q, int directory, int size)
    {
    		int row=1;
    		string line;
    
    		ifstream readfile(file.c_str(), ios::in);
    
    		if(readfile.is_open())
    {
    			cout << "Open file: " << file << '\n' << '\n';
    			while(readfile.good())
    			{
    					getline(readfile, line, '\n');
    
    					if(row==2)
    					{
    						/*ss << line.substr(0,3);  Instead of actual version
    						ss >> height;*/
    						string number1 = line.substr(0,line.find(" "));
    						height = atoi(number1.c_str());
    
    						string number2 = line.substr(line.find(" ")+1,line.find('\n'));
    						width = atoi(number2.c_str());
    
    						/*cout << height << endl;
    						cout << width << endl;*/
    					}
    
    					//if(row==3) color = atoi(line.c_str())+1; It doesn't matter, because color is in every file 256
    
    					if(row>=4)
    					{
    						for (int RGB=0; RGB < 6; RGB++)
    						{
    							int index = line.find(' ');
    							int index2 = line.find(' ', index+1);
    							string Pixel1 = line.substr(0,index);
    							string Pixel2 = line.substr(index+1, line.find(' ', index+1) - index - 1);
    							//Pixel3 = line.substr(line.find(Pixel2)+Pixel2.size()+1,line.find("  "));
    							string Pixel3 = line.substr(index2+1, line.find(' ', index2+1) - index2 - 1);
    
    							int Red = atoi(Pixel1.c_str());
    							int Green = atoi(Pixel2.c_str());
    							int Blue = atoi(Pixel3.c_str());
    
    							//cout << line << endl << '\n';
    							/*cout << Red << endl;					 In order to check if the readed values are correct!
    							cout << Green << endl;
    							cout << Blue << endl << '\n';	*/					
    
    							int posicionVector = ((Red/quantum) * pow((float)resQuantum, 2)) + ((Green / quantum) * resQuantum) + (Blue/quantum); 
    							vectorresQuantum[posicionVector]++;
    							//cout << posicionVector << endl << '\n';
    
    							if(line.find("  ") == -1) break;
    							line.erase(0, line.find("  ")+2);
    						}
    					}
    					row++;
    			}
    			int Sum =0;
    			for(int d=0; d<size; d++)        
    			{   
    				vectorresQuantum[d]= ((vectorresQuantum[d])/((float)(height*width))); 
    				 Sum = Sum + vectorresQuantum[d];
    
    			}
    			cout << "Sum: " << Sum << endl;
    
    			//SaveResultOfEachVectorImage(directory, q, vectorresQuantum, size);
    
    		  readfile.close();
    		  readfile.clear();
    	}
    	else cerr << "Unabile to open file" << '\n' << endl;
    }
    
    int determinedArrayValue(int quantum)
    {
    	resQuantum = 256 / quantum;
    	int vectorsize = pow((float)resQuantum, 3);
    
    	return vectorsize;
    }
    
    int main(int argc, const char* argv[])
    {
    	int optionmenu;
    
    	do
    	{
    		cout << "0 - Obtain file for furthering process" << endl;
    		cout << "1 - Manhattan (L1)" << endl;
    		cout << "2 - Euclídea (L2)" << endl;
    		cout << "3 - Kullback Leiber divergence" << endl;
    		cout << "4 - Jeffrey divergence" << endl;
    		cout << "5 - close programm" << endl;
    
    		cin >> optionmenu;
    		switch(optionmenu)
    		{
    			case 0:
    			{
    				cout << "Enter a number for quantum" << '\n';
    				cin >> quantum;
    				cout << '\n';
    
    				int totalFileNumber=0;
    				//In order to save the content into a fichero for each quantum 
    				int arrayvalue = determinedArrayValue(quantum);
    				vectorresQuantum = new float [arrayvalue];
    
    				//vector normalized, 1000 files, value of the vector
    				float **vectornormalized = NULL;
    				vectornormalized = new float *[1000];
    				for(int a=0; a<1000; a++){vectornormalized[a] = new float [arrayvalue+1];}
    
    					for(int numberDirectory=0; numberDirectory<10; numberDirectory++)
    					{
    						for(int numberFile=0; numberFile<100 && totalFileNumber<1000; numberFile++)
    						{
    							//readfile
    							stringstream full_path;
    							full_path << "corel/" << numberDirectory << '/' << totalFileNumber << ".ppm";
    							filepath = full_path.str();
    							readFile(filepath, quantum, numberDirectory, arrayvalue);
    
    							totalFileNumber++;
    						}//end for numberfile
    					}//end for numberdirectoris
    
    				cout << "heigth:" << height << endl;
    				cout << "guantum: " << quantum << endl;
    				cout << "result color/q: " << resQuantum << endl;
    
    				delete []vectornormalized;
    				vectornormalized = NULL;
    
    				delete []vectorresQuantum;
    				vectorresQuantum = NULL;
    
    				wait();
    				break;
    			}//case 0 - obtail file
    
    			case 1:
    				{
    					break;
    				}
    
    			case 2:
    				{
    					break;
    				}
    
    			case 3:
    				{
    					break;
    				}
    
    			case 4:
    				{
    					break;
    				}
    		}
    	}
    	while(optionmenu!=5);
        return 0;
    }
    


  • Sorry für Doppelpost!

    Ich habe vergessen zu sagen, dass er mir die Werte richtig ermittelt für die Vektorposition, was daraus hinausläuft das er mir die datei richtig einlesen tut...

    Hier mal ein Stück aus der Datei für das erste Bild:

    P3 //dieser Wert ist nicht zu gebrauchen
    256 384 //höhe breite
    255//farbanzahl
    //r g b     //r g b                                         //r g b
    67 125 113  68 126 114  69 127 115  69 127 115  69 129 119  72 132 122
    
    73 133 125  73 133 125  75 135 127  68 128 120  72 129 120  79 136 127
    81 137 126  81 137 126  83 139 128  83 141 129  78 140 127  86 148 135
                                                                //r g b
    97 154 147  92 147 142  82 134 132  90 142 140  99 151 149  95 144 140
    

  • Mod

    Kahori_87 schrieb:

    Ich suche nach dem Fehler schon wie eine Wahnsinnige und weiss nicht wo es genau schief geht :(!

    Darf ich mal sagen: Kein Wunder?

    250 Zeilen sind definitiv zu lang, um mit globalen Variablen zu arbeiten. Da ist doch klar, dass man die Übersicht verliert. Zudem benutzt du new[] statt vector, dafür gibt es niemals Gründe. Hättest du vector genommen, hättest du einfach dessen Debugmodus anschalten können und hättest schon einmal viel mehr Hilfe bekommen. Du liest falsch ein. Erst prüfst du, ob der letzte Lesevorgang gut ging, dann liest du etwas, dann verarbeitest du das Ergebnis. Rate mal, was passiert, wenn etwas schief geht, z.B. Dateiende erreicht wird. Warum benutzt du Funktionen wie atoi bei denen man nicht vernünftig prüfen kann, ob sie funktioniert haben? Nicht, dass du es überhaupt versuchen würdest, den Erfolg zu prüfen. Es sind noch sehr viele andere kleine Fehler und Fehlerquellen in dem Programm, zwei nennenswerte sind das #include<array> und das Nutzen von in_avail() , von beiden bin ich mir sicher, dass du etwas anderes erwartest, als sie eigentlich tun.

    Gesamtanalyse: Dieses Programm übersteigt deine Fähigkeiten bei weitem. Niemand kann das debuggen. Neuschreiben ist meine Empfehlung. Aber zuerst musst du folgendes richtig lernen, sortiert nach Nötigkeit:
    0. Warum globale Variablen Schwierigkeiten machen und wie man sie vermeidet
    1. Wie man die C++ Container benutzt
    2. Wie man aus Streams verschiedene Datentypen ausliest
    3. Welche C-Konzepte in C++ durch bessere (oder besser mit dem Rest von C++ arbeitende) Konzepte ersetzt wurden.
    Das waren die wichtigsten. Ein paar Kleinigkeiten, unsortiert:
    - Wie man Dateistreams handhabt
    - Wie man weiß, was jedes Zeichen im Programm bedeutet, so dass man auch nur genau die Sachen macht, die man möchte
    - Welcher Datentyp für welche Aufgabe der richtige ist

    Wenn du die ersten 4 wirklich sicher beherrscht, bist du auf gutem Weg und kannst anfangen, dein Programm nochmal zu schreiben. Wenn du dann auch noch die anderen Kleinigkeiten behebst, bekommst du ein Programm, dass halb so lang und viermal so gut ist. Und funktioniert 🙂 . Oder falls nicht, dann findet man leicht und schnell heraus, warum nicht.



  • Hab das gelöst, hab vergessen das Array zu intializieren...

    for(int k=0; k<arrayvalue+1; k++)
    {
       vectornormalized[j][k] = 0;
    }
    

Anmelden zum Antworten