/* * ===================================================================================== * * Filename: 1.01.bildverarbeitung3.cc * * Description: * * Version: 1.0 * Created: 20.03.2014 12:24:17 * Revision: none * Compiler: gcc * * Author: Stefan Suhren (SSuhren), suhren.stefan@fh-swf.de * Organization: FH Südwestfalen, Iserlohn * * ===================================================================================== */ #include #include #include #include #include using namespace std; //----------------------------------------------------------------------------- // Type Defs //----------------------------------------------------------------------------- typedef unsigned char Pixel; // ##### DATA TYPES - LOCAL TO THIS SOURCE FILE ############################## struct pgm_bild { char magic[2]; // Bildtyp int nx; // Zeilenzahl int ny; // Spaltenzahl int graumax; // max. Grauwert Pixel **bild; // Bildmatrix }; // ---------- end of struct pgm_bild ---------- // ##### LOCAL PROTOTYPES ###################################################### void bild_lesen( pgm_bild *bild, char *ifs_file_name ); void bild_schreiben( pgm_bild *bild, char *ofs_file_name ); void delete_pixel_matrix( Pixel **m ); Pixel** new_pixel_matrix( size_t rows, size_t columns ); void glaetten( pgm_bild *bild1, pgm_bild *bild2 ); void invertieren( pgm_bild *bild1, pgm_bild *bild2 ); void kantenbildung( pgm_bild *bild1, pgm_bild *bild2 ); void kopiere_bildkopf( pgm_bild *bild1, pgm_bild *bild2 ); void schwellwert( pgm_bild *bild1, pgm_bild *bild2, Pixel schwellwert ); // === FUNCTION ====================================================================== // Name: main // Description: Main loop for user interactions // Exitcodes: 0 success // 1 file open failure // 2 type missmatch // 3 header corrupted // 4 image to narrow // 5 image to low // 6 pixel read error // 7 pixel outside of interval // ===================================================================================== int main( int argc, char *argv[] ){ pgm_bild pic1; pgm_bild pic2; char menu = 'e'; // user input for conversion char ifs_file_name[] = "dreifach.pgm"; // input file name char ofs_file_name[] = "dreifach.out.pgm"; // output file name bild_lesen(&pic1, ifs_file_name); pic2.bild = new_pixel_matrix(1,1); do{ // repeates till user presses e cout << "c Kopieren\ng Glätten\ni Invertieren\nk Kantenbildung\ns Schwellwert\ne ENDE\n?"; cin >> menu; if(menu != 'e'){ switch (menu){ // change output case 'g': glaetten(&pic1, &pic2); break; case 'i': invertieren(&pic1, &pic2); break; case 'k': kantenbildung(&pic1, &pic2); break; case 's': schwellwert(&pic1, &pic2, 150); break; case 'c': kopiere_bildkopf(&pic1, &pic2); for(int i = 0; i < pic2.nx; i++){ // height for(int j = 0; j < pic2.ny; j++){ // width pic2.bild[i][j] = pic1.bild[i][j]; } } break; } bild_schreiben(&pic2, ofs_file_name); } }while(menu != 'e'); return EXIT_SUCCESS; } // ---------- end of function main ---------- // === FUNCTION ====================================================================== // Name: bild_lesen // Description: Reads image from the file ifs_file_name // ===================================================================================== void bild_lesen( pgm_bild *bild, char *ifs_file_name ){ int temp = 0; // reads the vales from input file string cod; // coding string at the beginning // Open file for manipulation ifstream ifs; // create ifstream object ifs.open ( ifs_file_name ); // open ifstream if (!ifs) { cerr << "\nERROR : failed to open input file " << ifs_file_name << endl; exit (EXIT_FAILURE); } getline(ifs, cod); // reads hole line if( cod != "P2"){ // type must match ifs.close(); // release file handler cerr << "File type wrong."; exit(2); } else{ bild->magic[0] = cod[0]; bild->magic[1] = cod[1]; } if(!(ifs >> bild->ny)){ // Header corrupted (width) ifs.close(); cerr << "Header corrupted."; exit(3); } if(!(ifs >> bild->nx)){ // Header corrupted (height) ifs.close(); cerr << "Header corrupted."; exit(3); } if(!(ifs >> bild->graumax)){ // Header corrupted ifs.close(); cerr << "Header corrupted."; exit(3); } if( bild->ny <= 0 ){ // image to narrow ifs.close(); // release file handler cerr << "Image is to narrow."; exit(4); } if( bild->nx <= 0 ){ // image to low ifs.close(); // release file handler cerr << "Image is to low."; exit(5); } // Create a new pixel matrix for the image bild->bild = new_pixel_matrix(bild->nx, bild->ny); cout << "File type: " << bild->magic << endl // printing for debug perposes << "Width: " << bild->ny << endl << "Height: " << bild->nx << endl << "maxGrey: " << bild->graumax << endl; for(int i = 0; i < bild->nx; i++){ // Height for(int j = 0; j < bild->ny; j++){ // Width if(ifs >> temp){ // to prevent char by char reading if(temp >= 0 && temp <= bild->graumax){ bild->bild[i][j] = temp; // reading input file } else{ cerr << "Pixel out of interval"; ifs.close(); exit(7); } } else{ cerr << "Pixel read error" << endl; ifs.close(); exit(6); } } } ifs.close (); // close ifstream } // === FUNCTION ====================================================================== // Name: bild_schreiben // Description: Writes image to file ofs_file_name // ===================================================================================== void bild_schreiben( pgm_bild *bild, char *ofs_file_name ){ ofstream ofs; // create ofstream object ofs.open ( ofs_file_name ); // open ofstream if (!ofs) { cerr << "\nERROR : failed to open output file " << ofs_file_name << endl; exit (EXIT_FAILURE); } ofs << bild->magic << endl // writing header << bild->ny << " " << bild->nx << endl << bild->graumax << endl; for(int i = 0; i < bild->nx; i++){ for(int j = 0; j < bild->ny; j++){ ofs << (int) bild->bild[i][j] << ' '; // and writing changed image (don't forget the ' ') } ofs << endl; } ofs.close (); // close ofstream } void delete_pixel_matrix( Pixel **m ){ delete[] *m; // delete data pointer delete[] m; // delete pointer array } // === FUNCTION ====================================================================== // Name: new_pixel_matrix // Description: Creates a new pixel matrix with a few tricks // ===================================================================================== Pixel** new_pixel_matrix( size_t rows, size_t columns ){ size_t i; Pixel **m; m = new Pixel* [rows]; // allocate pointer array *m = new Pixel [rows*columns]; // allocate data array for( i = 1; iny; i++){ // width bild2->bild[0][i] = bild1->bild[0][i]; // copy first row } for(int i = 1; i < bild2->nx-1; i++){ // height bild2->bild[i][0] = bild1->bild[i][0]; // copy first pixel every row for(int j = 1; j < bild2->ny-1; j++){ // width bild2->bild[i][j] = ( bild1->bild[i-1][j-1] + bild1->bild[i-1][j] + bild1->bild[i-1][j+1] + bild1->bild[i][j-1] + bild1->bild[i][j] + bild1->bild[i][j+1] + bild1->bild[i+1][j-1] + bild1->bild[i+1][j] + bild1->bild[i+1][j+1]) / 9; } bild2->bild[i][bild2->ny-1] = bild1->bild[i][bild2->ny-1]; // copy last pixel every row } for(int i = 0; i < bild2->ny; i++){ // width bild2->bild[bild2->nx-1][i] = bild1->bild[bild2->nx-1][i]; // copy last row } } // === FUNCTION ====================================================================== // Name: invertieren // Description: bild2 is a inverted version of bild1 // ===================================================================================== void invertieren( pgm_bild *bild1, pgm_bild *bild2 ){ // Copy the neccessary values kopiere_bildkopf( bild1, bild2 ); for(int i = 0; i < bild2->nx; i++){ // height for(int j = 0; j < bild2->ny; j++){ // width bild2->bild[i][j] = bild2->graumax - bild1->bild[i][j]; // inverts value by subtracting from graumax } } } // === FUNCTION ====================================================================== // Name: kantenbildung // Description: bild2 is a edged version of bild1 // ===================================================================================== void kantenbildung( pgm_bild *bild1, pgm_bild *bild2 ){ // Copy the neccessary values kopiere_bildkopf( bild1, bild2); for(int i = 0; i < bild2->ny; i++){ // width bild2->bild[0][i] = 0; // blacken the first row } for(int i = 1; i < bild2->nx-1; i++){ // height bild2->bild[i][0] = 0; // blacken the first pixel every row for(int j = 1; j < bild2->ny-1; j++){ // width bild2->bild[i][j] = abs(( -1*bild1->bild[i-1][j] -1*bild1->bild[i][j-1] +4*bild1->bild[i][j] -1*bild1->bild[i][j+1] -1*bild1->bild[i+1][j] ) /9 ); } bild2->bild[i][bild2->ny-1] = 0; // blacken the last pixel every row } for(int i = 0; i < bild2->ny; i++){ // width bild2->bild[bild2->nx-1][i] = 0; // blacken the last row } } // === FUNCTION ====================================================================== // Name: kopiere_bildkopf // Description: Copies the Header and allocates a new matrix (frees old) // ===================================================================================== void kopiere_bildkopf( pgm_bild *bild1, pgm_bild *bild2 ){ // Copy the magic value for(unsigned int i = 0; i < (sizeof bild1->magic/sizeof bild1->magic[0]); i++){ bild2->magic[i] = bild1->magic[i]; } // Copy over the height/width bild2->nx = bild1->nx; bild2->ny = bild1->ny; // Copy graumax bild2->graumax = bild1->graumax; //Free memory delete_pixel_matrix(bild2->bild); bild2->bild = new_pixel_matrix( bild2->nx, bild2->ny); } // === FUNCTION ====================================================================== // Name: schwellwert // Description: bild2 is a polarised version of bild1 parted by schwellwert // ===================================================================================== void schwellwert( pgm_bild *bild1, pgm_bild *bild2, Pixel schwellwert){ for(int i = 0; i < bild2->nx; i++){ // height for(int j = 0; j < bild2->ny; j++){ // width if( bild1->bild[i][j] < schwellwert ){ // value < schwellwert, image black bild2->bild[i][j] = 0; } else{ // else white bild2->bild[i][j] = bild2->graumax; } } } }