summary refs log tree commit diff
path: root/pnmconvol.html
blob: cce61cdec3750a04a48fd7a14cc72be60f7e5264 (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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD><TITLE>Pnmconvol User Manual</TITLE></HEAD>
<BODY>
<H1>pnmconvol</H1>
Updated: 29 June 2005
<BR>
<A HREF="#index">Table Of Contents</A>

<A NAME="lbAB">&nbsp;</A>
<H2>NAME</H2>

pnmconvol - general MxN convolution on a PNM image

<A NAME="lbAC">&nbsp;</A>
<H2>SYNOPSIS</H2>

<B>pnmconvol</B>

<I>convolution_matrix_file</I>
[-nooffset]
[<I>pnmfile</I>]

<p>Minimum unique abbreviation of option is acceptable.  You may use double
hyphens instead of single hyphen to denote options.  You may use white
space in place of the equals sign to separate an option name from its value.


<A NAME="lbAD">&nbsp;</A>
<H2>DESCRIPTION</H2>

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

<p><b>pnmconvol</b> reads two PNM images as input, convolves the
second using the first, and writes a PNM image as output.

<P>Convolution means replacing each pixel with a weighted average of
the nearby pixels.  The weights and the area to average are determined
by the convolution matrix (sometimes called a convolution kernel),
which you supply by way of the PNM image in the file you identify with
the <i>convolution_matrix_file</i> argument.  There are two ways
<b>pnmconvol</b> interprets the PNM convolution matrix image pixels as
weights: with offsets, and without offsets.

<p>The simpler of the two is without offsets.  That is what happens
when you specify the <b>-nooffset</b> option.  In that case,
<b>pnmconvol</b> simply normalizes the sample values in the PNM image
by dividing by the maxval.

<p>For example, here is a sample convolution file that causes an output pixel
to be a simple average of its corresponding input pixel and its 8 neighbors,
resulting in a smoothed image:

<PRE>
    P2
    3 3
    18
    2 2 2
    2 2 2
    2 2 2
</PRE>

<p>(Note that the above text is an actual PGM file -- you can cut and paste
it.  If you're not familiar with the plain PGM format, see
<a href="pgm.html">the PGM format specification</a>).

<p><b>pnmconvol</b> divides each of the sample values (2) by the maxval
(18) so the weight of each of the 9 input pixels gets is 1/9, which is
exactly what you want to keep the overall brightness of the image the
same.  <b>pnmconvol</b> creates an output pixel by multiplying the
values of each of 9 pixels by 1/9 and adding.

<p>Note that with maxval 18, the range of possible values is 0 to 18.
After scaling, the range is 0 to 1.

<p>For a normal convolution, where you're neither adding nor
subtracting total value from the image, but merely moving it around,
you'll want to make sure that all the scaled values in (each plane of)
your convolution PNM add up to 1, which means all the actual sample
values add up to the maxval.

<p>When you <em>don't</em> specify <b>-nooffset</b>, <b>pnmconvol</b>
applies an offset, the purpose of which is to allow you to indicate
negative weights even though PNM sample values are never negative.  In
this case, <b>pnmconvol</b> subtracts half the maxval from each sample
and then normalizes by dividing by half the maxval.  So to get the
same result as we did above with <b>-nooffset</b>, the convolution
matrix PNM image would have to look like this:

<PRE>
    P2
    3 3
    18
    10 10 10
    10 10 10
    10 10 10
</PRE>

<P>To see how this works, do the above-mentioned offset: 10 - 18/2
gives 1.  The normalization step divides by 18/2 = 9, which makes it
1/9 - exactly what you want.  The equivalent matrix for 5x5 smoothing
would have maxval 50 and be filled with 26.

<p>Note that with maxval 18, the range of possible values is 0 to 18.
After offset, that's -9 to 9, and after normalizing, the range is -1 to 1.

<p>For a normal convolution, where you're neither adding nor
subtracting total value from the image, but merely moving it around,
you'll want to make sure that all the offset, scaled values in (each
plane of) your convolution PNM add up to 1.  That means the actual
sample values, less half the maxval, add up to half the maxval as in
the example above.

<P>The convolution file will usually be a PGM, so that the same
convolution gets applied to each color component.  However, if you
want to use a PPM and do a different convolution to different
colors, you can certainly do that.

<P>At the edges of the convolved image, where the convolution matrix
would extend over the edge of the image, <B>pnmconvol</B> just copies
the input pixels directly to the output.

<p>The convolution computation can result in a value which is outside the
range representable in the output.  When that happens, <b>pnmconvol</b> just
clips the output, which means brightness is not conserved.

<A NAME="history">&nbsp;</A>
<H2>HISTORY</H2>
<p>The <b>-nooffset</b> option was new in Netpbm 10.23 (July 2004).


<A NAME="lbAE">&nbsp;</A>
<H2>SEE ALSO</H2>

<B><A HREF="pnmsmooth.html">pnmsmooth</A></B>,
<B><A HREF="pgmmorphconv.html">pgmmorphconv</A></B>,
<B><A HREF="pnmnlfilt.html">pnmnlfilt</A></B>,
<B><A HREF="pgmkernel.html">pgmkernel</A></B>,
<B><A HREF="pamgauss.html">pamgauss</A></B>,
<B><A HREF="pnm.html">pnm</A></B>

<A NAME="lbAF">&nbsp;</A>
<H2>AUTHORS</H2>

Copyright (C) 1989, 1991 by Jef Poskanzer.
<BR>

Modified 26 November 1994 by Mike Burns, <A
HREF="mailto:burns@chem.psu.edu">burns@chem.psu.edu</A>


<HR>
<A NAME="index">&nbsp;</A>
<H2>Table Of Contents</H2>
<UL>
<LI><A HREF="#lbAB">NAME</A>
<LI><A HREF="#lbAC">SYNOPSIS</A>
<LI><A HREF="#lbAD">DESCRIPTION</A>
<LI><A HREF="#lbAE">SEE ALSO</A>
<LI><A HREF="#history">HISTORY</A>
<LI><A HREF="#lbAF">AUTHORS</A>
</UL>
</BODY>
</HTML>