Hugin trunk 0.1
Loading...
Searching...
No Matches
PGMImage.cpp
Go to the documentation of this file.
1/* Import from Gabor API
2
3Copyright (c) 2002-3 Adriaan Tijsseling
4
5
6 All Rights Reserved
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22/*
23 Description: class for reading and storing pgm images
24 Author: Adriaan Tijsseling ( AGT )
25 Copyright: ( c ) Copyright 2002-3 Adriaan Tijsseling. All rights reserved.
26*/
27
28#include <cstring>
29#include "PGMImage.h"
30
31namespace celeste
32{
33// read PGM image from file
34int PGMImage::Read( char* file )
35{
36 int i,j;
37 char buf[256];
38 std::ifstream imgFile( file );
39
40 if ( !imgFile ) // Invalid FileName
41 {
42 std::cerr << "invalid filename: \"" << file << "\"" << std::endl;
43 exit(1);
44 return 0;
45 }
46 if ( mVerbosity ) std::cerr << "reading image from file \"" << file << "\"" << std::endl;
47
48// get file type
49 imgFile.getline( mMagicNumber, 256 );
50
51// ignore comments
52 imgFile.getline( buf, 256 );
53 while ( buf[0] == '#' ) imgFile.getline( buf, 256 );
54
55// get dimensions of image
56 mWidth = atoi( buf );
57 mHeight = atoi( strpbrk( buf, " \t" ) );
59
60// get color levels
61 if ( mMagicNumber[1] == '1' || mMagicNumber[1] == '4' )
62 {
63 mNumLevels = 1;
64 }
65 else
66 {
67 imgFile.getline( buf, 256 );
68 mNumLevels = atoi( buf );
69 }
70
71// determine number of bits given image level
72 mNumBits = (int)( log( (float)( mNumLevels+2 ) )/log( 2.0 ) );
73 if ( mVerbosity ) std::cerr << "[" << mNumBits << "-bit ";
74
75// read pixels
76 if ( mMagicNumber[1] == '5' || mMagicNumber[1] == '2' ) // GrayScale
77 {
78 // allocate pixel storage
80
81 if ( mMagicNumber[1] == '5' ) // RAWBITs
82 {
83 if ( mVerbosity ) std::cerr << "GrayScale RAWBITs PGM format]";
84 for ( i = 0; i < mHeight; i++ )
85 imgFile.read( (char *)mPixels[i], mWidth );
86 }
87 else // ASCII
88 {
89 if ( mVerbosity ) std::cerr << "GrayScale ASCII PGM format]";
90 for ( i = 0; i < mHeight; i++ )
91 {
92 for ( j = 0; j < mWidth; j++ )
93 {
94 int pix;
95 imgFile >> pix;
96 mPixels[i][j] = (unsigned char)( pix / pow( 2, (double)(mNumBits-8) ) );
97 }
98 }
99 }
100 }
101 else if ( mMagicNumber[1] == '6' || mMagicNumber[1] == '3' ) // RGB
102 {
103 // allocate rgb pixel storage
104 Allocate( kRGB );
105
106 if ( mMagicNumber[1] == '6' ) // RAWBITs
107 {
108 if ( mVerbosity ) std::cerr << "RGB RAWBITs PPM format]";
109 for ( i = 0; i < mHeight; i++ )
110 for ( j = 0; j < mWidth; j++ )
111 {
112 unsigned char rgb[3];
113 imgFile.read( (char *)rgb,3 );
114 mRGB[0][i][j] = (int)rgb[0];
115 mRGB[1][i][j] = (int)rgb[1];
116 mRGB[2][i][j] = (int)rgb[2];
117 }
118 }
119 else // ASCII
120 {
121 if ( mVerbosity ) std::cerr << "RGB ASCII PPM format]";
122 for ( i = 0; i < mHeight; i++ )
123 for ( j = 0; j < mWidth; j++ )
124 {
125 imgFile >> mRGB[0][i][j];
126 imgFile >> mRGB[1][i][j];
127 imgFile >> mRGB[2][i][j];
128 }
129 }
130 }
131 else if ( mMagicNumber[1] == '4' || mMagicNumber[1] == '1' ) // Binary
132 {
133 // allocate pixel storage
134 Allocate( kChars );
135
136 if ( mMagicNumber[1] == '4' ) // RAWBITs
137 {
138 if ( mVerbosity ) std::cerr << "Binary RAWBITs PBM format]";
139 for ( i = 0; i < mHeight; i++ )
140 for ( j = 0; j < mWidth; j += 8 )
141 {
142 char pix[1];
143 imgFile.read( pix, 1 );
144 unsigned int x = (unsigned int)pix[0];
145 for ( int k = 0; k < 8; k++ )
146 {
147 unsigned int y = x/( (unsigned int)pow( 2, (double)(7-k) ) );
148 if ( y )
149 mPixels[i][j+k] = 0;
150 else
151 mPixels[i][j+k] = 255;
152 x -= y*( (unsigned int)pow( 2, (double)(7-k) ) );
153 }
154 }
155 }
156 else
157 {
158 if ( mVerbosity ) std::cerr << "Binary ASCII PBM format]";
159 for ( i = 0; i < mHeight; i++ )
160 for ( j = 0; j < mWidth; j++ )
161 {
162 int pix;
163 imgFile >> pix;
164 if ( pix == 0 )
165 mPixels[i][j] = 0;
166 else
167 mPixels[i][j] = 255;
168 }
169 }
170 }
171
172 imgFile.close();
173
174 if ( mVerbosity )
175 {
176 std::cerr << std::endl;
177 std::cerr << "\twidth = " << mWidth << std::endl;
178 std::cerr << "\theight = " << mHeight << std::endl;
179 std::cerr << "\t#pixels = " << mNumPixels << std::endl;
180 }
181 mNumLevels = 255;
182 mNumBits = 8;
183 mMagicNumber[1] = '5';
184
185 return 1; // No error encountered....successful completion
186}
187
188
189// write PGM image to file
190void PGMImage::Write( char* file )
191{
192 std::ofstream outfile( file );
193
194 if ( mVerbosity )
195 {
196 //std::cerr << "writing " << mWidth << "x" << mHeight;
197 //std::cerr << " image to file1 \"" << file << "\"...";
198 }
199 outfile << mMagicNumber[0] << mMagicNumber[1] << std::endl; // 8-bit grayscale
200 outfile << "# grayscale image" << std::endl;
201 outfile << mWidth << " " << mHeight << std::endl;
202 outfile << mNumLevels << std::endl;
203
204 for ( int i = 0; i < mHeight; i++ )
205 outfile.write( (char *)mPixels[i], mWidth );
206
207 outfile.close();
208
209 //if ( mVerbosity ) std::cerr << "done" << std::endl;
210}
211
212
213// Write a PGM image in a file from output as is
214void PGMImage::Write( char* filename, float** output, int height, int width )
215{
216 int i, j;
217
218 // clear old data first
219 Deallocate();
220
221 // set dimensions of pixelmap and allocate memory
222 mWidth = width;
223 mHeight = height;
224 mMagicNumber[0] = 'P';
225 mMagicNumber[1] = '5';
226 mNumLevels = 255;
227 Allocate( kChars );
228
229 for( i = 0; i < mHeight; i++ )
230 for( j = 0; j < mWidth; j++ )
231 mPixels[i][j] = (unsigned char)output[i][j];
232
233 Write( filename );
234}
235
236
237// Write a color PPM image in a file
238void PGMImage::Write( char* filename, float*** pixels, int height, int width )
239{
240 std::ofstream outfile( filename );
241 unsigned char rgb[3];
242
243 // set dimensions of pixelmap and allocate memory
244 //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
245 //if ( mVerbosity ) std::cerr << " image to file2 \"" << filename << "\"...";
246 outfile << "P6" << std::endl; // 8-bit color
247 outfile << "# color image" << std::endl;
248 outfile << width << " " << height << std::endl;
249 outfile << 255 << std::endl;
250
251 for ( int i = 0; i < height; i++ )
252 for ( int j = 0; j < width; j++ )
253 {
254 rgb[0] = (unsigned char)(pixels[0][i][j]*255.0);
255 rgb[1] = (unsigned char)(pixels[1][i][j]*255.0);
256 rgb[2] = (unsigned char)(pixels[2][i][j]*255.0);
257 outfile.write( (char *)rgb, 3 );
258 }
259
260 outfile.close();
261
262 //if ( mVerbosity ) std::cerr << "done" << std::endl;
263}
264
265
266// Write a one-channel color PPM image in a file
267void PGMImage::Write( char* filename, float** pixels, int height, int width, int channel )
268{
269 std::ofstream outfile( filename );
270 unsigned char rgb[3];
271 float max, min, maxmin;
272 int i, j;
273
274 // set dimensions of pixelmap and allocate memory
275 //if ( mVerbosity ) std::cerr << "writing " << width << "x" << height;
276 //if ( mVerbosity ) std::cerr << " image to file3 \"" << filename << "\"...";
277 outfile << "P6" << std::endl; // 8-bit color
278 outfile << "# color image" << std::endl;
279 outfile << width << " " << height << std::endl;
280 outfile << 255 << std::endl;
281
282 // original float values scaled to [0,255]
283 max = min = pixels[0][0];
284 for( i = 0; i < height; i++ )
285 for( j = 0; j < width; j++ )
286 {
287 if( pixels[i][j] > max ) max = pixels[i][j];
288 if( pixels[i][j] < min ) min = pixels[i][j];
289 }
290 maxmin = max - min;
291
292 if ( channel == 0 )
293 for ( i = 0; i < height; i++ )
294 {
295 for ( j = 0; j < width; j++ )
296 {
297 rgb[0] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
298 //(unsigned char)(pixels[i][j]*255.0);
299 rgb[1] = 0;
300 rgb[2] = 0;
301 outfile.write( (char *)rgb, 3 );
302 }
303 }
304 else if ( channel == 1 )
305 for ( i = 0; i < height; i++ )
306 {
307 for ( j = 0; j < width; j++ )
308 {
309 rgb[0] = 0;
310 rgb[1] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
311 rgb[2] = 0;
312 outfile.write( (char *)rgb, 3 );
313 }
314 }
315 else
316 for ( i = 0; i < height; i++ )
317 {
318 for ( j = 0; j < width; j++ )
319 {
320 rgb[0] = 0;
321 rgb[1] = 0;
322 rgb[2] = (unsigned char)(255.0 * ( (pixels[i][j] - min ) / maxmin ));
323 outfile.write( (char *)rgb, 3 );
324 }
325 }
326
327 outfile.close();
328
329 //if ( mVerbosity ) std::cerr << "done" << std::endl;
330}
331
332
333// Write a PGM image in a file with output values scaled
334void PGMImage::WriteScaled( char* filename, float** output, int height, int width )
335{
336 float max, min, maxmin;
337 int i, j;
338
339// clear old data first
340 Deallocate();
341
342// set dimensions of pixelmap and allocate memory
343 mWidth = width;
344 mHeight = height;
345 mMagicNumber[0] = 'P';
346 mMagicNumber[1] = '5';
347 mNumLevels = 255;
348 Allocate( kChars );
349
350// original float values scaled to [0,255]
351 max = min = output[0][0];
352 for( i = 0; i < mHeight; i++ )
353 for( j = 0; j < mWidth; j++ )
354 {
355 if( output[i][j] > max ) max = output[i][j];
356 if( output[i][j] < min ) min = output[i][j];
357 }
358
359 maxmin = max - min;
360 for( i = 0; i < mHeight; i++ )
361 for( j = 0; j < mWidth; j++ )
362 mPixels[i][j] = (unsigned char)(255.0 * ( (output[i][j] - min ) / maxmin ));
363
364 Write( filename );
365}
366
367}; // namespace
unsigned char ** mPixels
Definition ImageFile.h:82
void Allocate(int dataset)
Definition ImageFile.cpp:50
void Write(char *)
Definition PGMImage.cpp:190
void WriteScaled(char *filename, float **output, int height, int width)
Definition PGMImage.cpp:334
int Read(char *)
Definition PGMImage.cpp:34
char mMagicNumber[2]
Definition PGMImage.h:55
static T min(T x, T y)
Definition svm.cpp:62
static T max(T x, T y)
Definition svm.cpp:65
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41