summary refs log tree commit diff
path: root/pnmnorm.html
blob: 17af3f4c4138cea96ac8b1ea41438bd02c31b45e (plain) (blame)
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD><TITLE>Pnmnorm User Manual</TITLE></HEAD>
<BODY>
<H1>pnmnorm</H1>
Updated: 19 December 2014
<BR>
<A HREF="#index">Table Of Contents</A>

<H2>NAME</H2>

pnmnorm - normalize the contrast in a Netpbm image

<H2 id="synopsis">SYNOPSIS</H2>

<B>pnmnorm</B>

[<B>-bpercent=</B><I>percent</I> | <B>-bvalue=</B><I>N</I> | <b>-bsingle</b>]

[<B>-wpercent=</B><I>percent</I> | <B>-wvalue=</B><I>N</I> | <b>-wsingle</b>]

[<b>-midvalue=</b><i>N</i>]

[<b>-middle=N</b>]

[<b>-maxexpand=</b><i>percent</i>]

[<B>-keephues</B>]

[<B>-luminosity</B> | <B>-colorvalue</B> | <B>-saturation</B>]

[<I>ppmfile</I>]


<P>All options can be abbreviated to their shortest unique prefix.
You may use two hyphens instead of one to designate an option.  You
may use either white space or an equals sign between an option name
and its value.

<H2 id="description">DESCRIPTION</H2>

<p>This program is part of <a href="index.html">Netpbm</a>.

<p><b>pnmnorm</b> reads a PNM image (PBM, PGM, or PPM).  It normalizes the
contrast by forcing the brightest pixels to white, the darkest pixels to
black, and spreading out the ones in between.  It produces the same kind of
file as output.  This is pretty useless for a PBM image.

<p>The program offers two ways of spreading out the pixels in between the
darkest and brightest: linear and quadratic.  In the quadratic case, you
specify some in between brightness and specify what brightness that should
become in the output.  With those three constraints: the brightness that
becomes black, the brightness that becomes white, and the brightness that
becomes that middle value, <b>pnmnorm</b> computes a quadratic equation that
maps all the other brightnesses from input values to output values.

<P>The program first determines a mapping of old brightness to new
brightness.  For each possible brightness of a pixel, the program
determines a corresponding brightness for the output image.

<P>Then for each pixel in the image, the program computes a color which has
the desired output brightness and puts that in the output.  With a color
image, it is not always possible to compute such a color and retain any
semblance of the original hue, so the brightest and dimmest pixels may only
approximate the desired brightness.

<p>For a PPM image, you have a choice of three ways to define brightness:
<ol>
<li>luminosity
<li>color value
<li>saturation
</ol>

In the case of saturation, "brightness" is pretty much a
misnomer, but you can use the brightness analogy to see what it does.
In the analogy, bright means saturated and dark means unsaturated.

<P>Note that all of these are different from separately normalizing
the individual color components.

<p>An alternative way to spread out the brightnesses in an image is
<b>pnmhisteq</b>.  <b>pnmhisteq</b> stretches the brightest pixels to
white and the darkest pixels to black, but rather than linearly
adjusting the ones in between, it adjusts them so that there are an
equal number of pixels of each brightness throughout the range.  This
gives you more contrast than <b>pnmnorm</b> does, but can considerably
change the picture in exchange.


<H2 id="options">OPTIONS</H2>

<P>By default, the darkest 2 percent of all pixels are mapped to
black, and the brightest 1 percent are mapped to white.  You can
override this behavior and specify either a different percentage, or
specific brightness values to map to black and to white, or just have
the single greatest brightness map to white and the least brightness map
to black.

<p>To specify a percentage, use the <B>-bpercent</B> and
<B>-wpercent</B> options, or you can specify the exact pixel values to
be mapped by using the <B>-bvalue</B> and <B>-wvalue</B> options.
You can get appropriate numbers for the options from
<b>ppmhist</b>.  If you just want to enhance the contrast, then
choose values at elbows in the histogram; e.g. if value 29 represents
3% of the image but value 30 represents 20%, choose 30 for
<I>bvalue</I>.  If you want to brighten the image, then set
<I>bvalue</I> to 0 and just fiddle with <I>wvalue</I>; similarly, to
darken the image, set <I>wvalue</I> to maxval and play with
<I>bvalue</I>.

<p>If you specify both <b>-bvalue</b> and <b>-bpercent</b>, <b>pnmnorm</b>
uses the one that produces the least change.  The same goes for
<b>-wvalue</b> and <b>-wpercent</b>.  (In Netpbm 10.26 (January 2005),
the <b>-bvalue</b>/<b>-wvalue</b> takes precedence, and before that,
it's a syntax error to specify both).

<p>If you want to maximize the change instead of minimizing it, just
cascade two runs of <b>pnmnorm</b>, specifying values for the first
and percentages for the second.

<p><b>-bpercent</b> and <b>-wpercent</b> values are floating point
decimal.  Zero is valid and is the same as <b>-bvalue=0</b> or
<b>-wvalue=</b><i>maxval</i>, respectively.

<p>Because there are whole numbers of pixels at each brightness,
<b>pnmnorm</b> obviously can't guarantee the exact percentage, so it
arranges that <em>at least</em> the percentage of pixels you specify
get remapped as promised.

<p>It is possible for your <b>-bpercent</b> or <b>-wpercent</b>
to overlap your <b>-wvalue</b> or <b>-bvalue</b>, respectively.  For
example, you say <b>-bpercent=20</b> and <b>-wvalue=100</b> for an
image in which only 10 percent of the pixels are darker than 100.
In that case, <b>pnmnorm</b> adjusts the percentile value as
required.  In the example, it uses 99 as the black value (like
<b>-bvalue=99</b>).

<P>It is also possible for your <b>-bpercent</b> and <b>-wpercent</b>
options to select the same brightness value for the stretch-to-white
and stretch-to-black value because of the fact that <b>pnmnorm</b>
can't subdivide a histogram cell.  E.g. if an image is all brightness
100, then no matter what <b>-bpercent</b> and <b>-wpercent</b>
values you choose, it's the same as saying <b>-bvalue=100 -wvalue=100</b>.
In that case, <b>pnmnorm</b> changes one of the values by 1 to make it
legal.  In the example, <b>pnmnorm</b> would either make the black
value 99 or the white value 101.

<p>Before Netpbm 10.43 (June 2008), <b>pnmnorm</b> fails if the
<b>-wpercent</b> and/or <b>-bpercent</b> values specify an overlap.

<p>The stretch points are further constrained by the <b>-maxexpand</b>
option.  Sometimes, too much contrast is a bad thing.  If your
intensities are all concentrated in the middle, <b>-bpercent=2</b> and
<b>-wpercent=1</b> might mean that an intensity of 60 gets stretched
up to 100 and intensity of 20 gets stretched down to zero, for a
range expansion of 150% (from a range of 40 to a range of 100).  That
much stretching means two adjacent pixels that used to differ in
intensity by 4 units now differ by 10, and that might be unsightly.

<p>To specify that the single least brightness in the image should stretch to
black in the output, specify <b>-bsingle</b>.  To specify that the single
greatest brightness in the image should stretch to white in the output,
specify <b>-wsingle</b>.  <b>-bsingle</b> and <b>-wsingle</b> were new in
Netpbm 10.69 (December 2014).

<p>So that you can put a limit on the amount of expansion without
having to examine the image first, there is the <b>-maxexpand</b>
option.  It specifies the maximum expansion you will tolerate, as an
additional percentage.  In the example above, you could say
<b>-maxexpand=50</b> to say you want the range to expand by at most
50%, regardless of your other options.  <b>pnmnorm</b> figures out
what intensity to stretch to full intensity and what intensity to
stretch to zero intensity as described above, and then raises the
former and lowers the latter as needed to limit the expansion to the
amount you specified.

<p>When <b>pnmnorm</b> limits the expansion because of <b>-maxexpand</b>,
it tells you about it with a message like this:
<pre>
<tt>
    limiting expansion of 150% to 50%
</tt>
</pre>

<p>In any case, <b>pnmnorm</b> tells you exactly what expansion it's
doing, like this:

<pre>
<tt>
    remapping 25..75 to 0..100
</tt>
</pre>

<p>Before Netpbm 10.26 (December 2004), it was not valid to specify both
<b>-bvalue</b> and <b>-bpercent</b> or <b>-wvalue</b> and <b>-wpercent</b>.

<p><b>-maxexpand</b> was new in Netpbm 10.32 (February 2006).

<P>The <B>-keephues</B> option says to keep each pixel the same hue as
it is in the input; just adjust its brightness.  You normally want this;
the only reason it is not the default behavior is backward compatibility
with a design mistake.

<p>By default, <B>pnmnorm</B> normalizes contrast in each component
independently (except that the meaning of the <B>-wpercent</B> and
<B>-bpercent</B> options are based on the overall brightnesses of the
colors, not each component taken separately).  So if you have a color
which is intensely red but dimly green, <B>pnmnorm</B> would make the
red more intense and the green less intense, so you end up with a
different hue than you started with.

<p>When you specify <b>-midvalue=</b><i>N</i>, <b>pnmnorm</b> uses a quadratic
function to map old brightnesses to new ones, making sure that an old
brightness of <i>N</i> becomes 50% bright in the output.  You can override
that 50% default with <b>-middle</b>.  The value of <b>-middle</b> is a
floating point number in the range 0 through 1 with 0 being full darkness and
1 full brightness.  If your <b>-midvalue</b> and <b>-middle</b> indicate an
ambiguous or impossible quadratic function (e.g. <b>-midvalue</b> is the same
as <b>-bvalue</b>, so an infinite number of quadratic functions
fit), <b>pnmnorm</b> just ignores your <b>-midvalue</b> and maps linearly.

<b>-midvalue</b> and <b>-middle</b> were new in Netpbm 10.57 (December 2011).

<P>If you specify <B>-keephues</B>, <B>pnmnorm</B> would likely leave
this pixel alone, since its overall brightness is medium.

<P><B>-keephues</B> can cause clipping, because a certain color may be
below a target intensity while one of its components is saturated.
Where that's the case, <B>pnmnorm</B> uses the maximum representable
intensity for the saturated component and the pixel ends up with less
overall intensity, and a different hue, than it is supposed to have.

<P>This option is meaningless on grayscale images.

<p>When you <em>don't</em> specify <b>-keephues</b>, the
<b>-luminosity</b>, <b>-colorvalue</b>, and <b>-saturation</b> options
affect the transfer function (which is the same for all three RGB
components), but are meaningless when it comes to applying the
transfer function (since it is applied to each individual RGB
component).

<P>Before Netpbm 9.25 (March 2002), there was no <B>-keephues</B> option.

<p><b>-luminosity</b>, <b>-colorvalue</b>, and <b>-saturation</b> determine
what property of the pixels <b>pnmnorm</b> normalizes.  I.e., what kind of
brightness.  You cannot specify more than one of these.

<P>The <B>-luminosity</B> option says to use the luminosity (i.e. the
"Y" in the YUV or YCbCr color space) as the pixel's brightness.  The
luminosity is a measure of how bright a human eye would find the color,
taking into account the fact that the human eye is more sensitive to some
RGB components than others.

<p>This option is default.

<P>This option is meaningless on grayscale images.

<P>Before Netpbm 10.28 (August 2005), there was no <B>-luminosity</B> option,
but its meaning was still the default.

<P>Before Netpbm 10.28 (August 2005), there was no <B>-colorvalue</B> option.

<P>The <B>-colorvalue</B> option says to use the color value (i.e. the
"V" in the HSV color space) as the pixel's brightness.  The
color value is the gamma-adjusted intensity of the most intense RGB
component.

<P>This option is meaningless on grayscale images.

<P>Before Netpbm 10.28 (August 2005), there was no <B>-colorvalue</B> option.

<p>The <b>-saturation</b> option says to use the saturation (i.e. the
"S" in the HSV color space) as the pixel's brightness.  The
saturation is the ratio of the intensity of the most intense RGB
component to the difference between the intensities of the most and least
intense RGB component (all intensities gamma-adjusted).

<p>In this case, "brightness" is more of a metaphor than anything.
"bright" means saturated and "dark" means unsaturated.

<p>This option is meaningless on grayscale images.

<P>Before Netpbm 10.28 (August 2005), there was no <B>-colorvalue</B> option.



<H2 id="seealso">SEE ALSO</H2>

<B><A HREF="pnmhisteq.html">pnmhisteq</A></B>,
<B><A HREF="pamlevele.html">pamlevels</A></B>,
<B><A HREF="ppmhist.html">ppmhist</A></B>,
<B><A HREF="pgmhist.html">pgmhist</A></B>,
<B><A HREF="pambrighten.html">pambrighten</A></B>,
<B><A HREF="ppmdim.html">ppmdim</A></B>,
<B><A HREF="pnmgamma.html">pnmgamma</A></B>,
<B><A HREF="pnm.html">pnm</A></B>

<HR>
<H2 id="index">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="#seealso">SEE ALSO</A>
</UL>
</BODY>
</HTML>