1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD><TITLE>Pnmhisteq User Manual</TITLE></HEAD>
<BODY>
<H1>pnmhisteq</H1>
Updated: 22 March 2015
<BR>
<A HREF="#index">Table Of Contents</A>
<H2>NAME</H2>
pnmhisteq - histogram equalize a PNM image
<H2 id="synopsis">SYNOPSIS</H2>
<B>pnmhisteq</B>
[<B>-gray</B>]
[<B>-noblack</B>]
[<B>-nowhite</B>]
[<B>-rmap</B> <I>pgmfile</I>]
[<B>-wmap</B> <I>pgmfile</I>]
[<B>-verbose</B>]
[<I>pnmfile</I>]
<H2 id="description">DESCRIPTION</H2>
<p>This program is part of <a href="index.html">Netpbm</a>.
<p><B>pnmhisteq</B> increases the contrast of a PGM or PPM image
through the technique of "histogram equalization."[1]
<p><b>pnmhisteq</b> computes a histogram of the luminosity of the
pixels in the image. It then calculates a mapping between each
luminosity and a new luminosity such that it spreads out intensity
levels around histogram peaks and compresses them at troughs. I.e.
it moves pixels around in the histogram so as to make it flat. It
applies that mapping to the input image to produce the output image.
The effect of this is that the image has equal numbers of pixels at each
possible intensity level, which means it uses the available levels of
intensity more efficiently and thereby has more visible detail.
<P>Mathematically, the luminosity mapping is this: Assume the pixels
are sorted by luminosity into <i>B</i> buckets numbered from 0 (lowest
luminosity) to <i>B</i>-1. <i>N[i]</I> is the number of pixels in
bucket <I>i</I>. <I>T</I> is the total number of pixels (sum of
<i>N[i]</i> over all <i>i</i>). <i>W</i> is the luminosity of white.
<p><b>pnmhisteq</b> replaces an input pixel whose luminosity falls into
bucket <i>j</i> with one whose luminosity is:
<pre>
j
---
\
> (N[i] / T) * W
/
---
i=0
</pre>
<p>Considering a grayscale image for simplicity, this means that
pixels in the most luminous bucket become white. Pixels in the 10th
per centile of luminosity become 10% of white.
<p><b>pnmhisteq</b> maps a single luminosity in the input to a single
luminosity in the output. That means if pixels A and B both have luminosity
.2 in the input, and pixel A has luminosity .4 in the output, pixel B also has
luminosity .4 in the output. And since the luminosities in the input are not
continuous, the luminosities in the output aren't either and <b>pnmhisteq</b>
doesn't meet the ideal of having exactly the same number of pixels of each
luminosity in the output.
<P>If you're processing a related set of images, for example frames of
an animation, it's generally best to apply the same luminosity mapping
to every frame, since otherwise you'll get distracting frame-to-frame
changes in the brightness of objects. <B>pnmhisteq</B>'s <B>-wmap</B>
option allows you to save, as a PGM image, the luminosity map it
computes from an image. The <b>-rmap</b> option causes <b>pnmisteq</b>
to use such an image as its luminosity map.
<p>So you can run <b>pnmhisteq</b> with <b>-wmap</b> on a composite
you created with <b>pnmcat</b> of the images you intend to process.
Then, you can run <b>pnmisteq</b> with <b>-rmap</b> on each of the
individual images, using the luminosity map you generated from the
composite.
<p>Use <b>pnmhistmap</b> to see the result. Run a color image through
<b>ppmtopgm</b> first so that you see a histogram of the luminosity instead of
histograms of the three color components. It should generally show a flat
histogram. But because of the quantization effects described above, you might
see high bars interleaved with low bars, with the local average being flat.
To see local averages, use the <b>-width</b> option of <b>pnmhistmap</b>.
<H2 id="options">OPTIONS</H2>
<P>You can abbreviate any option to its shortest unique prefix.
<DL COMPACT>
<DT><B>-gray</B>
<DD>When processing a color image, only gray pixels (those with identical
red, green, and blue values) are included in the histogram and
modified in the output image. This is a special purpose option
intended for images where the actual data are gray scale, with color
annotations you don't want modified. Weather satellite images that
show continent outlines in color are best processed using this option.
The option has no effect when the input is a graymap.
<DT><B>-noblack</B>
<dd>Do not include black pixels in the equalization. The black pixels in the
output are exactly the black pixels in the input and the number of black
pixels does not affect the color of any other pixels.
<p>Sometimes, black isn't as much a color as a background or annotation for
the real colors, so you want to treat it specially this way. Think of a
picture of stars, which is nearly all black, but with lots of stars of
different brightness. You want to change the brightnesses of the stars to
maximize contrast between them, but if you considered the blackness to be
significant, all the stars would end up close to full white.
<p>This option was new in Netpbm 10.70 (March 2015).
<DT><B>-nowhite</B>
<p>Same as <b>-noblack</b>, but for the white pixels.
<p>This option was new in Netpbm 10.70 (March 2015).
<DT><B>-rmap</B> <I>mapfile</I>
<DD>Process the image using the luminosity map specified by the PGM
file <I>mapfile</I>.
The PGM image, usually created by an earlier run of <B>pnmhisteq</B>
with the <B>-wmap</B> option, contains a single row with number of
columns equal to the maxval (greatest intensity value) of the image
plus one. Each pixel in the image is transformed by looking up its
luminosity in the corresponding column in the map file (column number
= luminosity) and changing it to the value given by that column.
<DT><B>-wmap</B> <I>mapfile</I>
<DD>Creates a PGM file <I>mapfile</I>, containing the luminosity map
computed from the histogram of the input image. This map file can be
read on subsequent runs of <B>pnmhisteq</B> with the <B>-rmap</B>
option, allowing a group of images to be processed with an identical
map.
<DT><B>-verbose</B>
<DD>Prints the histogram and luminosity map on Standard Error.
</DL>
<H2 id="limitations">LIMITATIONS</H2>
<p>Histogram equalization is effective for increasing the visible
detail in scientific imagery and in some continuous-tone pictures. It
is often too drastic, however, for scanned halftone images, where it
does an excellent job of making halftone artifacts apparent. You
might want to experiment with <B>pnmnorm</B> and <B>pnmgamma</B> for
more subtle contrast enhancement.
<P>The luminosity map file supplied by the <B>-rmap</B> option must
have the same maxval as the input image. This is always the case when
the map file was created by the <B>-wmap</B> option of
<B>pnmhisteq</B>. If this restriction causes a problem, simply adjust
the maxval of the map with <B>pamdepth</B> to agree with the input
image.
<P>If the input is a PBM file (on which histogram equalization is an
identity operation), the only effect of passing the file through
<B>pnmhisteq</B> will be the passage of time.
<H2 id="seealso">SEE ALSO</H2>
<B><A HREF="pnmnorm.html">pnmnorm</A></B>,
<B><A HREF="pnmcat.html">pnmcat</A></B>,
<B><A HREF="pamdepth.html">pamdepth</A></B>,
<B><A HREF="pnmgamma.html">pnmgamma</A></B>,
<B><A HREF="pnm.html">pnm</A></B>,
<DL COMPACT>
<DT>[1]
<DD>Russ, John C. The Image Processing Handbook. Boca Raton: CRC
Press, 1992. Pages 105-110.
</DL>
<HR>
<A NAME="index"> </A>
<H2>Table Of Contents</H2>
<UL>
<LI><A HREF="#synopsis">SYNOPSIS</A>
<LI><A HREF="#description">DESCRIPTION</A>
<LI><A HREF="#options">OPTIONS</A>
<LI><A HREF="#limitations">LIMITATIONS</A>
<LI><A HREF="#seealso">SEE ALSO</A>
</UL>
</BODY>
</HTML>
|