Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Fragen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
13.05.2004, 21:20 Uhr
Tommi Bisic



Hallo Leute!
Ich war schon lange nicht mehr hier aber das neue Semester hat angefangen und... naja...ihr wisst schon
Ich habe ein Problem mit ein Paar Schleifen die ich nicht verstehe.
Es geht um ein Programm dass Bilder in negatíve oder schwarz-weisse umwandeln kann.Zusätzlich kommt so ein Weich Zeichner -Effekt zum Einsatz
Das Programm sieht wie folgt aus;

C++:
#include <iostream.h>
#include <fstream.h>
#define ZEILE 480
#define SPALTE 640
void negativ(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE]);
void schwarz(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE]);
void filter(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE]);
int main()
{
  fstream File;
  char FileName[40],c;
  int Zeile, Spalte;
  unsigned char ucInBuffer[SPALTE][ZEILE];
  unsigned char ucOutBuffer[SPALTE][ZEILE];
  cout<<"Bitte Dateiname angeben: ";
  cin>>FileName;
  File.open(FileName,ios::in|ios::binary|ios::nocreate,0);
  //if (File.fail())
  if (!File)
    {
      cout<<"open Error"<<FileName<<endl;
      return 1;
    }
  for(Zeile=0;Zeile<ZEILE;Zeile++)
    {
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    File.read(&ucInBuffer[Spalte][Zeile],1);
    }
  File.close();
label:
  cout<<"n-negativ\ns-schwarz-weiss\nf-filter\nAuswahl:";
  cin>>c;
  switch(c)
    {
    case 'n':
      negativ(ucInBuffer, ucOutBuffer);
      break;
    case 's':
      schwarz(ucInBuffer, ucOutBuffer);
      break;
    case 'f':
      filter(ucInBuffer, ucOutBuffer);
      break;
    default:
      cout<<"Fehler";
      goto label;
    }
  cout<<"Bitte Dateiname angeben: ";
  cin>>FileName;
  File.open(FileName,ios::out|ios::binary,0);
  if (File.fail())
    {
      cout<<"open Error"<<FileName<<endl;
      return 1;
    }
  for(Zeile=0;Zeile<ZEILE;Zeile++)
    {
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    File.write(&ucOutBuffer[Spalte][Zeile],1);
    }
  File.close();
  return 0;
}
void negativ(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE])
     1
{
  int Zeile, Spalte;
  for(Zeile=0;Zeile<ZEILE;Zeile++)
    {
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    ucOut[Spalte][Zeile]=255-ucIn[Spalte][Zeile];
    }
}
void schwarz(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE])
{
  int Zeile, Spalte;
  for(Zeile=0;Zeile<ZEILE;Zeile++)
    {
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    {
      if(ucIn[Spalte][Zeile]>128)
        ucOut[Spalte][Zeile]=255;
      else
        ucOut[Spalte][Zeile]=0;
    }
    }
}
void filter(unsigned char ucIn[SPALTE][ZEILE], unsigned char ucOut[SPALTE][ZEILE])
{
#define FILTERLAENGE 15
#define ZEILENLAENGE 640
  int Zeile, Spalte;
  int iSumme, k, j;
  unsigned char ucZeile[ZEILENLAENGE];
  unsigned char ucZeileGefiltert[ZEILENLAENGE];
  for(Zeile=0;Zeile<ZEILE;Zeile++)
    {
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    {
      ucZeile[Spalte]=ucIn[Spalte][Zeile];
    }
      //Filtern
      for(k=0;k<(ZEILENLAENGE-FILTERLAENGE);k++)
    {
      iSumme=0;
      for(j=0;j<FILTERLAENGE;j++)
        iSumme=iSumme+ucZeile[k+j];
      ucZeileGefiltert[k]=iSumme/FILTERLAENGE;
    }
      //Zeile auffuellen
      for(k=(ZEILENLAENGE-FILTERLAENGE);k<ZEILENLAENGE;k++)
    {
      ucZeileGefiltert[k]=0;
    }
      for(Spalte=0;Spalte<SPALTE;Spalte++)
    {
      ucOut[Spalte][Zeile]=ucZeileGefiltert[Spalte];
    }
    }
}


Dabei verstehe ich vor allem diesen Teil, also diese Schleifen um genau zu sein, nicht:


C++:
for(Zeile=0;Zeile<ZEILE;Zeile++)
{
  for(Spalte=0;Spalte<SPALTE;Spalte++)
    {
      ucZeile[Spalte]=ucIn[Spalte][Zeile];
    }
  //Filtern
  for(k=0;k<(ZEILENLAENGE-FILTERLAENGE);k++)
    {
      iSumme=0;
      for(j=0;j<FILTERLAENGE;j++)
    iSumme=iSumme+ucZeile[k+j];
      ucZeileGefiltert[k]=iSumme/FILTERLAENGE;
    }
  //Zeile auffuellen
  for(k=(ZEILENLAENGE-FILTERLAENGE);k<ZEILENLAENGE;k++)
    {
  ucZeileGefiltert[k]=0;
}
  for(Spalte=0;Spalte<SPALTE;Spalte++)
    {
      ucOut[Spalte][Zeile]=ucZeileGefiltert[Spalte];
    }
}



Wäre für eure Hilfe sehr dankbar


Bearbeitung von Pablo:

Mit emacs eingerückt. So sieht es besser aus


Dieser Post wurde am 13.05.2004 um 22:58 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.05.2004, 21:32 Uhr
Pablo
Supertux
(Operator)


Was verstehst du nicht genau?

Tipp: Rücke deinen Code ein, sonst versteht das keiner
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.05.2004, 22:34 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


also mal davon abgsehen das das ein ziemlicher hickhack ist, der den stack nicht erfreuen wird(sowas allokiert man dynamisch und nicht mit so nem armseligen macro) ist er meiner meinung noch falsch


C++:
for(Zeile=0;Zeile<ZEILE;Zeile++){
    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucZeile[Spalte]=ucIn[Spalte][Zeile]; //hier kopierst du eine spalte der gerade akutelle ZEILE Zeile, imho totaler bullshit... müsste die zeile kompiert werden und nicht die spalte
    }

    //Filtern
    for(k=0;k<(ZEILENLAENGE-FILTERLAENGE);k++){ //hier wird so ne arte faltung gemacht
        iSumme=0;
        for(j=0;j<FILTERLAENGE;j++)
            iSumme=iSumme+ucZeile[k+j];
        ucZeileGefiltert[k]=iSumme/FILTERLAENGE;
    }

//Zeile auffuellen
    for(k=(ZEILENLAENGE-FILTERLAENGE);k<ZEILENLAENGE;k++){
        ucZeileGefiltert[k]=0;
    }

    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucOut[Spalte][Zeile]=ucZeileGefiltert[Spalte];
    }
}



--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 13.05.2004 um 22:35 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
13.05.2004, 22:43 Uhr
Tommi Bisic



Nunja,vielleicht mag das ja bullshit sein aber es ist die Lösung von meinem Prof,ich hätte das ehrlich gesagt nicht auf die Reihe bekommen.
Was mich interessiert ist was diese Schleifen im Weichzeichner-Effekt(der ja einen Mittelwert zwischen 2 benachbarten Pixeln berechnet...glaube ich...)
jeweils einzeln bewirken.Das mit dem ins negative wandeln ist ja einleuchtend und das mit schwarz-weiss auch,nur diese Schleifen verwirren mich total.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
13.05.2004, 23:56 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


mag ja auch sein das ich falsch liege und etwas für nen fehler halte was keiner ist..ich habe ja imho geschrieben... Ich bleibe allerdings dabei das man sowas dynamisch allokieren sollte...

Ich will mal versuchen in anderen worten zu erklären was ich meine


C++:
#define ZEILE 480    
#define SPALTE 640
//bild ist also immer 480 mal 640;

ucIn[SPALTE][ZEILE]; //also ucIn[640][480]
unsigned char ucZeile[ZEILENLAENGE]; //wird also zu ucZeile[640];

for(Zeile=0;Zeile<ZEILE;Zeile++){
    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucZeile[Spalte]=ucIn[Spalte][Zeile]; //wiso nennt der das teil uc Zeile wenn er dann ne Spalte kopiert...da fängst schon mal an.. dann wird innerhalb der funktion ucZeile nicht mehr weiter verwendet... was soll der blödsinn... ucZeile ist lokal innerhalb der funktion angeleget gibt es also nach dem durchlaufen der funktion nicht mehr... deshalb meiner meinung nach hohle kopiererei... wenns keine sein soll wüsste ich gerne mal wofür man was kopiert was man am ende nicht mehr braucht... und wiso nennt man das das zeile wenn man ne spalte kopiert?
    }


    //das hier macht irgendwie noch sinn... er addiert in der aktuellen zeile alle werte von der aktuellen zeile bis zur aktuellen zeile+Filterlänge-1 zusammen und mittelt diese dann
    for(k=0;k<(ZEILENLAENGE-FILTERLAENGE);k++){ //hier wird so ne arte faltung gemacht
        iSumme=0;
        for(j=0;j<FILTERLAENGE;j++)
            iSumme=iSumme+ucZeile[k+j];
        ucZeileGefiltert[k]=iSumme/FILTERLAENGE;
    }


//das erscheint mir auch noch sinnvoll wobei ichs nicht für geschickt halte einfach nur ne 0 reinzufeuern sondern man könnte auch hier noch mitteln nur halt bei jedem durchlauf mit entsprechend einem wert weniger... aber seis drum hier wird nun mal mit nullen aufgefüllt...
    for(k=(ZEILENLAENGE-FILTERLAENGE);k<ZEILENLAENGE;k++){
        ucZeileGefiltert[k]=0;
    }

//so hier kopiert er die gefillterte spalte in das neue bild... imho wieder blödsinn und speicherverschendung... da hätte er es ja auch gleich reinkopieren können...
    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucOut[Spalte][Zeile]=ucZeileGefiltert[Spalte];
    }



//so und hier am ende seh ich nichts von ucZeile... was sollte also die dumme kopiererei wenn die nicht verwendet wird? scheint mir mehr ein altes relikt aus nem früheren code zu sein


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 13.05.2004 um 23:59 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
14.05.2004, 13:02 Uhr
ao

(Operator)



Zitat:
Windalf postete
Ich bleibe allerdings dabei das man sowas dynamisch allokieren sollte...

Wenn das ne Musterlösung oder so sein soll, dann ist es nicht verkehrt, wenn sie sich auf das Wesentliche konzentriert und nicht noch nebenher mit dynamischem Speicher rumwerkelt.
Das sind zwei Arrays mit je 300 KB, die passen wohl noch auf den Stack, und wenn es Probleme gibt, kann man das ja immer noch ändern.

Zitat:

C++:
for(Zeile=0;Zeile<ZEILE;Zeile++){
    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucZeile[Spalte]=ucIn[Spalte][Zeile]; //wiso nennt der das teil uc Zeile wenn er dann ne Spalte kopiert... */


Hier hast du wohl recht, und es sollte besser ucSpalte heißen. Oder ich habs auch falsch verstanden.

Zitat:

C++:
/* dann wird innerhalb der funktion ucZeile nicht mehr weiter verwendet... was soll der blödsinn... */


Das stimmt nicht; schau mal hier:

Zitat:

C++:
    for(k=0;k<(ZEILENLAENGE-FILTERLAENGE);k++){ //hier wird so ne arte faltung gemacht
        iSumme=0;
        for(j=0;j<FILTERLAENGE;j++)
            iSumme=iSumme+[b]ucZeile[k+j][/b];
        ucZeileGefiltert[k]=iSumme/FILTERLAENGE;
    }

//so hier kopiert er die gefillterte spalte in das neue bild... imho wieder blödsinn und speicherverschendung... da hätte er es ja auch gleich reinkopieren können...
    for(Spalte=0;Spalte<SPALTE;Spalte++){
        ucOut[Spalte][Zeile]=ucZeileGefiltert[Spalte];
    }



Hätte er, aber möglicherweise meint er, dass es mit einem Zwischenergebnis leichter zu lesen ist.
Außerdem handelt es sich nur um ein Zeilenobjekt (d.h. 640 Bytes), und wenn man schon 2 x 300 K Bildpuffer benutzt, kann man die paar Bytes wohl auch noch verschmerzen. Und der Speicher wird nicht verschwendet, sondern nach Benutzung brav zurückgegeben, ist ja schließlich eine Stackvariable.


Zitat:

C++:
//so und hier am ende seh ich nichts von ucZeile... was sollte also die dumme kopiererei wenn die nicht verwendet wird? scheint mir mehr ein altes relikt aus nem früheren code zu sein



Beruhig dich, Windalf, bald ist Wochenende ;-)

Dieser Post wurde am 14.05.2004 um 13:03 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
14.05.2004, 16:31 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@ao
tatsache hab ich übersehen... die kopierei macht dann aber auch in diesem fall keinen sinn man kann ja auch in diesem falle direkt drauf zugreifen...



Zitat:

Und der Speicher wird nicht verschwendet, sondern nach Benutzung brav zurückgegeben, ist ja schließlich eine Stackvariable


mit verschenden meinte ich das der stack kurzfristig zugemüllt von dem man ja auch nicht weiss wieviel speicher der überhaupt verkraftet...



Zitat:

Beruhig dich, Windalf, bald ist Wochenende ;-)


Ich bin wie immer ganz entspannt und gut gelaunt...
Mach ich so oft nen anderen Eindruck?
Auf den Code hab ich nur "geschimpft" weil ich den für die Lehre ungeeignet finde...(Es sei denn er soll als schlechtes beispiel dienen ), aber meine Laune tangiert das eigentlich nicht... Ich muss mich ja nicht mit rumärgern

ärgerlich bin ich nur wenn mir mal wieder ein vertreter vor der Tür was anzuderehen versucht und nicht akzeptieren will das ich den Krempel nicht kaufen will....
Schönes Wochenende wünsch ich euch auch allen...
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 14.05.2004 um 16:32 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
15.05.2004, 18:47 Uhr
Tommi Bisic



Also gut.Erst mal danke für die Antworten,aber könntet ihr euch vielleicht ein wenig verständlicher ausdrücken so dass ich(2 Semester) es auch verstehe.Stack kam glaube ich mal in einer meiner Assembler-Vorlesungen dran und ist eine Art Zwischenspeicher auf den man was "pushen" und "poppen" kann soweit ich weiss(korrigiert mich bitte wenn ich falsch liege).Könntet ihr mir bitte erklären wie das mit C++ funktioniert?Speziell an dem Bsp?Danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
16.05.2004, 13:42 Uhr
Tommi Bisic



Hallo?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
16.05.2004, 14:21 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


naja dein rechner benutzt halt einen teil des speichers als stack... wen du eine funktion aufrufst werden dort die variablen deiner funktion raufgepackt...(push) und wenn die funktion zu ende ist werden sie halt wieder runtergenommen (pop)... wenn du da riesige statische felder raufpackst.. kanns dir passieren das der stack überläuft... er ist halt eigentlich nicht dafür vorgesehen mega grosse datenmengen aufzunehmen...

wenn man mal viel speicher brauch allokiert man den mit new auf dem heap...

kannst dich z.b. genauer hier informieren
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: