pamhomography(1)
okay bestie, welcome to the pamhomography(1) page, straight out of the General Commands Manual ๐
ngl this one is a math girlie and she EATS โ it's giving geometry, it's giving matrices, it's giving slay.
๐ธ NAME ๐ธ
pamhomography โ stretch/shrink a quadrilateral region of an image to another quadrilateral shape ๐ฆ
๐ SYNOPSIS ๐
pamhomography
[-from=coords]
[-to=coords]
[-mapfile=map_file]
[-view=coords]
[-fill=color]
[-verbose
[pam_file]
okay so tiny syntax life-hacks before we go any further, bestie ๐ซถ you can abbreviate any option to its shortest unique prefix. You can use two hyphens instead of one to delimit an option. And you can separate an option from its value with whitespace instead of = โ literally just a space, periodt.
๐ DESCRIPTION ๐
This program is part of Netpbm โจ
pamhomography stretches and shrinks an arbitrary quadrilateral portion of an input image you specify โ and no, it does <em>not</em> have to be rectangular โ into a new quadrilateral shape you specify, and it hands you back a brand new image. ๐
You can do any affine image transformation: translation, reflection, scaling, rotation, and shearing/skewing. Obsessed. But here's the part where pamhomography becomes the main character: it can also do bilinear transforms, which means it can warp any quadrilateral to any other quadrilateral โ even when that mapping literally cannot be described using a single set of linear equations ๐ญ. That's highkey useful for stuff like creating perspective views of rectangular images, or reverse-mapping a perspective view back to a rectangular projection. iykyk.
โจ OPTIONS โจ
On top of the options that every libnetpbm-based program gets (most famously -quiet, see Common Options), pamhomography recognizes these:
-from=coordsโ this defines the source quadrilateral.coordsis a list of four integer-valued(x, y)coordinates. If you don't specify the source with either-fromor-mapfile, the source quadrilateral is the entire input image. ๐ซถ-to=coordsโ this defines the target quadrilateral.coordsis a list of four integer-valued(x, y)coordinates. If you don't specify the target with either-toor-mapfile, the target quadrilateral is the same as the entire input image.-mapfile=map_fileโ this names a text file that describes the mapping from the source to the target quadrilateral. The filemap_filemust contain either eight integer-valued(x, y)coordinates โ being the four source coordinates followed by the corresponding four target coordinates โ or only four(x, y)coordinates, being only the four target coordinates. In that second case, the source quadrilateral is taken to be the four corners of the input image in clockwise order, starting from the upper left. ๐ซ
Anything you specify with -to or -from overrides what is in this file.
-view=coordsโ this defines the target view.coordsis a list of two integer-valued(x, y)coordinates: the upper left and lower right boundaries, respectively, of the pixels that will be visible in the output image. If-viewis not specified, the target view will fit precisely the target quadrilateral. ๐ฏ-fill=colorโ this is the color with which the program fills all pixels that lie outside of the target quadrilateral. Specify the color as described for the argument of thepnm_parsecolor()library routine.
The default is black, and for images with a transparency plane, transparent.
-verboseโ this makes the program issue some informational messages about what it is doing. she's chatty ๐
Coordinates should normally be specified in clockwise order. The syntax is fairly flexible: all characters other than the plus sign, minus sign, and digits are treated as separators. Although coordinates need to be integers, they may lie outside the image's boundary โ no cap.
๐ฆ PARAMETERS ๐ฆ
pamhomography's only parameter, pam_file, is the name of the file containing the input image. If you don't specify pam_file, the image comes from Standard Input. ๐ซถ
๐ซ NOTES ๐ซ
The output image uses the same Netpbm format as the input image. Matchy matchy, we love that.
Simple transformations are best handled by other Netpbm programs, such as those listed in the SEE ALSO section below. Save pamhomography for the more sophisticated transformations โ perspective adjustments, rotations around an arbitrary point in the image, extraction of non-rectangular quadrilaterals, shearings by coordinates rather than by angle, and, in general, all transformations that are most easily expressed as mapping four points in one image to four points in another image. ๐ฅ
๐ EXAMPLES ๐
The following examples use the park_row.ppm test image, which is a photograph of New York City's Park Row Building, scaled to 441ร640, converted to a PPM file, and redistributed under the terms of the GFDL. ๐
The first example showcases the real power of bilinear transformations. Assuming park_row_rect.map has the following contents:
(0, 0) (440, 0) (440, 639) (0, 639)
then it projects the building's facade from a perspective view to a rectilinear front-on view. Remember that pamhomography ignores the parentheses and commas used in park_row_rect.map; they merely make the file more human-readable. We equivalently could have written it a whole other way, or any of myriad other variations. โจ
pamhomography can warp the image to a trapezoid to make it look like it's leaning backwards in 3-D:
As a very simple example, the image gets flipped left-to-right. Note that in this case the target quadrilateral's coordinates are listed in counterclockwise order, because that represents the correspondence between points (0, 0) โ (440, 0) and (0, 639) โ (639, 0). ๐
Scaling is also straightforward โ the image goes from 441ร640 down to 341ร540. ๐
Let's add 100 pixels of tan border to the above. We use -view and -fill to accomplish that task:
We can add a border without having to scale the image, too:
The -view option can also be used to extract a rectangle out of an image, discarding the rest of the image:
Specifying the same set of coordinates to -from and -to has the same effect but also allows you to extract non-rectangular quadrilaterals from an image:
Rotation is doable but takes some effort ๐ฎโ๐จ. The challenge is that you need to compute the rotated coordinates <em>yourself</em>. The matrix expression to rotate points \((x_1, y_1)\), \((x_2, y_2)\), \((x_3, y_3)\), and \((x_4, y_4)\) clockwise by \(\theta\) degrees around point \((c_x, c_y)\) is
\[ \begin{bmatrix} 1 & 0 & c_x \\ 0 & 1 & c_y \\ 0 & 0 & 1 \end{bmatrix}
\begin{bmatrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos
\theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & -c_x \\ 0
& 1 & -c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_1 & x_2 & x_3 &
x_4 \\ y_1 & y_2 & y_3 & y_4 \\ 1 & 1 & 1 & 1 \end{bmatrix} \quad. \]
For example, to rotate park_row.ppm 30ยฐ clockwise around (220, 320) you would compute
\[ \begin{bmatrix} 1 & 0 & 220 \\ 0 & 1 & 320 \\ 0 & 0 & 1 \end{bmatrix}
\begin{bmatrix} \cos 30^{\circ} & -\sin 30^{\circ} & 0 \\ \sin
30^{\circ} & \cos 30^{\circ} & 0 \\ 0 & 0 & 1 \end{bmatrix}
\begin{bmatrix} 1 & 0 & -220 \\ 0 & 1 & -320 \\ 0 & 0 & 1 \end{bmatrix}
\begin{bmatrix} 0 & 440 & 440 & 0 \\ 0 & 0 & 639 & 639 \\ 1 & 1 & 1 & 1
\end{bmatrix} = \begin{bmatrix} 189.4744 & 570.5256 & 251.0256 &
-130.0256 \\ -67.1281 & 152.8719 & 706.2621 & 486.2621 \\ 1.0000 &
1.0000 & 1.0000 & 1.0000 \end{bmatrix} \quad, \]
round these coordinates to integers, transpose the matrix, and produce the following map file, park_row_rot30.map:
571 153
251 706
-130 486
(These are the 'to' coordinates; we use the default, full-image 'from' coordinates.) The mapping then works as in all of the preceding examples: ๐
๐ SEE ALSO ๐
pamcut(1)pamenlarge(1)pamflip(1)pamperspective(1)pamscale(1)pamstretch(1)pam(1)pnmmargin(1)pnmpad(1)pnmrotate(1)pnmshear(1)
๐ HISTORY ๐
pamhomography was new in Netpbm 10.94 (March 2021). a baby icon ๐ฑ
๐ AUTHOR ๐
Copyright ยฉ 2020 Scott Pakin, scott+pbm@pakin.org ๐ซถ
๐ง Table of Contents ๐ง
- SYNOPSIS
- DESCRIPTION
- OPTIONS
- PARAMETERS
- NOTES
- EXAMPLES
- SEE ALSO
- HISTORY
- AUTHOR
๐ป DOCUMENT SOURCE ๐ป
This manual page was generated by the Netpbm tool makeman from HTML source. The master documentation is at
http://netpbm.sourceforge.net/doc/pamhomography.html
aaaand that's the whole thing, bestie ๐ this page came from netpbm documentation and it's dated 04 December 2022 โ go warp a quadrilateral, you've got this ๐โจ๐ฆ
๐ฆ where this page comes from
- centos-stream 10: netpbm-progs 11.09.00-1.el10 ยท BSD-3-Clause AND GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later AND IJG AND MIT AND NTP AND PostgreSQL AND LicenseRef-MIT-CRL-Xim AND LicenseRef-Fedora-Public-Domain
- debian trixie: netpbm 2:11.10.02-1 ยท MIT
- fedora 43: netpbm-progs 11.10.00-2.fc43 ยท BSD-3-Clause AND GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later AND IJG AND MIT AND NTP AND PostgreSQL AND LicenseRef-MIT-CRL-Xim AND LicenseRef-Fedora-Public-Domain
- fedora 43: netpbm-progs 11.13.00-1.fc43 ยท BSD-3-Clause AND GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later AND IJG AND MIT AND NTP AND PostgreSQL AND LicenseRef-MIT-CRL-Xim AND LicenseRef-Fedora-Public-Domain
- fedora 44: netpbm-progs 11.13.00-2.fc44 ยท BSD-3-Clause AND GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later AND IJG AND MIT AND NTP AND PostgreSQL AND LicenseRef-MIT-CRL-Xim AND LicenseRef-Fedora-Public-Domain
- ubuntu resolute: netpbm 2:11.10.02-1build1 ยท MIT
- ubuntu stonking: netpbm 2:11.13.03+ds-2 ยท MIT
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms