hn4u @ Last updated 21/11/04 22:42
Go to my homepage at http://4u.jcisio.com
Full version available at http://4u.jcisio.com/r/article404.htm

Không rõ

2D Image/Pixel Computations

How do I rotate a bitmap?

The easiest way, according to the comp.graphics faq, is to take

the rotation transformation and invert it. Then you just iterate

over the destination image, apply this inverse transformation and

find which source pixel to copy there.

A much nicer way comes from the observation that the rotation

matrix:

R(T) = { { cos(T), -sin(T) }, { sin(T), cos(T) } }

is formed my multiplying three matrices, namely:

R(T) = M1(T) * M2(T) * M3(T)

where

M1(T) = { { 1, -tan(T/2) },

{ 0, 1         } }

M2(T) = { { 1,      0    },

{ sin(T), 1    } }

M3(T) = { { 1, -tan(T/2) },

{ 0,         1 } }

Each transformation can be performed in a separate pass, and

because these transformations are either row-preserving or

column-preserving, anti-aliasing is quite easy.

Another fast approach is to perform first a column-preserving roation,

and then a row-preserving rotation. For an image W pixels wide and

H pixels high, this requires W+H BitBlt operations in comparison to

the brute-force rotation, which uses W*H SetPixel operations (and a

lot of multiplying).

Reference:

Paeth, A. W., "A Fast Algorithm for General Raster Rotation",

Proceedings Graphics Interface '89, Canadian Information

Processing Society, 1986, 77-81

[Note - e-mail copies of this paper are no longer available]

[Gems I]

How do I display a 24 bit image in 8 bits?

[Gems I] pp. 287-293, "A Simple Method for Color Quantization:

Octree Quantization"

B. Kurz.  Optimal Color Quantization for Color Displays.

Proceedings of the IEEE Conference on Computer Vision and Pattern

Recognition, 1983, pp. 217-224.

[Gems II] pp. 116-125, "Efficient Inverse Color Map Computation"

This describes an efficient technique to

map actual colors to a reduced color map,

selected by some other technique described

in the other papers.

[Gems II] pp. 126-133, "Efficient Statistical Computations for

Optimal Color Quantization"

Xiaolin Wu.  Color Quantization by Dynamic Programming and

Principal Analysis.  ACM Transactions on Graphics, Vol. 11, No. 4,

October 1992, pp 348-372.

How do I fill the area of an arbitrary shape?

"A Fast Algorithm for the Restoration of Images Based on Chain

Codes Description and Its Applications", L.W. Chang & K.L. Leu,

Computer Vision, Graphics, and Image Processing, vol.50,

pp296-307 (1990)

Heckbert, Paul S., Generic Convex Polygon Scan Conversion and Clipping,

Graphics Gems, p. 84-86, code: p. 667-680, PolyScan/.

Heckbert, Paul S., Concave Polygon Scan Conversion, Graphics Gems, p.

87-91, code: p. 681-684, ConcaveScan.c.

http://www.acm.org/tog/GraphicsGems/gems/PolyScan/

http://www.acm.org/tog/GraphicsGems/gems/ConcaveScan.c

For filling a region of a bitmap, see

Heckbert, Paul S., A Seed Fill Algorithm, Graphics Gems, p. 275-277,

code: p. 721-722, SeedFill.c. The code is at

http://www.acm.org/tog/GraphicsGems/gems/SeedFill.c

[Gems I]

[Foley]

[Hearn]

How do I find the 'edges' in a bitmap?

A simple method is to put the bitmap through the filter:

-1    -1    -1

-1     8    -1

-1    -1    -1

This will highlight changes in contrast.  Then any part of the

picture where the absolute filtered value is higher than some

threshold is an "edge".

A more appropriate edge detector for noisy images is

described by Van Vliet et al. "A nonlinear Laplace operator

as edge detector in noisy images", in Computer Vision,

Graphics, and image processing 45, pp. 167-195, 1989.

How do I enlarge/sharpen/fuzz a bitmap?

Sharpening of bitmaps can be done by the following algorithm:

I_enh(x,y) = I_fuz(x,y)-k*Laplace(I_fuz(x,y))

or in words:  An image can be sharpened by subtracting a positive

fraction k of the Laplace from the fuzzy image.

One "Laplace" kernel, approximating a Laplacian operator, is:

1   1   1

1  -8   1

1   1   1

The following library implements Fast Gaussian Blurs:

MAGIC: An Object-Oriented Library for Image Analysis by David Eberly

The library source code and the documentation (in Latex) are  at

http://www.magic-software.com/

The code compiles on Unix systems using g++ and on PCs using

Microsoft Windows 3.1 and Borland C++.  The fast Gaussian blurring

is based on a finite difference method for solving s u_s = s^2 \nabla^2 u

where s is the standard deviation of the Gaussian (t = s^2/2).  It

takes advantage of geometrically increasing steps in s (rather than

linearly increasing steps in t), thus getting to a larger "time" rapidly,

but still retaining stability.  Section 4.5 of the  documentation contains

the algorithm description and implementation.

A bitmap is a sampled image, a special case of a digital signal,

and suffers from two limitations common to all digital signals.

First, it cannot provide details at fine enough spacing to exactly

reproduce every continuous image, nor even more detailed sampled

images. And second, each sample approximates the infinitely fine

variability of ideal values with a discrete set of ranges encoded

in a small number of bits---sometimes just one bit per pixel. Most

bitmaps have another limitation imposed: The values cannot be

negative. The resolution limitation is especially important, but

see "How do I display a 24 bit image in 8 bits?" for range issues.

The ideal way to enlarge a bitmap is to work from the original

continuous image, magnifying and resampling it. The standard way

to do it in practice is to (conceptually) reconstruct a continuous

image from the bitmap, and magnify and resample that instead. This

will not give the same results, since details of the original have

already been lost, but it is the best approach possible given an

already sampled image. More details are provided below.

Both sharpening and fuzzing are examples of filtering. Even more

specifically, they can be both be accomplished with filters which

are linear and shift invariant. A crude way to sharpen along a row

(or column) is to set output pixel B[n] to the difference of input

pixels, A[n]-A[n-1]. A similarly crude way to fuzz is to set B[n]

to the average of input pixels, 1/2*A[n]+1/2*A[n-1]. In each case

the output is a weighted sum of input pixels, a "convolution". One

important characteristic of such filters is that a sinusoid going

in produces a sinusoid coming out, one of the same frequency. Thus

the Fourier transform, which decomposes a signal into sinusoids of

various frequencies, is the key to analysis of these filters. The

simplest (and most efficient) way to handle the two dimensions of

images is to operate on first the rows then the columns (or vice

versa). Fourier transforms and many filters allow this separation.

A filter is linear if it satisfies two simple relations between the

input and output: scaling the input by a factor scales the output

by the same factor, and the sum of two inputs gives the sum of the

two outputs. A filter is shift invariant if shifting the input up,

down, left, or right merely shifts the output the same way. When a

filter is both linear and shift invariant, it can be implemented as

a convolution, a weighted sum. If you find the output of the filter

when the input is a single pixel with value one in a sea of zeros,

you will know all the weights. This output is the impulse response

of the filter. The Fourier transform of the impulse response gives

the frequency response of the filter. The pattern of weights read

off from the impulse response gives the filter kernel, which will

usually be displayed (for image filters) as a 2D stencil array, and

it is almost always symmetric around the center. For example, the

following filter, approximating a Laplacian (and used for detecting

edges), is centered on the negative value.

1/6     4/6     1/6

4/6   -20/6     4/6

1/6     4/6     1/6

The symmetry allows a streamlined implementation. Suppose the input

image is in A, and the output is to go into B. Then compute

B[i][j] = (A[i-1][j-1]+A[i-1][j+1]+A[i+1][j-1]+A[i+1][j+1]

+4.0*(A[i-1][j]+A[i][j-1]+A[i][j+1]+A[i+1][j])

-20.0*A[i][j])/6.0

Ideal blurring is uniform in all directions, in other words it has

circular symmetry. Gaussian blurs are popular, but the obvious code

is slow for wide blurs. A cheap alternative is the following filter

(written for rows, but then applied to the columns as well).

B[i][j] = ((A[i][j]*2+A[i][j-1]+A[i][j+1])*4

+A[i][j-1]+A[i][j+1]-A[i][j-3]-A[i][j+3])/16

For sharpening, subtract the results from the original image, which

is equivalent to using the following.

B[i][j] = ((A[i][j]*2-A[i][j-1]-A[i][j+1])*4

-A[i][j-1]-A[i][j+1]+A[i][j-3]+A[i][j+3])/16

Credit for this filter goes to Ken Turkowski and Steve Gabriel.

Reconstruction is impossible without some assumptions, and because

of the importance of sinusoids in filtering it is traditional to

assume the continuous image is made of sinusoids mixed together.

That makes more sense for sounds, where signal processing began,

than it does for images, especially computer images of character

shapes, sharp surface features, and halftoned shading. As pointed

out above, often image values cannot be negative, unlike sinusoids.

Also, real world images contain noise. The best noise suppressors

(and edge detectors) are, ironically, nonlinear filters.

The simplest way to double the size of an image is to use each of

the original pixels twice in its row and in its column. For much

better results, try this instead. Put zeros between the original

pixels, then use the blurring filter given a moment ago. But you

might want to divide by 8 instead of 16 (since the zeros will dim

the image otherwise). To instead shrink the image by half (in both

vertical and horizontal), first apply the filter (dividing by 16),

then throw away every other pixel. Notice that there are obvious

optimizations involving arithmetic with powers of two, zeros which

are in known locations, and pixels which will be discarded.

How do I map a texture on to a shape?

Paul S. Heckbert, "Survey of Texture Mapping", IEEE Computer

Graphics and Applications V6, #11, Nov. 1986, pp 56-67 revised

from Graphics Interface '86 version

Eric A. Bier and Kenneth R. Sloan, Jr., "Two-Part Texture

Mappings", IEEE Computer Graphics and Applications V6 #9, Sept.

1986, pp 40-53 (projection parameterizations)

How do I detect a 'corner' in a collection of points?

[Currently empty entry.]

Where do I get source to display (raster font format)?

ftp://oak.oakland.edu/SimTel/msdos/

See also James Murray's graphics file formats FAQ:

http://www.ora.com/centers/gff/gff-faq/index.htm

What is morphing/how is it done?

Morphing is the name that has come to be applied to the technique

ILM used in the movie "Willow", where one object changes into

another by changing both its shape and picture detail. It was a

2D image manipulation, and has been done in different ways. The

first method published was by Thad Beier at PDI. Michael Jackson

famously used morphing in his music videos, notably "Black or

White". The word is now used more generally.

For more, see [Anderson], Chapter 3, page 59-90, and Beier's

http://www.hammerhead.com/thad/morph.html

How do I quickly draw a filled triangle?

The easiest way is to render each line separately into an edge

buffer. This buffer is a structure which looks like this (in C):

struct { int xmin, xmax; } edgebuffer[YDIM];

There is one entry for each scan line on the screen, and each

entry is to be interpreted as a horizontal line to be drawn from

xmin to xmax.

Since most people who ask this question are trying to write fast

games on the PC, I'll tell you where to find code.  Look at:

ftp::/ftp.uwp.edu/pub/msdos/demos/programming/source

ftp::/ftp.luth.se/pub/msdos/demos (Sweden)

ftp::/NCTUCCCA.edu.tw:/PC/uwp/demos

/www.wit.com:/mirrors/uwp/pub/msdos/demos">http://www.wit.com:/mirrors/uwp/pub/msdos/demos

ftp::/ftp.cdrom.com:/demos

See also Subject 3.03, which describes methods for filling polygons.

3D Noise functions and turbulence in Solid texturing.

See:

ftp://gondwana.ecr.mu.oz.au/pub/

ftp://ftp.cis.ohio-state.edu/pub/siggraph...raph92_C23.shar

In it there are implementations of Perlin's noise and turbulence

functions, (By the man himself) as well as Lewis' sparse

convolution noise function (by D. Peachey) There is also some of

other stuff in there (Musgrave's Earth texture functions, and some

stuff on animating gases by Ebert).

SPD (Standard Procedural Databases) package:

ftp://avalon.chinalake.navy.mil/utils/SPD/

ftp://avalon.chinalake.navy.mil/utils/SPD/.

Now moved to http://www.viewpoint.com/

References:

[Ebert]

Noise, Hypertexture, Antialiasing and Gesture, (Ken Perlin) in

Chapter 6, (p.193-), The disk accompanying the book is available

from

ftp://archive.cs.umbc.edu/pub/.

For more info on this text/code see:

http://www.cs.umbc.edu/~ebert/book/book.html

For examples from a current course based on this book, see:

http://www.seas.gwu.edu/graphics/ProcTexCourse/

Linke broken 21Jan03; will remove eventually if not fixed.

[Watt:Animation]

Three-dimensional Nocie, Chapter 7.2.1

Simulating turbulance, Chapter 7.2.2

How do I generate realistic sythetic textures?

For fractal mountains, trees and sea-shells:

SPD (Standard Procedural Databases) package:

ftp://avalon.chinalake.navy.mil/utils/SPD/

ftp://avalon.chinalake.navy.mil/utils/SPD/.

Now moved to http://www.viewpoint.com/

Reaction-Diffusion Algorithms:

For an illustartion of the parameter space of a reaction

diffusion system, check out the Xmorphia page at

http://www.ccsf.caltech.edu/ismap/image.html

References:

[Ebert]

Entire book devoted to this subject, with RenderMan™ and C code.

[Watt:Animation]

Procedural texture mapping and modelling, Chapter 7

"Generating Textures on Arbitrary Surfaces Using Reaction-Diffusion"

Greg Turk,   Computer Graphics, Vol. 25, No. 4, pp. 289-298

July 1991 (SIGGRAPH '91)

http://www.cs.unc.edu:80/~turk/reaction_di..._diffusion.html

A list of procedural texture synthesis related web pages

http://www.threedgraphics.com/pixelloom/tex_synth.html

How do I convert between color models (RGB, HLS, CMYK, CIE etc)?

References:

[Watt:3D] pp. 313-354

[Foley]   pp. 563-603

How is "GIF" pronounced?

"GIF" is an acronymn for "Graphics Interchange Format."  Despite the

hard "G" in "Graphics," GIF is pronounced "JIF."  Although we don't

have a direct quote from the official CompuServe specification

released June 1987, here is a quote from related CompuServe documentation,

for CompuShow, a DOS-based image viewer used shortly thereafter:

"The GIF (Graphics Interchange Format), pronounced "JIF", was

designed by CompuServe ..."

We also have a report that the principal author of the GIF spec,

Steve Wilhite, says "it's pronounced JIF (like the peanut butter."

See also

http://www.60-seconds.com/articles/86.html


hainam4u @ Last updated 21/11/04 22:42
Go to my homepage at http://4u.jcisio.com