240 likes | 252 Views
Learn about how images are represented in computers, different image file formats, and how to read and write image files in C++. Includes examples and functions for PGM images.
E N D
Image Representation and Read/Write CS479/679 – Prof. Bebis
Image file formats • Many image formats adhere to the following simple model: • Header • Data
Image file formats (cont.) • Header contains at least: • A signature or “magic number” (i.e., a short sequence of bytes for identifying the file format). • The width and height of the image.
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 format • A popular format 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) • ASCII or binary (raw) storage ASCII raw
Image Class - PGM • class ImageType { • public: • ImageType(); // constructor • ~ImageType(); // destructor • void getImageInfo(int&, int&, int&); • void setImageInfo(int, int, int); • void setVal(int, int, int); • void getVal(int, int, int&); • // more functions ... • private: • int N, M, Q; //N: # rows, M: # columns • int **pixelValue; • };
Input / Output Functions • C++ routine to read the header of a PGM image: ReadImageHeader.cpp • C++ routine to read a PGM image: ReadImage.cpp • C++ routine to write a PGM image: WriteImage.cpp
An example - Threshold.cpp • void readImageHeader(char[], int&, int&, int&, bool&); • void readImage(char[], ImageType&); • void writeImage(char[], ImageType&); • void main(int argc, char *argv[]) • { • int i, j, M, N, Q; • bool type; • int val, thresh; • // read image header • readImageHeader(argv[1], N, M, Q, type); • // allocate memory for the image array • ImageType image(N, M, Q);
Threshold.cpp (cont’d) • // read image • readImage(argv[1], image); cout << "Enter threshold: "; • cin >> thresh; • // threshold image for(i=0; i<N; i++) • for(j=0; j<M; j++) { • image.getVal(i, j, val); • if(val < thresh) • image.setVal(i, j, 0); • else • image.setVal(i, j, 255); • } • // write image • writeImage(argv[2], image); • }
Reading/Writing PGM images (2D array of int) (1D array of unsigned char) Use “write” (1D array of unsigned char) (2D array of int) Use “read”
Writing a PGM image to a file • void writeImage(char fname[], ImageType& image) • int N, M, Q; • unsigned char *charImage; • ofstream ofp; • image.getImageInfo(N, M, Q); • charImage = (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.getVal(i, j, val); • charImage[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 << "P5" << endl; • ofp << M << " " << N << endl; • ofp << Q << endl; • ofp.write( reinterpret_cast<char *>(charImage), (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 readImage(char fname[], ImageType& image) • { • int i, j; • int N, M, Q; • unsigned char *charImage; • 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'); // read Q • Q=strtol(header,&ptr,0); • charImage = (unsigned char *) new unsigned char [M*N]; • ifp.read( reinterpret_cast<char *>(charImage), (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)charImage[i*M+j]; • image.setVal(i, j, val); • } • }
Color Images struct RGB { RGB(int, int, int); RGB& operator=(RGB); intr, g, b; } RGB;
Image Class – PPM • class ImageType { • public: • ImageType(); // constructor • ~ImageType(); // destructor • void getImageInfo(int&, int&, int&); • void setImageInfo(int, int, int); • void setVal(int, int, RGB); • void getVal(int, int, RGB&); • // more functions ... • private: • int N, M, Q; //N: # rows, M: # columns • RGB **pixelValue; • };
ReadImage - PPM charImage = (unsigned char *) new unsigned char [3*N*M]; ifp.read( reinterpret_cast<char *>(charImage), (3*M*N)*sizeof(unsigned char)); RGB val; for(i=0; i < N; i++) for(j=0; j < 3*M; j+=3) { val.r = (int)charImage[i*3*M+j]; val.g = (int)charImage[i*3*M+j+1]; val.b = (int)charImage[i*3*M+j+2]; image.setPixelVal(i, j/3, val); }
WriteImage - PPM charImage = (unsigned char *) new unsigned char [3*M*N]; for(i=0; i<N; i++) for(j=0; j<3*M; j+=3) { image.getPixelVal(i, j/3, val); charImage[i*3*M+j]=(unsigned char)val.r; charImage[i*3*M+j+1]=(unsigned char)val.g; charImage[i*3*M+j+2]=(unsigned char)val.b; } ofp.write( reinterpret_cast<char *>(charImage), (3*M*N)*sizeof(unsigned char));
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