# Image processing and manipulation

Computer image processing involves the use of algorithms to perform operations on digital images to enhance, analyze, or manipulate them. This involves a range of techniques used to convert images into a more desirable form, extract information, or create visual effects.&#x20;



### Working with bitmap data (images and videos)

To load images and videos into the TD network the <mark style="color:orange;">MovieFile In</mark> TOP is used.&#x20;

Here's an example of how to make an image selector that reacts to SuperCollider sending OSC messages:&#x20;

{% tabs %}
{% tab title="TouchDesigner" %}
<figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2F6YiXq5wek7FGoGnodv9J%2F01%20Image%20Selector.png?alt=media&#x26;token=5ca199f1-b127-41df-83f7-a9661477c602" alt=""><figcaption></figcaption></figure>


{% endtab %}

{% tab title="SuperCollider" %}
{% code overflow="wrap" lineNumbers="true" %}
```supercollider
s.boot;
s.quit;

// see available audio devices
ServerOptions.outDevices;

// define output device
Server.default.options.outDevice_("Scarlett 8i6 USB");

// Set up NetAddr for OSC communication
n = NetAddr("localhost", 12000);

// Define the SynthDef

SynthDef(\randomFilterSaw, {
    arg out=0, freq=220, amp=0.3;
    var sig, filterFreq, trigger;

    // Create trigger for random timing (between 0.5 and 3 seconds)
    trigger = Dust.kr(LFNoise0.kr(0.1).range(1/3, 2));

    // Generate random filter frequency (between 80 and 300 Hz)
    filterFreq = TRand.kr(80, 300, trigger);

    // Saw oscillator
    sig = Saw.ar(freq);

    // Apply low pass filter with random cutoff
    sig = LPF.ar(sig, filterFreq);

    // Apply amplitude envelope
    sig = sig * amp;

    // Send OSC message with current filter frequency
    SendReply.kr(trigger, '/filter_freq', filterFreq);

    Out.ar(out, sig!2);
}).add;

OSCdef(\filterFreqReporter, {|msg|
    var freq = msg[3];
    "Current filter frequency: % Hz".format(freq).postln;
    n.sendMsg("/filter_freq", freq);
}, '/filter_freq');




// Start synth on first output (channel 0)
x = Synth(\randomFilterSaw, [\out, 0]);

x.free;
```
{% endcode %}


{% endtab %}
{% endtabs %}



### Manipulation of values in the bitmap: Color adjustments + Manipulation of the bitmap structure&#x20;

TouchDesigner provides many operators to easily adjust and manipulate bitmap data. The functionality of these operators is quite similar as in equivalent tools in image editing programms like Photoshop or video editors.&#x20;

TOPs: HSV Adjust, Level, Monochrome, Blend

{% tabs %}
{% tab title="TouchDesigner" %}
<figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FZAmVle2wCLnMu5xLhPHf%2FImage%20Processing.png?alt=media&#x26;token=ec14936f-b6f8-4f0c-a825-bd89be92cc54" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="SuperCollider" %}
{% code overflow="wrap" lineNumbers="true" %}
```supercollider
s.boot;
s.quit;

// see available audio devices
ServerOptions.outDevices;

// define output device
Server.default.options.outDevice_("Scarlett 8i6 USB");

// Set up NetAddr for OSC communication
n = NetAddr("localhost", 12000);

// Define the SynthDef

SynthDef(\randomFilterSaw, {
    arg out=0, freq=220, amp=0.3;
    var sig, filterFreq, trigger;

    // Create trigger for random timing (between 0.5 and 3 seconds)
    trigger = Dust.kr(LFNoise0.kr(0.1).range(1/3, 2));

    // Generate random filter frequency (between 80 and 300 Hz)
    filterFreq = TRand.kr(80, 300, trigger);

    // Saw oscillator
    sig = Saw.ar(freq);

    // Apply low pass filter with random cutoff
    sig = LPF.ar(sig, filterFreq);

    // Apply amplitude envelope
    sig = sig * amp;

    // Send OSC message with current filter frequency
    SendReply.kr(trigger, '/filter_freq', filterFreq);

    Out.ar(out, sig!2);
}).add;

OSCdef(\filterFreqReporter, {|msg|
    var freq = msg[3];
    "Current filter frequency: % Hz".format(freq).postln;
    n.sendMsg("/filter_freq", freq);
}, '/filter_freq');




// Start synth on first output (channel 0)
x = Synth(\randomFilterSaw, [\out, 0]);

x.free;


SynthDef(\randomFilterNoise, {
    arg out=0, amp=0.3;
    var sig, filterFreq, trigger;

    // Create trigger for random timing (between 0.5 and 3 seconds)
    trigger = Dust.kr(LFNoise0.kr(0.1).range(1/3, 2));

    // Generate random filter frequency (between 100 and 1000 Hz)
    filterFreq = TRand.kr(100, 1000, trigger);

    // White noise oscillator
    sig = WhiteNoise.ar();

    // Apply low pass filter with random cutoff
    sig = LPF.ar(sig, filterFreq);

    // Apply amplitude envelope
    sig = sig * amp;

    // Send OSC message with current filter frequency to localhost:12000
    SendReply.kr(trigger, '/noise_freq', filterFreq);

    // Output routing
    Out.ar(out, sig!2);
}).add;



// OSC responder
OSCdef(\noiseFreqReporter, {|msg|
    var freq = msg[3];
    "Current filter frequency: % Hz".format(freq).postln;
    n.sendMsg("/noise_freq", freq);
}, '/noise_freq');


y = Synth(\randomFilterNoise);
y.free;
```
{% endcode %}


{% endtab %}
{% endtabs %}





{% hint style="success" %}
Assignment:

Experiment with different texture operators to manipulate bitmap data. Find out about them autonomously. Pair them via OSC with sounds generated in SuperCollider.

Duration: \~30 minutes
{% endhint %}



Example for detecting edges, extracting 2d-vector points and using them for generative visuals (coded in Processing, but similarely possible in TouchDesigner): [http://andreaspirchner.com/generative-image-based-illustration/](http://andreaspirchner.com/generative-image-based-illustration/)

<div><figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FRtgjeKJx7hoN2WV4SBgU%2Frhizom04.jpg?alt=media&#x26;token=d77999cb-ad01-40d5-ba96-90b83d13f675" alt=""><figcaption></figcaption></figure> <figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FIbyVt05wcud9kYRh5hH2%2Frhizom06.jpg?alt=media&#x26;token=e2677f96-6fee-49dc-9376-ddd167bae988" alt=""><figcaption></figcaption></figure> <figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FWkigsdZeQuaMQSc8juiC%2Frhizom09.jpg?alt=media&#x26;token=d2648500-e2e6-4d7f-8678-5ba551ab89c2" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FtQ2clNOOpXKMbQBrvTC8%2Frhizom13.jpg?alt=media&#x26;token=91179c07-d7a0-439f-8d69-aa93e6112fb6" alt=""><figcaption></figcaption></figure> <figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FNqt5UoTrWbrc2caztqrR%2Frhizom14.jpg?alt=media&#x26;token=23248d75-cf1f-4908-9653-ec7119227ae2" alt=""><figcaption></figcaption></figure> <figure><img src="https://510937649-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FjQUmn9q3i7gpMtKYvCss%2Fuploads%2FExjHa1SoQfQVXFXTyxO6%2Frhizom15.jpg?alt=media&#x26;token=8734b5a2-e822-4451-9337-5173088d56ca" alt=""><figcaption></figcaption></figure></div>









