summaryrefslogtreecommitdiffstats
path: root/1.01.bildverarbeitung3.cc
diff options
context:
space:
mode:
Diffstat (limited to '1.01.bildverarbeitung3.cc')
-rw-r--r--1.01.bildverarbeitung3.cc366
1 files changed, 366 insertions, 0 deletions
diff --git a/1.01.bildverarbeitung3.cc b/1.01.bildverarbeitung3.cc
new file mode 100644
index 0000000..08c3a1c
--- /dev/null
+++ b/1.01.bildverarbeitung3.cc
@@ -0,0 +1,366 @@
+/*
+ * =====================================================================================
+ *
+ * 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 <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cmath>
+
+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; i<rows; i++){ // set pointers
+ m[i] = m[i-1] + columns;
+ }
+ return m;
+}
+
+// === FUNCTION ======================================================================
+// Name: glaetten
+// Description: bild2 is a smoothed version of bild1
+// =====================================================================================
+void glaetten( 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] = 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;
+ }
+ }
+ }
+}