The Binary Brain

Université de Bordeaux
×
Harvard Medical School

#seriousgame #tablette #recherche #crowdsourcing #cerveau

💀📲

Parcourir le cerveau humain dans le navigateur.

IRM

Imagerie par Résonance Magnétique

Image Voxel

💾

my_brain.nii
Nifti-1

🤖

Le binaire

1, 10, 11, 100, 101

1 bit = 0 | 1

8 bits = 1 octet = 10010110

1024 octets =1 Ko = 8192 bits

536,870,912 octets

Representer l'information

Numériser votre information

Numéro de sécurité sociale

189103818504886

Stocker les nombres en binaire

base 10 👉 base 2

Représenter une image en binaire

  • Une grille de pixel
  • 1 pixel = 1 couleur
  • 1 couleur = 3 valeurs RVB
  • 1 valeur = 1 entier de 0 à 255

Entier sur 8 bit

00000000 = 0

11111111 = 255

3 x 8 bits = 24 bits
16,777,216 valeurs possibles

111011111001001000011100100010110101000011111001

2391462813980249

Entier sur 16 bit

0000000000000000 = 0

1111111111111111 = 65535

111011111001001000011100100010110101000011111001

61330730720729

Une chaine binaire n'a pas de signification en soi.

Manipuler du binaire
en Javascript

ArrayBuffer

const buffer = new ArrayBuffer(byteLength);

001100100100010100000101010011100101011010101011

TypedArrays

const view = new Uint8Array(buffer);

00110010 01000101 00000101 01001110 01010110 10101011

[50, 69, 5, 78, 86, 171]
const view = new Uint16Array(buffer);

0011001001000101 0000010101001110 0101011010101011

[12869, 1358, 22187]

Ecriture

view[0] = 255;

11111111 01000101 00000101 01001110 01010110 10101011

Attention aux dépassements !

view[0] = 546;

546 = 1000100010

view[0] === 34;

Plein d'utilitaires!

Int8Array, Float32Array, Uint8ClampedArray, Uint32Array, ...

new Uint8Array(buffer, 2, 4);
new DataView(buffer).setInt16(42, 1337);
ArrayBuffer.slice(0, 352);

Tableaux typés en PHP ?!

// Create a unsigned int
$buffer = pack("S*", 61330, 7307, 20729);
// string(6)

// Read as 16bit unsigned integers
$values = unpack("S*", $buffer);
// [61330, 7307, 20729]

Recevoir des données existantes

XMLHttpRequest
const request = new XMLHttpRequest();
request.responseType = 'arraybuffer';
request.open('GET', 'http://my.brain.com/my_brain.nii');
request.addEventListener('load', () => {
    const buffer = request.response;
});
request.send();
FileReader
const file = document.getElementById('my-file').files[0];
const buffer = new FileReader().readAsArrayBuffer(file);
WebSocket
const socket = new WebSocket('ws://localhost');
socket.binaryType = 'arraybuffer';
socket.send(buffer);
// ---
socket.on('message', (event) => { const buffer = event.data; })

La spec Nifti-1

Header sur 352 octets

40 Nombre de dimensions: 3 (ou 4 👽)
42 44 46 Largeur, hauteur et profondeur
70 72 DataType et Nombre de bit par voxel
... Information d'échelles, description, etc.

Manipuler le header

const header = new DataView(buffer, 0, 352);
const width  = header.getUint16(42); // 256
const height = header.getUint16(44); // 256
const depth  = header.getUint16(46); // 176
const dataType = header.getUint16(70); // 16 (Float32Array)
const bitPerVoxel = header.getUint16(72); // 32

Body à partir de l'octet 352

Suite de voxel.

const size = 352 + (length * width * depth) * (bitPerVoxel / 8);

11 534 336 voxels

46 137 696 octets = 46,1 Mo

Lire le body

const body = new Float32Array(buffer, 352); 
function getVoxelValue(x, y, z) {
    const index = x + (y * width) + (z * width * height);

    return body[index];
}

Créer une image

const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const slice = new ImageData(width, height);

Remplir l'image

function setPixelValue(x, y, intensity) {
    const index = 4 * (x + y * width);
    const value = Math.round(intensity * 255);

    slice.data.fill([value, value, value, 255], index); // R, G, B, A
}
setPixelValue(50, 100, getVoxelValue(50, 100, 32));

Afficher l'image

context.putImageData(slice);
demo.tom32i.fr

Pourquoi c'est cool ?

🏋️

Le poids

Json: 54 octets

{ "event": "position", "id": 19, "x": 125, "y": 158 }

Binaire: 6 octets

[event sur 1 octet][id sur 1 octet][x sur 2 octets][y sur 2 octets]

⚡️

Rapidité de l'encodage / décodage

🌍

Supporte tout, supporté partout.

☠️

Pourquoi c'est chaud ?

  • Pas lisible
  • Rigide
  • Peu de bug

💡️

Quelques idées d'utilisation

  • Lire et écrire un format tiers.
  • Jeu en temps réel.
  • Filtres Instagram.
Javascript gère bien le binaire 👌

Merci !