An example of something, which isn’t AI.

One of the behaviours which has been trending for several years now, is to take an arbitrary piece of information, and just to call it AI.

This should not be done.

As an example of what I mean, I can give the following image:

frame_000010_c_1

This is an image, which has been palletized. That means that the colours of individual pixels have been reduced to ‘some palette of 256 colours’. What any conventional software allows me to do – including ‘GIMP’ – is next, to assign a new colour palette to this image, so that all these colours get remapped, as follows:

frame_000010_c_2

What I could do – although I won’t – is claim somehow that this has ‘artistic merit’. But what I cannot legitimately do is, to claim that the second image is ‘an example of AI’.

(Updated 7/06/2021, 16h30… )

Continue reading An example of something, which isn’t AI.

An exercise at converting an arbitrary video clip into ASCII-art.

One of the throw-back activities in Computing, which has existed since the 1990s, was so-called ‘ASCII-Art’, in which regular characters represented an image.

When this form of Art is created by a Human, it can look quite nice. But, if a mere computer program is given a sequence of images to convert into characters in a batch-process, the results are usually inferior, because all the program will be able to do is, to translate each cell of the images to an ASCII character, the brightness of which is supposed to represent the original brightness of the cell of the image. The complex shape of the actual text characters is not taken into account – at least, by any programs I have access to – and will also interfere with the viewer’s ability to recognize the intended image, because those shapes will just represent some random ‘noise’ in the image, without which, merely to have been given grey-scale tiles would have probably made it easier for the viewer to recognize the image.

In spite of recognizing this, I have persevered, and converted an arbitrary video-clip of mine into ASCII-art, programmatically. The following is the link by which it can be viewed:

(Link within my Web-site.)

And Yes, the viewer would need to enable JavaScript from my site, in order to obtain an actual animation, because that is what advances the actual ‘iframe’.

 

(Updated 6/26/2021, 14h45… )

Continue reading An exercise at converting an arbitrary video clip into ASCII-art.

There can be curious gaps, in what some people understand.

One of the concepts which once dominated CGI was, that textures assigned to 3D models needed to include a “Normal-Map”, so that even early in the days of 3D gaming, textured surfaces would seem to have ‘bumps’, and these normal-maps were more significant, than displacement-maps – i.e., height- or depth-maps – because shaders were actually able to compute lighting subtleties more easily, using the normal-maps. But additionally, it was always quite common that ordinary 8x8x8 (R,G,B) texel-formats needed to store the normal-maps, just because images could more-easily be prepared and loaded with that pixel-format. (:1)

The old-fashioned way to code that was, that the 8-bit integer (128) was taken to symbolize (0.0), that (255) was taken to symbolize a maximally positive value, and that the integer (0) was decoded to (-1.0). The reason for this, AFAIK, was the use by the old graphics cards, of the 8-bit integer, as a binary fraction.

In the spirit of recreating that, and, because it’s sometimes still necessary to store an approximation of a normal-vector, using only 32 bits, the code has been offered as follows:

 


Out.Pos_Normal.w = dot(floor(normal * 127.5 + 127.5), float3(1 / 256.0, 1.0, 256.0));

float3 normal = frac(Pos_Normal.w * float3(1.0, 1 / 256.0, 1 / 65536.0)) * 2.0 - 1.0;

 

There’s an obvious problem with this backwards-emulation: It can’t seem to reproduce the value (0.0) for any of the elements of the normal-vector. And then, what some people do is, to throw their arms in the air, and to say: ‘This problem just can’t be solved!’ Well, what about:

 


//  Assumed:
normal = normalize(normal);

Out.Pos_Normal.w = dot(floor(normal * 127.0 + 128.5), float3(1 / 256.0, 1.0, 256.0));

 

A side effect of this will definitely be, that no uncompressed value belonging to the interval [-1.0 .. +1.0] will lead to a compressed series of 8 zeros.

Mind you, because of the way the resulting value was now decoded again, the question of whether zero can actually result, is not as easy to address. And one reason is the fact that, for all the elements except the first, additional bits after the first 8 fractional bits, have not been removed. But that’s just a problem owing to the one-line decoding that was suggested. That could be changed to:

 


float3 normal = floor(Pos_Normal.w * float3(256.0, 1.0, 1 / 256.0));
normal = frac(normal * (1 / 256.0)) * (256.0 / 127.0) - (128.0 / 127.0);

 

Suddenly, the impossible has become possible.

N.B.  I would not use the customized decoder, unless I was also sure, that the input floating-point value, came from my customized encoder. It can easily happen that the shader needs to work with texture images prepared by an external program, and then, because of the way their channel-values get normalized today, I might use this as the decoder:

 


float3 normal = texel.rgb * (255.0 / 128.0) - 1.0;

 

However, if I did, a texel-value of (128) would still be required, to result in a floating-point value of (0.0)

(Updated 5/10/2020, 19h00… )

Continue reading There can be curious gaps, in what some people understand.

Wavelet Decomposition of Images

One type of wavelet which exists, and which has continued to be of some interest to computational signal processing, is the Haar Wavelet. It’s thought to have a low-pass and a high-pass version complementing each other. This would be the low-pass Haar Wavelet:

[ +1 +1 ]

And this would be the high-pass version:

[ +1 -1 ]

These wavelets are intrinsically flawed, in that if they are applied to audio signals, they will produce poor frequency response each. But they do have as an important Mathematical property, that from its low-pass and its high-pass component, the original signal can be reconstructed fully.

Now, there is also something called a wavelet transform, but I seldom see it used.

If we wanted to extend the Haar Wavelet to the 2D domain, then a first approach might be, to apply it twice, once, one-dimensionally, along each axis of an image. But in reality, this would give the following low-frequency component:

[ +1 +1 ]

[ +1 +1 ]

And only, the following high-frequency component:

[ +1 -1 ]

[ -1 +1 ]

This creates an issue with common sense, because in order to be able to reconstruct the original signal – in this case an image – we’d need to arrive at 4 reduced values, not 2, because the original signal had 4 distinct values.

gpu_1_ow

And so closer inspection should reveal, that the wavelet reduction of images has 3 distinct high-frequency components: ( :1 )

Continue reading Wavelet Decomposition of Images