PGM Format CS 474674 Prof Bebis How are
PGM Format CS 474/674 – Prof. Bebis
How are images represented?
Color images
Common image file formats • • • PGM (Portable Gray Map) PNG (Portable Network Graphics) GIF (Graphic Interchange Format) JPEG (Joint Photographic Experts Group) TIFF (Tagged Image File Format) FITS (Flexible Image Transport System)
PGM Image file format (Portable Graymap) • It adheres to the following simple model: – Header – Data (line by line, no breaks between lines).
PGM Image file format (cont. ) • Header contains at least: – A signature or “magic number” (i. e. , a short sequence of bytes for identifying the file format). – Possible comments (starting with # symbol) – The columns (M) and rows (N) of the image. – The number of quantization levels (Q) – typically on a separate line (not on the same line as shown below). MNQ
PGM Image file format (cont. ) • Data can be stored in ASCII or Raw format – ASCII takes up 3 bytes/pixel – Raw takes up 1 byte/pixel (preferred) • ASCII Raw
Related image file formats • PGM is for grayscale images (8 bits/pixel) • Closely-related formats are: – PBM (Portable Bitmap), for binary images (1 bit/pixel) – PPM (Portable Pixelmap), for color images (24 bits/pixel) •
Image Class class Image. Type { public: Image. Type(); // constructor Image. Type(Image. Type&); // copy-constructor ~Image. Type(); // destructor void get. Image. Info(int&, int&); void set. Image. Info(int, int); void get. Val(int, int&); void set. Val(int, int); // more functions to be implemented by you. . . private: int N, M, Q; //N: # rows, M: # columns int **pixel. Value; };
Input / Output Functions • C++ routine to read the header of a PGM image: Read. Image. Header. cpp • C++ routine to read a PGM image from a file: Read. Image. cpp • C++ routine to write a PGM image to a file: Write. Image. cpp
An example - Threshold. cpp void read. Image. Header(char[], int&, bool&); void read. Image(char[], Image. Type&); void write. Image(char[], Image. Type&); void main(int argc, char *argv[]) { int i, j, M, N, Q; bool type; int val, thresh; // read image header read. Image. Header(argv[1], N, M, Q, type); // allocate memory for the image array Image. Type image(N, M, Q);
Threshold. cpp (cont’d) // read image read. Image(argv[1], image); cout << "Enter threshold: "; cin >> thresh; // threshold image for(i=0; i<N; i++) for(j=0; j<M; j++) { image. get. Val(i, j, val); if(val < thresh) image. set. Val(i, j, 0); else image. set. Val(i, j, 255); } // write image write. Image(argv[2], image); }
Reading/Writing PGM images (2 D array of int) (1 D array of unsigned char) Use “write” (1 D array of unsigned char) Use “read” (2 D array of int)
Writing a PGM image to a file void write. Image(char fname[], Image. Type& image) int N, M, Q; unsigned char *char. Image; ofstream ofp; image. get. Image. Info(N, M, Q); char. Image = (unsigned char *) new unsigned char [M*N]; // convert integer values to unsigned char int val; for(i=0; i<N; i++) for(j=0; j<M; j++) image. get. Val(i, j, val); char. Image[i*M+j]=(unsigned char)val; }
Writing a PGM image. . . (cont’d) ofp. open(fname, ios: : out | ios: : binary); if (!ofp) { cout << "Can't open file: " << fname << endl; exit(1); } ofp << "P 5" << endl; ofp << M << " " << N << endl; ofp << Q << endl; ofp. write( reinterpret_cast<char *>(char. Image), (M*N)*sizeof(unsigned char)); if (ofp. fail()) { cout << "Can't write image " << fname << endl; exit(0); } ofp. close(); }
Reading a PGM image from a file void read. Image(char fname[], Image. Type& image) { int i, j; int N, M, Q; unsigned char *char. Image; char header [100], *ptr; ifstream ifp; ifp. open(fname, ios: : in | ios: : binary); if (!ifp) { cout << "Can't read image: " << fname << endl; exit(1); }
Reading a PGM image from a file // read header ifp. getline(header, 100, 'n'); if ( (header[0]!=80) || // 'P' (header[1]!=53) ) { // '5' cout << "Image " << fname << " is not PGM" << endl; exit(1); } ifp. getline(header, 100, 'n'); // skip comments while(header[0]=='#') ifp. getline(header, 100, 'n'); M=strtol(header, &ptr, 0); // read M, N N=atoi(ptr);
Reading a PGM image …. (cont’d) ifp. getline(header, 100, 'n'); // assumes Q is stored on a separate line Q=strtol(header, &ptr, 0); char. Image = (unsigned char *) new unsigned char [M*N]; ifp. read( reinterpret_cast<char *>(char. Image), (M*N)*sizeof(unsigned char)); if (ifp. fail()) { cout << "Image " << fname << " has wrong size" << endl; exit(1); } ifp. close();
Reading a PGM image…(cont’d) // Convert unsigned characters to integers int val; for(i=0; i<N; i++) for(j=0; j<M; j++) { val = (int)char. Image[i*M+j]; image. set. Val(i, j, val); } }
How do I “see” images on my computer? • Unix/Linux: xv, gimp • Windows: Photoshop Irfanview
How do I convert an image from one format to another? • Use “Save As” option
- Slides: 21