if-Bedingung wird nie wahr



  • Hi(gh)!

    Zum besseren Verständnis vorweg: yip (Yadgar's Image Processor) ist ein konsolenbasiertes (für Linux und Windows) Bildbearbeitungsprogramm, an dem ich seit einigen Jahren programmiere... voriges Jahr hatte ich mich schon einmal in diesem Zusammenhang an d.c.l.i-c++ gewandt.

    Mein aktuelles Problem bezieht sich auf die neu implementierte "-c64"-Funktionalität, ein Kommando, das eingelesene True-Color-Bilder in die 16farbige Palette des Commodore 64 umrechnet und, falls die Bilddateien nicht bildfüllend sind (40 x 25 Pixel im Blockgrafik- und 160 x 200 Pixel im Multicolor-Modus) die fehlenden Zeilen oder Spalten mit einer aus diesen 16 Farben wählbaren Füllfarbe auffüllt. Diese beiden Funktionen arbeiten einwandfrei; beim Multicolor-Modus kommt jedoch eine dritte Funktion hinzu, in deren Code ein für mich nicht nachvollziehbarer Fehler steckt.

    Entsprechend der hardwareseitig vorgegebenen Beschränkung der freien Farbwahl im Multicolor-Modus des C 64 teilt diese dritte Funktion, c64multicolor_correct() das Bild in Abschnitte zu jeweils 4 x 8 Pixel, zählt in jedem dieser Abschnitte die vorkommenden Farben; falls die Anzahl der Farben größer ist als 4 ist, werden die Häufigkeiten der Farben ermittelt, die Farben absteigend nach ihrer Häufigkeit sortiert und alle Farben ab der fünften Farbe durch die im RGB-Farbraum nächste unter den ersten vier Farben ersetzt.

    Soweit die Theorie... hier der Code:

    void c64multicolor_correct(vector<vector<pixel> >& c64img, vector<vector<pixel> >& c64_area)
    {
      short a, b, i, j, k, l, m, n, colnum_area, freq;
      pixel p;
      rgb c;
      vector<rgb> areacols;
      vector<short> colfreqs;
      bool match;
    
    
    
    
      for (a=24; a<32; a+=8) // zu Testzwecken wird nur ein einzelner 4 x 8-Bereich eingelesen! Bitte anschließend korrigieren!
      {
        for (b=56; b<60; b+=4)
        {
          c64_area.resize(8);
          for (i=a; i<a+8; i++) // pixels from image are copied into temporary 4 by 8 pixel vector
          {
            for (j=b; j<b+4; j++)
            {
              p.set_red((unsigned char)c64img[i].at(j).get_red());
              p.set_green((unsigned char)c64img[i].at(j).get_green());
              p.set_blue((unsigned char)c64img[i].at(j).get_blue());
    
              //cout << "Pixel (" << b+j << "/" << a+i << "): rgb <" << p.get_red() << "," << p.get_green() << "," << p.get_blue() << ">" << endl;
    
              c64_area[i-a].push_back(p);
            }
          }
          areacols.resize(0);
          for (k=0; k<8; k++) // vector containing different colors in temporay 4 by 8 pixel vector is created
          {
            for (l=0; l<4; l++)
            {
              c.red = c64_area[k].at(l).get_red();
              c.green = c64_area[k].at(l).get_green();
              c.blue = c64_area[k].at(l).get_blue();
              match=false;
              if (k==0 && l==0)
          {
                areacols.push_back(c);
          }
              else
              {
                for (m=0; m<areacols.size(); m++)
                {
                  if (c.red == areacols[m].red && c.green == areacols[m].green && c.blue == areacols[m].blue)
                  {
                    match=true;
                  }
                }
                if (match == false) // new color found
                {
                  areacols.push_back(c);
                }
              }
        
            }
          }
          colnum_area = areacols.size();
          //cout << "Number of different colors in 4 by 8 pixel area (" << b << "/" << a << " to " << b+3 << "/" << a+7 << "): " << colnum_area << endl;
          if (colnum_area > 4)
          {
        colfreqs.resize(colnum_area);
        for (m=0; m<colfreqs.size(); m++)
          colfreqs[m] = 0;
        m=0;
        for (k=0; k<8; k++)
        {
          for (l=0; l<4; l++)
          {
            if ( k == 0 && l == 0)
            {
              colfreqs[m]++;
            }
            else
            {
              c.red = c64_area[k].at(l).get_red();
              c.green = c64_area[k].at(l).get_green();
              c.blue = c64_area[k].at(l).get_blue();
                  while (!(c.red == areacols[m].red && c.green == areacols[m].green && c.blue == areacols[m].blue))
            m++;
              colfreqs[m]++;
              m = 0;
            }
          }
        }
        for (m = 0; m < colnum_area; m++)
          cout << "Farbe #" << m << ": rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << "> - " << colfreqs[m] << " Pixel" << endl;
        qsrt(colfreqs, areacols, 0, colfreqs.size()-1);
        for (m = 0; m < colnum_area; m++)
          cout << colfreqs[m] << " Pixel: rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << ">" << endl;
    
        vector<rgb> fourcolors;
        for (m = 0; m < 4; m++)
          fourcolors.push_back(areacols[m]);
        vector<rgb> excesscolors;
        for (m = 4; m < colnum_area; m++)
          excesscolors.push_back(areacols[m]);
        
        
        
        rgb closest = fourcolors[0];
        for (m = 4; m < colnum_area; m++)
        {
          for (n = 0; n < 4; n++)
          {
            if (coldist(areacols[m], fourcolors[n]) < coldist(areacols[m], closest))
            {
              closest = fourcolors[n];
              cout << "rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << "> wird ersetzt durch <"<< fourcolors[n].red << "," << fourcolors[n].green << "," << fourcolors[n].blue << ">" << endl;
            }
          }
        }
        
    
        cout << Uuml << "bersch" << uuml << "ssige Farben:" << endl;
        for (m = 0; m < colnum_area-4; m++)
          cout << "rgb <" << excesscolors[m].red << "," << excesscolors[m].green << "," << excesscolors[m].blue << ">" << endl;
        
        
        for (k=0; k<8; k++)
        {
          for (l=0; l<4; l++)
          {
            match = false;
            m = 0;
            c.red = c64_area[k].at(l).get_red();
            c.green = c64_area[k].at(l).get_green();
            c.blue = c64_area[k].at(l).get_blue();
            while (match == false && m < colnum_area-4)
            {
              cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
                  if ((c.red == excesscolors[m].red) && (c.green == excesscolors[m].green) && (c.blue == excesscolors[m].blue))
                    match == true;
              m++;
            }
            cout << match << endl;
            if (match == true)
            {
              rgb closest = fourcolors[0];
              for (n=0; n<4; n++)
              {
              if (coldist(c, fourcolors[n]) < coldist(c, closest))
                  closest = fourcolors[n];
              }
              cout << a+k << endl;
              cout << b+l << endl;
              c64img[a+k].at(b+l).set_all(closest.red, closest.green, closest.blue);
            }
          }
        }
          }
        }
      }
    }
    

    Die Funktion bekommt zwei Referenzen auf Vektoren vom Typ pixel übergeben. Die Klasse pixel ist wie folgt definiert:

    class pixel
    {
      public:
        pixel(); // Standard-Konstruktor
        pixel (short, short, short); // Allgemeiner Konstruktor
        ~pixel(); // Destruktor
        void set_all(short, short, short);
        void set_red(short);
        void set_green(short);
        void set_blue(short);
        void get_all(rgb&);
        short get_red();
        short get_green();
        short get_blue();
        void invert();
        void rgb2grey();
        void rgb2grey(float, float, float);
        float getvalue();
      private:
        short r;
        short g;
        short b;
        short round(float);
    };
    
    pixel::pixel()
    {}
    
    pixel::pixel(short red, short green, short blue)
    {
      r = red;
      g = green;
      b = blue;
    }
    
    pixel::~pixel()
    {}
    
    void pixel::set_all(short red, short green, short blue)
    {
      r = red;
      g = green;
      b = blue;
    }
    
    void pixel::set_red(short red)
    {
      r = red;
    }
    
    
    void pixel::set_green(short green)
    {
      g = green;
    }
    
    void pixel::set_blue(short blue)
    {
      b = blue;
    }
    
    
    void pixel::get_all(rgb &tr)
    {
      tr.red = r;
      tr.green = g;
      tr.blue = b;
    }
    
    short pixel::get_red()
    {
      return r;
    }
    
    short pixel::get_green()
    {
      return g;
    }
    
    short pixel::get_blue()
    {
      return b;
    }
    
    void pixel::invert()
    {
      r = 255-r;
      g = 255-g;
      b = 255-b;
    }
    
    void pixel::rgb2grey()
    {
      float red = r*0.299;
      float green = g*0.587;
      float blue = b*0.114;
      float sum = red+green+blue;
      r = g = b = round(sum);
    }
    
    void pixel::rgb2grey(float redw, float greenw, float bluew)
    {
      float sumw = redw+greenw+bluew;
      float red = r*(redw/sumw);
      float green = g*(greenw/sumw);
      float blue = b*(bluew/sumw);
      float sum = red+green+blue;
      r = g = b = round(sum);
    }
    short pixel::round(float total)
    {
      short grey;
      if (total-floor(total) < 0.5)
        grey = floor(total);
      else
        grey = ceil(total);
    
      return grey;
    }
      for (k=0; k<8; k++)
        {
          for (l=0; l<4; l++)
          {
            match = false;
            m = 0;
            c.red = c64_area[k].at(l).get_red();
            c.green = c64_area[k].at(l).get_green();
            c.blue = c64_area[k].at(l).get_blue();
            while (match == false && m < colnum_area-4)
            {
              cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
                  if ((c.red == excesscolors[m].red) && (c.green == excesscolors[m].green) && (c.blue == excesscolors[m].blue))
                    match == true;
              m++;
            }
            cout << match << endl;
            if (match == true)
            {
    float pixel::getvalue()
    {
      float value;
      value = r*0.299+g*0.587+b*0.114;
      return value;
    }
    

    Nach diversen Testausgaben (der gefundenen Farben und deren Sortierung) erfolgt ein erneutes Durchgehen aller 32 Pixel des 4 x 8-Abschnittes; für jedes Pixel wird geprüft, ob seine Farbe mit einer der (in diesem Fall drei) überzähligen Farben identisch ist:

    for (k=0; k<8; k++)
        {
          for (l=0; l<4; l++)
          {
            match = false;
            m = 0;
            c.red = c64_area[k].at(l).get_red();
            c.green = c64_area[k].at(l).get_green();
            c.blue = c64_area[k].at(l).get_blue();
            while (match == false && m < colnum_area-4)
            {
              cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
                  if ((c.red == excesscolors[m].red) && (c.green == excesscolors[m].green) && (c.blue == excesscolors[m].blue))
                    match == true;
              m++;
            }
            cout << match << endl;
            if (match == true)
            {
                  [...]
    

    Obwohl laut Ausgabe bereits beim ersten Pixel die Gleichheit mit einer der überzähligen Farben erreicht ist, wird

    ((c.red == excesscolors[m].red) && (c.green == excesscolors[m].green) && (c.blue == excesscolors[m].blue))
    

    niemals wahr! Wieso?

    Die Objekte c und der Vektor excesscolors[] sind vom Typ rgb, im Gegensatz zu pixel keine Klasse, sondern eine einfache Struktur:

    struct rgb // global!
    {
      short red;
      short green;
      short blue;
    };
    

    Hier die vorhin angekündigte Ausgabe des Programms:

    Farbe #0: rgb <112,116,111> - 1 Pixel
    Farbe #1: rgb <253,254,252> - 12 Pixel
    Farbe #2: rgb <48,230,198> - 3 Pixel
    Farbe #3: rgb <66,69,64> - 6 Pixel
    Farbe #4: rgb <164,167,162> - 8 Pixel
    Farbe #5: rgb <0,0,0> - 1 Pixel
    Farbe #6: rgb <95,83,254> - 1 Pixel
    12 Pixel: rgb <253,254,252>
    8 Pixel: rgb <164,167,162>
    6 Pixel: rgb <66,69,64>
    3 Pixel: rgb <48,230,198>
    1 Pixel: rgb <0,0,0>
    1 Pixel: rgb <95,83,254>
    1 Pixel: rgb <112,116,111>

    Überschüssige Farben:
    rgb <0,0,0>
    rgb <95,83,254>
    rgb <112,116,111>
    112 116 111 | 0 0 0
    112 116 111 | 95 83 254
    112 116 111 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    48 230 198 | 0 0 0
    48 230 198 | 95 83 254
    48 230 198 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    0 0 0 | 0 0 0
    0 0 0 | 95 83 254
    0 0 0 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    48 230 198 | 0 0 0
    48 230 198 | 95 83 254
    48 230 198 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    48 230 198 | 0 0 0
    48 230 198 | 95 83 254
    48 230 198 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    66 69 64 | 0 0 0
    66 69 64 | 95 83 254
    66 69 64 | 112 116 111
    0
    95 83 254 | 0 0 0
    95 83 254 | 95 83 254
    95 83 254 | 112 116 111
    0
    253 254 252 | 0 0 0
    253 254 252 | 95 83 254
    253 254 252 | 112 116 111
    0
    164 167 162 | 0 0 0
    164 167 162 | 95 83 254
    164 167 162 | 112 116 111
    0

    Bis bald im Khyberspace!

    Yadgar



  • Bitte bearbeite Deinen Beitrag und schreibe ``` über und ``` unter Deinen Code. Oder Markiere den Code und klicke auf </>.

    Naja, gibt

    cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
    

    nun gleiche Werte pro Komponente aus, oder nicht?



  • @swordfish sagte in if-Bedingung wird nie wahr:

    Bitte bearbeite Deinen Beitrag und schreibe ``` über und ``` unter Deinen Code. Oder Markiere den Code und klicke auf </>.

    Zu spät, das geht jetzt schon nicht mehr... ich sehe jedenfalls nirgendwo eine Schaltfläche "Bearbeiten"...

    Naja, gibt

    cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
    

    nun gleiche Werte pro Komponente aus, oder nicht?

    Ja, tut es:

    1. Pixel im Bereich:

    112 116 111 | 0 0 0
    112 116 111 | 95 83 254
    112 116 111 | 112 116 111

    Im dritten Durchgang der Testschleife sind die Werte offensichtlich gleich - und trotzdem wird nicht nach true verzweigt!

    Verstehe ich nicht...

    Bis bald im Khyberspace!

    Yadgar



  • @yadgar sagte in if-Bedingung wird nie wahr:

    Zu spät, das geht jetzt schon nicht mehr... ich sehe jedenfalls nirgendwo eine Schaltfläche "Bearbeiten"...

    Rechts unter Deinem Betrag findest Du "Antworten", "Zitieren", den Reputation-Zähler und eine Schaltfläche mit drei Punkten hinter der sich ein Menü mit dem Menüpunkt "Bearbeiten" verbirgt.



  • @yadgar sagte in if-Bedingung wird nie wahr:

    match == true;

    Schau mal auf die Warnungen deines Compilers!



  • OMG war ich blind. Naja, es war spät.



  • @th69
    Mein Compiler (g++ 6.3.0 für Debian Linux) zeigte beim Kompilieren keine Warnungen an!



  • @yadgar sagte in if-Bedingung wird nie wahr:

    Mein Compiler (g++ 6.3.0 für Debian Linux) zeigte beim Kompilieren keine Warnungen an!

    Warnungen einschalten!? https://godbolt.org/g/YHS43u



  • @swordfish

    <anKopfklatsch>
    Natürlich! Klassischer Anfängerfehler! Vergleichsoperator == mit Zuweisungsoperator = verwechselt!
    </anKopfklatsch>

    Das Problem war also gar nicht die if-Verzweigung, sondern die darauf folgende vermeintliche Zuweisung... das kommt davon, wenn man zu selten in C++ programmiert! Ich sollte eigentlich wenigstens vier Tage in der Woche an yip arbeiten, dann käme ich auch schneller voran!

    Danke, Swordfish! Ich werde dich umgehend in die Credit-Liste am Anfang des Codes eintragen!

    Und jetzt als nächstes erstmal diverse "Max Canada Lynx"-Videos von Bernadette "WildlifeBernie" Hoffman (natürlich mit ihrer Erlaubnis, die sie mir schon vor einigen Monaten gegeben hat!) vervierundsechzigern...

    Und dann die nächste Funktion in yip implementieren: Bildarithmetik! Oder doch lieber erst die beiden Atari ST-Farbmodi?

    Bis bald im Khyberspace!

    Yadgar



  • @yadgar sagte in if-Bedingung wird nie wahr:

    Danke, Swordfish! Ich werde dich umgehend in die Credit-Liste am Anfang des Codes eintragen!

    Ähm. @Th69 hat es gesehen.
    Wie gesagt: In Zukunft bitte mit -Wall kompilieren.



  • Das war leider (wie eigentlich fast immer in der Programmiererei!) zu früh gefreut: solange ich nur einen einzigen (von insgesamt 1000) 4 x 8-Pixel-Bereich überprüfe, funktioniert die Ersetzung der überschüssigen Farben einwandfrei - sobald ich aber das gesamte Bild durchgehe, passiert bei Bereichen mit mehr als 4 Farben rein gar nichts!

    Ich war davon ausgegangen, dass es wohl an der fehlenden Neuinitialisierung der Vektoren fourcolours und excesscolors für die 4 häufigsten bzw. überschüssigen Farben gelegen haben könnte - leider änderte eine entsprechende Code-Änderung auch nichts am Ergebnis!

    Hier der aktuelle Code:

     void c64multicolor_correct(vector<vector<pixel> >& c64img, vector<vector<pixel> >& c64_area)
    {
      short a, b, i, j, k, l, m, n, colnum_area, freq;
      pixel p;
      rgb c;
      vector<rgb> areacols;
      vector<short> colfreqs;
      vector<rgb> fourcolors;
      vector<rgb> excesscolors;    
      bool match;
      
      
      
      
      for (a=0; a<200; a+=8) // zu Testzwecken wird nur ein einzelner 4 x 8-Bereich eingelesen! Bitte anschließend korrigieren!
      {  
        for (b=0; b<160; b+=4)
        {
          c64_area.resize(8);
          for (i=a; i<a+8; i++) // pixels from image are copied into temporary 4 by 8 pixel vector
          {
            for (j=b; j<b+4; j++)
            {
              p.set_red((unsigned char)c64img[i].at(j).get_red());
              p.set_green((unsigned char)c64img[i].at(j).get_green());
              p.set_blue((unsigned char)c64img[i].at(j).get_blue());
              c64_area[i-a].push_back(p);
            }
          }
          areacols.resize(0);
          for (k=0; k<8; k++) // vector containing different colors in temporay 4 by 8 pixel vector is created
          {
            for (l=0; l<4; l++)
            {
              c.red = c64_area[k].at(l).get_red();
              c.green = c64_area[k].at(l).get_green();
              c.blue = c64_area[k].at(l).get_blue();
              match=false;
              if (k==0 && l==0)
    	  {  
                areacols.push_back(c);
    	  }
              else
              {
                for (m=0; m<areacols.size(); m++)
                {
                  if (c.red == areacols[m].red && c.green == areacols[m].green && c.blue == areacols[m].blue)
                  {
                    match=true;
                  }  
                } 
                if (match == false) // new color found
                {
                  areacols.push_back(c);
                }
              }
    	  
            } 
          }
          colnum_area = areacols.size();
          if (colnum_area > 4)
          {
            fourcolors.resize(4);
            excesscolors.resize(colnum_area-4);
            colfreqs.resize(colnum_area);
            for (m=0; m<colfreqs.size(); m++)
            colfreqs[m] = 0;
            m=0;
            for (k=0; k<8; k++) 
            {
            for (l=0; l<4; l++)
            {
                if ( k == 0 && l == 0)
                {
                colfreqs[m]++;
                }
                else
                {
                c.red = c64_area[k].at(l).get_red();
                c.green = c64_area[k].at(l).get_green();
                c.blue = c64_area[k].at(l).get_blue();
                    while (!(c.red == areacols[m].red && c.green == areacols[m].green && c.blue == areacols[m].blue))
                m++;
                colfreqs[m]++;
                m = 0;
                }
            }
            }
    	/* for (m = 0; m < colnum_area; m++)
    	  cout << "Farbe #" << m << ": rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << "> - " << colfreqs[m] << " Pixel" << endl; */
    	qsrt(colfreqs, areacols, 0, colfreqs.size()-1);  
    	/* for (m = 0; m < colnum_area; m++)
    	  cout << colfreqs[m] << " Pixel: rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << ">" << endl; */
            
    	
    	for (m = 0; m < 4; m++)
    	  fourcolors.push_back(areacols[m]);
    	for (m = 4; m < colnum_area; m++)
    	  excesscolors.push_back(areacols[m]);
    	
    	
    	
    	/* rgb closest = fourcolors[0];
    	for (m = 4; m < colnum_area; m++)
    	{
    	  for (n = 0; n < 4; n++)
    	  {  
    	    if (coldist(areacols[m], fourcolors[n]) < coldist(areacols[m], closest))
    	    {  
    	      closest = fourcolors[n];
    	      cout << "rgb <" << areacols[m].red << "," << areacols[m].green << "," << areacols[m].blue << "> wird ersetzt durch <"<< fourcolors[n].red << "," << fourcolors[n].green << "," << fourcolors[n].blue << ">" << endl;
    	    }  
    	  }
    	}
    	
    
    	cout << Uuml << "bersch" << uuml << "ssige Farben:" << endl;
    	for (m = 0; m < colnum_area-4; m++)
    	  cout << "rgb <" << excesscolors[m].red << "," << excesscolors[m].green << "," << excesscolors[m].blue << ">" << endl; */
    	
    	
    	for (k=0; k<8; k++) 
    	{
    	  for (l=0; l<4; l++)
    	  {
            match = false;
    	    m = 0;
    	    c.red = c64_area[k].at(l).get_red();
    	    c.green = c64_area[k].at(l).get_green();
    	    c.blue = c64_area[k].at(l).get_blue();
    	    while (match == false /*&& m < colnum_area-4*/)
    	    {
    	      // cout << c.red << " " << c.green << " " << c.blue << " | " << excesscolors[m].red << " " << excesscolors[m].green << " " << excesscolors[m].blue << endl;
              if ((c.red == excesscolors[m].red) && (c.green == excesscolors[m].green) && (c.blue == excesscolors[m].blue))
                match = true;
    	      m++;
    	    }
    	    // cout << match << endl;
    	    if (match == true)
    	    {  
    	      rgb closest = fourcolors[0];
    	      for (n=0; n<4; n++)
    	      {
    		  if (coldist(c, fourcolors[n]) < coldist(c, closest))
    	          closest = fourcolors[n];
    	      }
    	      /* cout << a+k << endl;
    	      cout << b+l << endl; */
    	      c64img[a+k].at(b+l).set_all(closest.red, closest.green, closest.blue);
    	    } 
    	  }     
    	}      
        }
        }
      }
    }
    

    Wenn ich vor dem Teil, der nur bei mehr als 4 Farben ausgeführt wird, die Anzahl der Farben ausgeben lasse, wird immer "3" angezeigt - die Farbanzahl des allerersten 4 x 8-Pixel-Bereiches...



  • void c64multicolor_correct(std::vector<std::vector<pixel>>& c64img)
    {
     	for (std::size_t a = 0; a < 200; a += 8)
    	{
    		for (std::size_t b = 0; b < 160; b += 4)
    		{
    			std::vector<std::vector<pixel>> c64_area(8);
    			for (std::size_t i = a; i < a + 8; i++)
    				for (std::size_t j = b; j < b + 4; j++)
    					c64_area[i - a].push_back(c64img[i][j]);
    
    			std::vector<pixel> areacols;
    			areacols.push_back(c64_area[0][0]);
    
    			for (std::size_t k = 0; k < 8; k++)
    				for (std::size_t l = 0; l < 4; l++)
    					if (k && l && std::find(std::begin(areacols), std::end(areacols), c64_area[k][l]) == std::end(areacols))
    						areacols.push_back(c64_area[k][l]);
    
    			if (areacols.size() <= 4)
    				continue;
    
    			std::vector<short> colfreqs(areacols.size());
    				
    			for (std::size_t k = 0; k < 8; k++)
    			{
    				for (std::size_t l = 0; l < 4; l++)
    				{
    					if (k == 0 && l == 0) {
    						colfreqs[0]++;
    						continue;
    					}
    							
    					colfreqs[std::find(std::begin(areacols), std::end(areacols), c64_area[k][l]) - std::begin(areacols)]++;
    				}
    			}
    
    			qsrt(colfreqs, areacols, 0, colfreqs.size() - 1);
    
    			std::vector<pixel> fourcolors{ std::begin(areacols), std::begin(areacols) + 4 };
    			std::vector<pixel> excesscolors{ std::begin(areacols) + 4, std::end(areacols) };
    
    			for (std::size_t k = 0; k < 8; k++)
    			{
    				for (std::size_t l = 0; l < 4; l++)
    				{
    					if (std::find(std::begin(excesscolors), std::end(excesscolors), c64_area[k][l]) != std::end(excesscolors) ) {
    						pixel closest = fourcolors[0];
    						for (std::size_t n = 0; n<4; n++)
    							if (coldist(c64_area[k][l], fourcolors[n]) < coldist(c64_area[k][l], closest))
    								closest = fourcolors[n];
    
    						c64img[a + k][b + 1] = closest;
    					}
    				}
    			}
    		}
    	}
    }
    

    Das sollte äquivalent zu deinem Spaghetti von oben sein. class pixel braucht dafür noch einen Zuweisungsoperator und Vergleichsoperatoren. Debuggen darfst selbst.



  • @swordfish sagte in if-Bedingung wird nie wahr:

    Das sollte äquivalent zu deinem Spaghetti von oben sein. class pixel braucht dafür noch einen Zuweisungsoperator und Vergleichsoperatoren. Debuggen darfst selbst.

    Damit fange ich dann auch gleich an... in welcher Bibliothek finde ich z. B. die Funktion find()? Bei mir führte die gerade eben zu diesem Fehler hier:

    yip.cc: In function ‘void c64multicolor_correct(std::vector<std::vector<pixel> >&)’:
    yip.cc:3288:86: error: no matching function for call to ‘find(std::vector<pixel>::iterator, std::vector<pixel>::iterator, __gnu_cxx::__alloc_traits<std::allocator<pixel> >::value_type&)’
         if (k && l && std::find(std::begin(areacols), std::end(areacols), c64_area[k][l]) == std::end(areacols))
    

    Bis bald im Khyberspace!

    Yadgar



  • Steht da doch, in der std. Mit std::find via Google einfach zu finden.
    Was fehlt sind die inlcudes. In dem Fall #include <algorithm>



  • @schlangenmensch sagte in if-Bedingung wird nie wahr:

    via Google einfach zu finden.

    Yadgar googelt nicht gerne da

    @yadgar sagte in Spezifikation von 16bit-Graustufen-TIFFs?:

    Ich habe leider die Erfahrung gemacht, dass Google nicht mein Freund ist, sondern mir viel zu oft den Bildschirm nur mit nutzlosem Linkmüll vollknattert...

    💡



  • @swordfish

    Also, #include <algorithm> habe ich eingefügt - jetzt kennt das Programm meine Quicksort-Implementation qsrt() nicht mehr!

    Fehlermeldung:

    yip.cc: In function ‘void c64multicolor_correct(std::vector<std::vector<pixel> >&)’:
    yip.cc:3322:51: error: no matching function for call to ‘qsrt(std::vector<short int>&, std::vector<pixel>&, int, std::vector<short int>::size_type)’
        qsrt(colfreqs, areacols, 0, colfreqs.size() - 1);
    

    ...und das ist nur die erste einer langen Latte von Fehlermeldungen, eine kryptischer als die andere!

    qsrt ist in zwei Varianten definiert:

    void qsrt(vector<float>&, vector<pixel>&, unsigned int, unsigned int); 
    void qsrt(vector<short>&, vector<rgb>&, unsigned int, unsigned int); // descending!
    

    Und warum size_type statt Standardtypen für die Zählervariablen? Warum muss immer alles so kompliziert sein?

    Geht es nicht einfacher? Ich bin C++-Anfänger! Was ist denn der konkrete Grund dafür, dass colnum_area immer 3 bleibt? Mit einer turbo-optimierten Profi-Lösung (die noch dazu aus didaktischen Gründen fehlerhaft ist) kann ich nichts anfangen, die verstehe ich nämlich nicht!



  • @yadgar sagte in if-Bedingung wird nie wahr:

    qsrt ist in zwei Varianten definiert:

    void qsrt(vector<float>&, vector<pixel>&, unsigned int, unsigned int); 
    void qsrt(vector<short>&, vector<rgb>&, unsigned int, unsigned int); // descending!
    

    Mach

    void qsrt(vector<short>&, vector<pixel>&, int, std::size_t);
    

    draus.

    Und warum size_type statt Standardtypen für die Zählervariablen?

    Weil Speichergrößen nunmal std::size_t groß sein können.

    Was ist denn der konkrete Grund dafür, dass colnum_area immer 3 bleibt?

    Keine Ahnung. Wie gesagt: Debuggen darfst selbst.



  • @swordfish

    plonk



  • . o O ( wer nicht will der hat schon 👍 )



  • @swordfish sagte in if-Bedingung wird nie wahr:

    . o O ( wer nicht will der hat schon 👍 )

    Das war etwas voreilig... ich reagierte so angefressen, weil ich davon ausging, dass du der Meinung wärest, dass der Fehler etwas mit meiner veralteten bzw. umständlichen Datenstruktur zu tun hätte! Jetzt, wo ich sehe, dass das offensichtlich zwei ganz verschiedene "Baustellen" sind, würde ich es doch noch einmal versuchen, von Hand den Code durchzugehen...