We now have something like a map. It is not complete but corresponds in character to a Tabula Rogeriana, deficient, yet perhaps complete enough for our first strokes, which will be simple things, akin to painting single points in the spatial sense – just simple waves. To do this we employ G'MIC's Discrete Fourier Synthesis command, -ifft.
Harnessing G'MIC's -set command, we plot coefficients in pairs of otherwise black (zeroed out) 200 × 200, one slice and channel images (gray scales), each, respectively, the real and imaginary components of the spectral domain. We feed these mostly empty spectral domains to -ifft, obtaining the corresponding waveforms.
The preamble to our -set commands:
gmic -input 200,200,1,1 [-1] …
produces the real and imaginary components of the spectral domain, initially empty. The post script:
…-ifft[-2,-1] -remove[-1] -normalize 0,255 -output[-1] wavy.png
transforms our plotted coefficients into the spatial domain, producing waves, and writes the normalized real component out as separate image. Sandwiched betwixt these, our sundry -set commands.
The real component? Yes, the real component, for the G'MIC Inverse Fast Fourier Transform also represents the spatial domain as a field of complex numbers and thereby hangs a tale. It suffices to note at this time that both transforms switch views on the same underlying dataset, one that requires complex numbers in order to be fully expressed.
At our present map-making state, this requirement is not that clear to us. The imaginary component seems a mysterious and slightly annoying extra which more often than not becomes a deletable supernumary. Recent 1.6.x G'MIC releases furnish -fft and -ifft work-a-likes, -dct and -idct, which hide the imaginary component from our ken. For cyclic workflows where one customarily transforms forward to the spectral domain with -fft, alter coefficients to serve some aim, then transit back to the spatial with -ifft, the Discrete Cosine Transform (-dct) and Inverse Discrete Cosine Transform (-idct) furnish imaginary-free spectral editing, a practical convenience. We're map-making, however, and hiding things is not conducive to making good maps. So here we will stick with -fft and -ifft for the sheer mysteries they offer.
Chiral pairing, and that some coefficients do not have counterparts, constitute the most prominent feature of our nascent map. Most coefficients pair off with their "reflection images" across horizontal and vertical reflection axes. The coefficients that do not pair in that way coincide with the various intersection points of these reflection axes. Sitting on the reflection axis, they "self-reflect."
We begin with a gallery of these self-chirals. Though we are formally working with complex numbers, in this round the imaginary components of all our plots are zero, and since our spatial domain components come out of the box as zero, we need not plot zero all over again, so we only use one -set command where two would normally prevail.
-set[0] 1,0,0,0,0 | -set[0] 1,100,0 |
A solid gray, which normalization drives to zero (omitted from the postscript in this rendition). We set the coefficient at 0:0 – the origin, you recall – to 1 + i0. The other arguments which -set takes are for the current slice, 0, and the current channel, 0, and as these values will not change, the corresponding arguments will be omitted here on.
In this example, the transformed image is composed of one value, a “sinusoidal wave” with a frequency of zero and an infinite wavelength. Recall that in the spectral domain, the frequency pair associated with the coefficient y = x = 0 is 0:0. The origin of the spectral domain corresponds to a frequency of zero along the length and breadth of the spatial image. In essence, the origin coefficient defines an unchanging bias value that is applied to every pixel in the spatial image. |
A varying signal, mean of 0. We set the coefficient 100:0 to 1 + i0. The transformed image varies from positive to negative at a wavelength of two pixels, this the Nyquist rate for the 200 × 200 pixel image, which cannot reliably reproduce variations at shorter wavelengths. This particular coefficient, 100:0, is at the top edge of the spectral map, right at pixel column 100, row 0, and the image has a frequency of 100 cycles along the width, but 0 cycles along the height. You might be thinking that there is a relation between frequency and coefficient positions in the specular domain. Nudge, nudge, wink, wink. |
-set[0] 1,0,100 | -set[0] 1,100,100 |
A varying signal, mean of 0. We set the coefficient at 0:100 to 1 + i0 Everything noted about the other waveforms corresponding to Nyquist rates apply here as well. Here we set the coefficient at column 0, row 100 on the left edge of the image and the transformed image produced by -ifft portrays a frequency of 0 cycles along the width, but 100 cycles along the height. You might be thinking that there is a relation between frequency and coefficient positions in the specular domain. We'll kick you once, hard, in the shins if you don't. |
A varying signal, mean of 0, and a one pixel sized checkerboard. Keep -ifft in mind when you want to generate Damn Fast checkerboards at single pixel resolutions. The reason for this should not be a surprise. We set the Nyquist coefficient at 100:100 to 1 + i0. This gives rise to a variation at the Nyquist rate along the height and width. With a two pixel wavelength in both the width and height, a checkerboard necessarily arises. So setting the coefficient at location 100:100 in the 200 × 200 spectral domain image gives rise to an image with a frequency of 100 cycles along the height and a 100 cycles along the width. You don't suppose there is a relationship between the coordinates of a coefficient in the spectral domain and frequencies in the spatial domain? |
The Complex Number Field | Painting With Waves: Part Two |