Thomas Kramer

IT-COW | All posts tagged 'C-Aufgaben'

C-Aufgaben: Weitere Bildbearbeitungsfunktionen

By Administrator at April 14, 2011 20:55
Filed Under: C(++), Programmierung allgemein, Studium

In diesem Programm werden einfache Bearbeitungsfunktionen auf ein Bild angewandt:

 

  • Invertieren
  • Glätten
  • Schwellwert
  • Kantenbildung

 

Das Programm funktioniert nur mit graustufigen PGM-Bildern. Eine genauere Beschreibung spare ich mir, denn die Algorithmen sind eigentlich ziemlich einfach. Im Internet lässt sich übrigens ohne weiteres eine alternative Variante aus dem Jahr 2006 finden.  

 

Das Syntax-Highlighting von BlogEngine.NET korrekt zu benutzen ist gar nicht so einfach, denn nach einem Zeilenkommentar // will er (ohne folgende Leerzeile) auch die nachfolgenden Zeilen als Kommentar kennzeichnen, was aber eigentlich falsch ist. Ich denke ich werde künftig einfach immer /* */ verwenden, das funktioniert besser.

 

Leider konnte ich die exit()-Befehle wieder nicht überreden, genau untereinander zu erscheinen.

 

/*
* =====================================================================================
*
*       Filename:  
*
*    Description:  Bildbearbeitungsfunktionen
*
*        Version:
*        Created:
*       Revision:  none
*       Compiler:  gcc
*
*         Author:  Thomas Kramer
*        Company:
*
* =====================================================================================
*/

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <assert.h>
#include <string.h>

using namespace std;
#define N1 1000                                        /* maximale Bildhöhe   */
#define N2 1000                                        /* maximale Bildbreite */


#define Datei_nicht_vorhanden 1
#define falscher_Bildtyp 2
#define sonstige_Fehler 3
typedef unsigned char Pixel;                         
typedef struct pgm_bild Pgm_Bild;                  
struct pgm_bild
{
    /* Bildtyp */
    char magic[10];
    /* Zeilenzahl */
    int  nx;
    /* Spaltenzahl */
    int  ny;
    /* max. Grauwert */
    int  graumax;
    /* Bildmatrix */
    Pixel bild[N1][N2];
};

void invertieren   ( Pgm_Bild *bild1, Pgm_Bild *bild2 );
void glaetten      ( Pgm_Bild *bild1, Pgm_Bild *bild2 );
void schwellwert   ( Pgm_Bild *bild1, Pgm_Bild *bild2, Pixel schwellwert );
void kantenbildung ( Pgm_Bild *bild1, Pgm_Bild *bild2 );

int bild_lesen     ( char *dateiname, Pgm_Bild *bild );
int bild_schreiben ( char *dateiname, Pgm_Bild *bild );


int main()
{
   Pgm_Bild Bild_Eingabe;
   Pgm_Bild Bild_Ausgabe;
   int z=0;
   int s=0;
   char c;

   char *datei;
   datei="C:\\Pfad\\bild.pgm";
   bild_lesen(datei, &Bild_Eingabe);

   Bild_Ausgabe=Bild_Eingabe;

   /*-----------------------------------------------------------------------------
    *  Menü ausgeben, Bildbearbeitung
    *-----------------------------------------------------------------------------*/

   printf("\nMenue\n\n");
   printf("g Glaettung\n");
   printf("i Invertierung\n");
   printf("k Kantenbildung\n");
   printf("s Schwellwert\n");
   printf("e Ende\n\n");
   printf("Auswahl : ");

   do
   {
      c = getchar();
   }
   while ((strchr("gikse", c)==0));

   /*-----------------------------------------------------------------------------
    *  Bildbearbeitung ausführen
    *-----------------------------------------------------------------------------*/

   switch (c)
   {
     case 'g':
               glaetten(&Bild_Eingabe,&Bild_Ausgabe);
               break;
     case 'i':
               invertieren(&Bild_Eingabe,&Bild_Ausgabe);
               break;
     case 'k':
               kantenbildung(&Bild_Eingabe,&Bild_Ausgabe);
               break;
     case 's':
               schwellwert(&Bild_Eingabe,&Bild_Ausgabe,150);
               break;
     case 'e':
               printf("Beendigung.");
               exit(0);
               break;
     default:
               break;
   }


   /*-----------------------------------------------------------------------------
    *  Datei schreiben
    *-----------------------------------------------------------------------------*/

   datei="C:\\Pfad\\bild.out.pgm";
   bild_schreiben(datei,&Bild_Ausgabe);

   /*-----------------------------------------------------------------------------
    *  Ausgabe-Bilddatei öffnen
    *-----------------------------------------------------------------------------*/

   system(datei);

   return 0;
}

int bild_lesen     ( char *dateiname, Pgm_Bild *bild )
{
    FILE *infile;
    char typ[2];
    int b=0;
    int h=0;
    int graumax=0;
    int z=0;
    int s=0;
    int temp=0;

    /*-----------------------------------------------------------------------------
     *  Datei öffnen und Dateityp verifizieren
     *-----------------------------------------------------------------------------*/

    infile = fopen(dateiname, "r");
    if (infile == NULL) {
      printf("\nDatei konnte nicht geöffnet werden");
      exit(Datei_nicht_vorhanden);                                                                                               
    }

    typ[0]=fgetc(infile);
    typ[1]=fgetc(infile);

    if ((typ[0]!='P') || (typ[1]!='2'))
    {
        printf("\nCodierung des Dateityps falsch!\n");
        fclose(infile);
        exit(falscher_Bildtyp);
    }

    /*-----------------------------------------------------------------------------
     *  Datei einlesen
     *-----------------------------------------------------------------------------*/

    if (fscanf(infile, "%i %i %i", &b, &h, &graumax)==3)
    {
      /* Zeilen=N1, Spalten=N2 */
      if ((b>N2) || (h>N1))
      {
         printf("\nBild zum Einlesen zu groß!\n");
         fclose(infile);
         exit(sonstige_Fehler);
      }
         else if ((b<=1) || (h<=1))
      {
         printf("\nBildgröße falsch!\n");
         fclose(infile);
         exit(sonstige_Fehler);
      }

      for (z=0;z<h;z+=1)
      {
        for (s=0;s<b;s+=1)
        {
            if (fscanf(infile, " %i ", &temp)==1)
           {
             if ((temp>=0) && (temp<=graumax))
             {
               bild->bild[z][s]=temp;
             } else {
               printf("\nBild falsch codiert!\n");
               fclose(infile);
               exit(sonstige_Fehler);
             }
           }
        }
      }
        fclose(infile);

    /*-----------------------------------------------------------------------------
     *  weitere Daten der Datei übernehmen
     *-----------------------------------------------------------------------------*/

     bild->magic[0]=typ[0];
     bild->magic[1]=typ[1];
     bild->nx=h;
     bild->ny=b;
     bild->graumax=graumax;
    }
}

int bild_schreiben ( char *dateiname, Pgm_Bild *bild )
{
  FILE *outfile;
  int z=0;
  int s=0;

  /*-----------------------------------------------------------------------------
   * in neue Datei ausgeben, aus dem neuen Array
   *-----------------------------------------------------------------------------*/

  outfile = fopen(dateiname, "w");
  if (outfile == NULL) {
    printf("\nDatei konnte nicht erstellt werden");
      exit(sonstige_Fehler);                                                                                                
  }

  fprintf(outfile, "%c%c\n", bild->magic[0], bild->magic[1]);
  fprintf(outfile, "%i %i\n", bild->ny, bild->nx);
  fprintf(outfile, "%i\n", bild->graumax);

  for (z=0;z<bild->nx;z+=1)
  {
    for (s=0;s<bild->ny;s+=1)
    {
      fprintf(outfile," %3i", bild->bild[z][s]);
     }
     fprintf(outfile,"\n");
  }

  fclose(outfile);
}

void invertieren   ( Pgm_Bild *bild1, Pgm_Bild *bild2 )
{
  int z=0;
  int s=0;

  for (z=0;z<bild1->nx;z+=1)
  {
    for (s=0;s<bild1->ny;s+=1)
    {
      bild2->bild[z][s]=(bild1->graumax)-(bild1->bild[z][s]);
    }
  }
}

void glaetten      ( Pgm_Bild *bild1, Pgm_Bild *bild2 )
{
  int z=0;
  int s=0;

  for (z=0;z<bild1->nx;z+=1)
  {
    for (s=0;s<bild1->ny;s+=1)
    {
      bild2->bild[z][s]=(((bild1->bild[z-1][s-1]+bild1->bild[z-1][s]+bild1->bild[z-1][s+1])+
                          (bild1->bild[z][s-1]+bild1->bild[z][s]+bild1->bild[z][s+1])+
                          (bild1->bild[z+1][s-1]+bild1->bild[z+1][s]+bild1->bild[z+1][s+1]))
                          /9);
    }
  }
}

void schwellwert   ( Pgm_Bild *bild1, Pgm_Bild *bild2, Pixel schwellwert )
{
  int z=0;
  int s=0;

  for (z=0;z<bild1->nx;z+=1)
  {
    for (s=0;s<bild1->ny;s+=1)
    {
       if (bild1->bild[z][s]<schwellwert)
       {
         bild2->bild[z][s]=0;
       } else {
         bild2->bild[z][s]=bild1->graumax;
       }
    }
  }
}

void kantenbildung ( Pgm_Bild *bild1, Pgm_Bild *bild2 )
{
  /* Die Betragsfunktion liefert den Wert des übergebenen Wertes, wenn er positiv ist, und multipliziert ihn mit -1, wenn er negativ ist.
  Damit liefert die Funktion also immer einen positiven Wert. Es gibt eine Funktion namens abs() für ganzzahlige Werte aus der Bibliothek
  stdlib und eine Funktion fabs() für Fließkommazahlen aus der math-Bibliothek. */

  int z=0;
  int s=0;

  for (z=0;z<bild1->nx;z+=1)
  {
    for (s=0;s<bild1->ny;s+=1)
    {
      if ((z==0 || z==((bild1->nx)-1)) && (s==0 || s==(bild1->ny-1)))
      {
        // Rand soll ja schwarz gefärbt werden.
        bild2->bild[z][s]=0;
      } else {
        // geteilt durch 9 oder 9.0?
        bild2->bild[z][s]=abs(((bild1->bild[z-1][s]*-1)+
                    (bild1->bild[z][s-1]*-1+bild1->bild[z][s]*4+bild1->bild[z][s+1]*-1)+
                    (bild1->bild[z+1][s]*-1))/4);
         }
    }
  }
}

 

Tag-Wolke

Monats-Liste