image/svg+xml

Figure 7: The (Spectral Domain) World According To -tiletex

-Tiletex

It soon grows tedious to render single waveform compositions. By setting a lot of coefficients in one fell swoop, we can obtain textures of complexity and interest. And though, up to now, we have been mainly working in Glorious Black and White, the extension to color is trivial. The Fourier analysis and synthesis transforms treat each channel of multispectral images independently. So red, green and blue spectral coefficients exit the transform as distinct red, green and blue waveforms.

By the time you read this, a spraycan of spectral domain coefficients, -tiletex, should be on the G'MIC server. You can get it by executing gmic -update, or, alternatively, hitting the refresh button within the Gimp-G'MIC plug-in.

If you can't get to the Internet, there is an annotated cut-and-paste version in an appendix to this recipe, which, hopefully, hasn't been left out of whatever it is you're reading, You can cut and paste the code into your .gmic file in your home directory (UNIX-flavor O/S) or your %APPDATA%/gmic file (WINDOWS). There isn't a Gimp-G'MIC plug-in version of -tiletex as of this writing. Maybe when the G'MIC Department of Redundant Documentation Department finishes its mission to Pluto.

-tiletex generates tileable textures; it does so by transforming a chunk of the spectral domain around the Zero Pole into the spatial domain, which, you might recall, can be likened to the surface of a torus. The left edge of the texture segues to the right, making a tube; the top edge of the texture segues to the bottom, making a torus. Or, instead of that, use a bazillion copies to seamlessly carpet the Piazza San Pietro, but a lot of people would probably get upset with you so don't do it.

With -tiletex, we have been induced to redraw the spectral domain (yet again: Figure 7), progressing perhaps to the World Map by Hendrick Hondius (1630). The most visually dramatic change is really one of orientation. We have shifted the map diagonally so that the Zero Pole (ZP) occupies the center, with the Nyquist Pole (NP) occupying the upper left hand corner. In G'MIC-speak: -shift 50%,50%,0,0,2, cyclic mode, so that pixels roll off one edge and emerge at the opposite. Practical matters have induced this: about seven times in ten, we manipulate the coefficients very near the Zero Pole, so that becomes the view that we'd most like removed from the discontinuity of edges.

New to this map are these curious barred circles. The diagonal slashes indicate the predilections of waveforms in that quadrant to bend sinister or bend dexter orientations. There are clockwise and counterclockwise revolution hints on these markers that reference new discoveries, the marvels of which we will defer to the next section, Coefficient Values: Part One. The rather more reddish horizontal rows demark horizontal reflection axes and the rather more cyanic columns demark vertical reflection axes, with the four self-chirals nestled at their intersections.

-tiletex has two behaviors. If you hand it a bunch of empty images, the script will take these to be desolate patches of the spectral domain and spraypaint a bunch of randomly chosen, nonzero values around the Zero Pole. This gets you interesting results (usually) without having to write a panoply of -set commands. Or you can feed -tiletex image pairs where you yourself have set the coefficients around the Zero Pole. You don't need a bunch of -set commands; a paint program that does one pixel pencil strokes will do. Recall that coefficients are complex numbers, hence come in two parts. Hitherto, we have written these parts in rectangular form: the real component (a) plus the imaginary component (ib). -tiletex only accepts the alternate polar form, where a ray (r) of a certain length (magnitude) rotates by a certain phase angle (θ) to select a point on the complex plane. Again, practical matters induce this: to express coefficient values via paint programs, we have to dance daintily around the issue of numeric representation, to wit: most paint programs deal in unsigned (zero or positive) integers, still too commonly in eight bit formats. Magnitudes are distances and can always be positive. Angles can always be positive rotations, so with the polar form, we may constitute complex numbers without recourse to numerals less than zero.

-tiletex takes three optional arguments. 'texscale' sets a window size around the Zero Pole within which random coefficients will be set, if the image appears bereft of imagery, or which coefficients will be cataloged otherwise. It can be as large as you like, but it is pointless to set it larger than half the largest dimension of the input images and it defaults to 8. 'autoangle' sets a default phase angle in degrees. In principle, -tiletex requires two coefficient images, one establishing the magnitude of the coefficients, the other the phase angle. Setting 'autoangle' to a positive number establishes a default phase angle for all coefficients, so that only one magnitude image is needed. The last argument, 'keepimg', takes three flags, 0, 1, 2. The first, the default, asks that -tiletex furnish both real and imaginary output images, the second asks only for the real image, the third only for the imaginary image.

The following gallery is a progression of some not particulary disciplined play with -tiletex. The top row is a foray into randomness, the middle row delves into specifying coefficients through input images and the last row employs spectral-to-spatial transforms in larger schemes.

gmic \
-srand 1234 \
-input 256,256,1,3 \
-tiletex 1 \
-normalize[-1] 0,255 \
-output[-1] tricolor.png
gmic \
-srand 9717 \
-input 256,256,1,3 \
-tiletex 3 \
-normalize[-2,-1] 0,255 \
-output[-1] tricolor.png
   
We seed the random number generator with '1234' so you can reproduce this result. See the -plasma tutorial for background. The argument, “1”, is the textscale argument. It sets a tiny window around the spectral domain origin so only a very few coordinates in the immediate vicinity of the Zero Point are randomly set. These coordinates have very low coordinates, in the ones and twos, which gives rise to large features with fuzzy edges, the sort of thing which can get through a (very) low pass filter. A larger window, “texscale=3”, admits more coefficients around the origin, corresponding to higher frequency waveforms. This gives rise to smaller features.
gmic \
-input radius_20.png \
-tiletex[-1] 16,0 \
-normalize[-1] 0,255 \
-output[-1] waves_r20.png
 gmic \
-input radius_20.png \
-tiletex[-1] 16,0 \
-normalize[-1] 0,255 \
-output[-1] waves_r20.png




Random is OK but no control over your ultimate destiny. So if you feed -tiletex images that have luminous pixels, it will take these to be coefficient settings. The first argument still sets window size, but now -tiletex is using that argument to limit its attention to just a modest sized region around the Zero Pole. The second argument to -tiletex, 0 here, is a common phase angle argument, which should make your head ring just a little bit. -tiletex likes complex numbers in polar form, an alternate notation for picking out points on the complex number plane. Instead of so many increments horizontally, (a), then so many increments vertically (b), the polar form takes the length of a ray (r) and a rotation amount (θ) to pick out a point on the complex number plane. The rotation amount is the phase angle and the length of the ray is the magnitude. This second argument to -tiletex lets it know that we're not furnishing any phase angles, just magnitudes, and every single blessed one of those complex numbers are to have a common phase angle of zero. This lets us just furnish one input image, setting magnitudes.

The three lefthand images are not the literal input. We have magnified a 16×16 pixel region around the Zero Pole and superimposed a grid to help visualize the location of coefficients. If you peak inside of radius_20.png, you will find these pixels clustered around the image center, depicted here just to the right and below the intersection of the crosshairs.

The righthand images are the result of these four coefficients metamorphing into waveforms which then reinforce one another here, but then cancel one another there. Notice that how we distribute coefficients matter. When we favor one quadrant, the pattern becomes strongly diagonal.

Particular patterns in the spectral domain often engender similar patterns in the spatial, albeit with frequency and angular shifts. Diagonal patterns rotate 90° into other diagonal patterns. Gaussian-like piles at the origin become Gaussian-like piles at the corners, and periodic patterns appear as periodic patterns, though the period in one has an inverse relation to the period in the other.
gmic \
-input wavespectral.png \
-tiletex 20,30,1 \
-channels[-1] 0,1 \
-orientation[-1] \
-normalize[-1] -10,10
-input waveface.png \
-warp[-1] [-2],1,2,2
See text.

Tilable textures are not ends in themselves. Often they go on as pieces in some larger graphic puzzle. In this panel, a low frequency, two channel spatial rendition of a very few spectral coefficients continues its career as a vector field, one exhibiting a full repertoire of shears and whirlpools. 

Some notes on the script: -tiletex has been given only input magnitudes in wavespectral.png, a very few non-zero pixels (coefficients) near the center of the image. The first argument to -tiletex, 20, tells -tiletex to only survey a small square around the Zero Pole. The second argument to -tiletex, 30, sets a common angle of 30° to all the magnitudes found in that window. The third argument to -tiletex, 1, tells it that we are only interested in the real spatial output window. 2 gives us only the imaginary window and 0, the default, provides both.

For the rest of the script, spend some time with -orientation and -warp, We (rather arbitrarily) chose to regard the red and green color components as those of a two dimensional vector, and having made this leap, harnessed -orientation to normalize all of them to unit length. The common purpose for this is to get a fairly direct read on the heading of vectors – their component lengths are the sines and cosines of their heading angles (that is, their orientation). The uncommon purpose is that sign transitions in the original data develop into abrupt creases. They make particularly interesting warp fields. The right hand image in the top row illustrates the results of this enterprise. We apply this green-yellow-red direction field to the face via the -warp command.

It is not difficult to emulate a 1970's era color television set on the fritz, in case the need for such ever arises, which my childhood friend Melvin did for real. A mechanically inclined youngster, he tightened all of the screws in the back of the family color TV set to get rid of a rattle and inadvertently anticipated G'MIC's -warp command by over a quarter century. Alas, he never published. His worldliness was limited at that age. Nobody ever told him about radio frequency circuits either, along with those core adjustment screws on top of the RF coils. But he did make sure that they were pretty darn tight.

Ah. We seem to have digressed.

Almost everything about this animation is the technique on the left repeated, oh, 2,048 times, or there abouts. The bit that is new is the animation of the warp field.

The inside of wavespectral.png, the input image to -tiletex, looks pretty much like the examples in the previous row, those on the left: a bunch of coefficients around the Zero Pole in various colors. In the pipeline that made the 2,048 warp fields for the animation, those coefficients changed color. They were, as engineers like to say, parametrically driven, which is a round-about way of saying they changed color over the length of an interval divided into 2,048 slices, and they changed a little bit for each slice. Since these are spectral coefficients, under Fourier synthesis they morph into waveforms, so as the coefficients change, so change the waveforms. With each increment, they don't wave in quite the same magnitude or phase as before.

The question of how much they change (how fast, what direction) is a matter of taste. In our minds, we had the tentative jerkiness of a color television set with its vertical and horizontal hold circuits very much out of tune (but pretty tight!). For us, the quirkiness of -turbulence, Mode 0, was just the thing, so you should spend some time with that tutorial.

So imagine a -repeat-done loop iterating over a 2048 × 1 three channel (RGB) image that had been worked over by -turbulence with a radius of about 80 to 128, 6 to 12 octaves, a decay factor of 3 or 4, no differencing and Mode 0, because in mode 0 turbulence makes these abrupt transitions — jerks! — that seem especially apt. Two of these long skinny images, one for magnitude the other for angle, were concocted for each coefficient, three chiral pairs, six coefficients, twelve data sets. On each turn of the repeat loop, we took the indexed colors out of each long skinny image and used it to change the color of its corresponding coefficient. Usually, the colors changed slightly, but sometimes one or another would get a turbulent wack, hence the jerkiness.

That Swiss Army knife of video file manipulators, ffmpeg, generated the 2,048 test frames, basic colorbars and a time counter, something that one can do when defining a filter chain. This footage was then warped (-warp) and composited (-blend, difference,0.5) againt the real output image of -tiletex, giving a ghosty, shadow-like coloring. We added a wisp of mode 0 -noise for that faux film effect.


A Wave Painting Workflow Coefficient Values: Part One