Hugin trunk
0.1
Loading...
Searching...
No Matches
celeste
PGMImage.cpp
Go to the documentation of this file.
1
/* Import from Gabor API
2
3
Copyright (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
31
namespace
celeste
32
{
33
// read PGM image from file
34
int
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"
) );
58
mNumPixels
=
mWidth
*
mHeight
;
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
79
Allocate
(
kChars
);
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
190
void
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
214
void
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
238
void
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
267
void
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
334
void
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
PGMImage.h
celeste::ImageFile::mPixels
unsigned char ** mPixels
Definition
ImageFile.h:82
celeste::ImageFile::mHeight
int mHeight
Definition
ImageFile.h:85
celeste::ImageFile::mWidth
int mWidth
Definition
ImageFile.h:84
celeste::ImageFile::mVerbosity
bool mVerbosity
Definition
ImageFile.h:86
celeste::ImageFile::Deallocate
void Deallocate()
Definition
ImageFile.cpp:92
celeste::ImageFile::mRGB
int *** mRGB
Definition
ImageFile.h:81
celeste::ImageFile::Allocate
void Allocate(int dataset)
Definition
ImageFile.cpp:50
celeste::PGMImage::mNumBits
int mNumBits
Definition
PGMImage.h:58
celeste::PGMImage::Write
void Write(char *)
Definition
PGMImage.cpp:190
celeste::PGMImage::mNumPixels
int mNumPixels
Definition
PGMImage.h:56
celeste::PGMImage::WriteScaled
void WriteScaled(char *filename, float **output, int height, int width)
Definition
PGMImage.cpp:334
celeste::PGMImage::Read
int Read(char *)
Definition
PGMImage.cpp:34
celeste::PGMImage::mMagicNumber
char mMagicNumber[2]
Definition
PGMImage.h:55
celeste::PGMImage::mNumLevels
int mNumLevels
Definition
PGMImage.h:57
celeste
Definition
Celeste.cpp:40
celeste::min
static T min(T x, T y)
Definition
svm.cpp:62
celeste::kRGB
@ kRGB
Definition
ImageFile.h:44
celeste::kChars
@ kChars
Definition
ImageFile.h:42
celeste::max
static T max(T x, T y)
Definition
svm.cpp:65
threshold
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
Generated on Sun Sep 13 2026 02:49:53 for Hugin trunk by
1.9.8