Afbeeldingen
Een pixelafbeelding moet een bestaande afbeelding omzetten in digitale codes of een “beeld uit de werkelijkheid” omzetten in een reeks digitale codes. Het principe achter digitalisering is even eenvoudig als geniaal, en vooral ook niet nieuw. Reeds in de Klassieke Oudheid was de techniek van het “digitaliseren” of coderen van informatie bekend. Uiteraard digitaliseerde men toen geen afbeeldingen, maar gebruikte men een gelijkaardige techniek voor het verzenden van tekstboodschappen.
Cleoxenus en Democlitus bedachten een methode die verder werd uitgewerkt door Polybius, waardoor de communicatie op lange afstand aanzienlijk verbeterde. Ze gebruikten combinaties van fakkels, vastgemaakt aan panelen. Elke combinatie van fakkels vertegenwoordigde een bepaalde letter uit het alfabet. Hiervoor werden twee (houten?) panelen opgesteld. Elk paneel was voorzien van houders voor maximum 5 fakkels. Dit gaf een totaal van 25 mogelijke combinaties wat ongeveer overeen kwam met het aantal letters in het Griekse alfabet.
Naar analogie kunnen we dit vergelijken met de werking van een kruiswoordraadsel. Het eerste paneel staat dan voor de horizontale cijfers in het raster, het tweede (rechtse) paneel voor de verticale cijfers langs het raster. Twee fakkels op het linkerpaneel en vijf fakkels op het rechterpaneel stonden voor de letter k. De vergelijking met een kruiswoordraadsel doet een beetje afbreuk aan de inventiviteit van deze vondst. De zender “scant” een tweedimensionale rij van lettertekens. Hij verzendt informatie over de positie van elk element in een raster. Het roept vergelijkingen op met de methodes die door televisies en faxtoestellen worden gebruikt voor het scannen en verzenden van afbeeldingen. Het doet ook denken aan de discretisatie bij het digitaliseren van afbeeldingen1.
Vergelijk een digitale afbeelding met een tabel (zoals bijvoorbeeld in een rekenbladprogramma). Elke horizontale pixel krijgt een cel in een (horizontale) rij. Maar ook verticaal wordt elke pixel in een rij geplaatst. Een afbeelding van 300 x 400 pixels bevat op die manier 400 kolommen (horizontaal) en 300 rijen of een totaal van 120 000 pixels.
Net zoals in MS Excel kan je een tabel ook voorstellen als een grafiek. In het vak wiskunde heb je geleerd dat een grafiek een horizontale as (de x-as) en een verticale as (de y-as) heeft. In een grafiek raken de x- en de y-as elkaar links onderaan. Op dat punt is x=0 en ook y=0. Bij een beeldscherm of bij een afbeelding vormt de linkerbovenhoek het absolute “nulpunt”. De pixel links bovenaan op je computerscherm, in je programmavenster of de linkerbovenhoek van een digitale afbeelding staat op x=0 en y=0. De positie van die pixel is dus x=0 en y=0. Als we één pixel opschuiven naar rechts, dan zitten we op x=1, y=0 enz. Gaan we in plaats van naar rechts, één pixel naar beneden, dan krijgen we x=0, y=1 enz.
In de meest eenvoudige vorm van een digitale afbeelding kan elke pixel twee mogelijke waarden krijgen: een 0 of een 1. Een 0 zou dan kunnen staan voor wit en een 1 voor zwart. We spreken dan van een “bitmap”, of een “bit-kaart”. Inderdaad, elke pixel heeft een plaatsje gekregen op de “kaart” en kan een waarde van één bit krijgen.
Hieronder zie je hoe je op die manier een smiley zou kunnen tekenen.
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
Elk van die pixels heeft een positie in de tabel. De eerste pixel (links bovenaan) staat bijvoorbeeld op x=0 en y=0. Pixelbewerkingen op zo'n afbeelding zijn relatief eenvoudig. Als we de afbeelding willen “inverteren”, dan vervangen we alle 1'en door een 0 en omgekeerd.
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
Uiteraard bevatten de meeste afbeeldingen meer dan 2 kleurwaarden. Hierover leer je meer in het volgende onderdeel.
Als we over digitale afbeelding spreken, dan hebben we het zowel over de manier waarop die afbeeldingen als bestanden worden bewaard, als over de manier waarop een digitaal beeldscherm de afbeeldingen weergeeft. Aan de binnenkant van een beeldscherm zitten de zogenaamde pixels (picture elements), kleine “punten” die het licht in een bepaalde kleur kunnen uitzenden. De resolutie van een beeldscherm vertelt hoeveel pixels een scherm horizontaal en verticaal kan weergeven.
Pixels kunnen kleuren weergeven door de primaire kleuren rood, groen en blauw in een bepaalde verhouding bij elkaar op te tellen (optellen= to add, vandaar “additief” kleursysteem).
De hoeveelheid die van elke primaire kleur nodig is om een bepaalde mengkleur te verkrijgen, drukt men uit in een getal van 8 bits oftwel 256 verschillende waarden. Vermits een computer ook 0 meerekent (geen hoeveelheid), kan de waarde variëren van 0 ('niets van die kleur') tot 255. Je kan die kleurwaarde ook uitdrukken in een “hexadecimale” waarde. Bij hexadecimale codering kan je de volgende waarden toekennen om tot 256 verschillende combinaties te komen: 00 (tot 99 en alle combinaties daar tussen) tot FF (van AA tot FF en alle combinaties daar tussen). De waarde #CCCCCC geeft bijvoorbeeld lichtgrijs, #000000 geeft zwart, en #FFFFFF toont wit.
Kleur |
Rood |
Groen |
Blauw |
RGB-waarde |
---|---|---|---|---|
Wit |
FF |
FF |
FF |
#FFFFFF |
Zwart |
00 |
00 |
00 |
#000000 |
Rood |
FF |
00 |
00 |
#FF0000 |
Groen |
00 |
FF |
00 |
#00FF00 |
Blauw |
00 |
00 |
FF |
#0000FF |
… |
… |
… |
… |
... |
Vermits elke kleur op die manier 256 verschillende waarden kan krijgen, komen we op een totaal van 256*256*256=16 777 216 mogelijke mengkleuren.
“In toepassingen waar een hogere kwaliteit vereist wordt worden ook wel 12, 16 of nog meer bits per kleur gebruikt, waarmee kleurwaardes tussen 0 en 4095 resp. 0 en 65535 of nog meer aangegeven kunnen worden, zo bevatten RAW-bestanden van digitale camera's meestal 12-bits kleurwaarden.”2
Het kleurenpalet in Adobe Photoshop:
Een aantal RGB-kleurwaarden3:
Digitale foto's zijn ook opgebouwd uit pixels en kunnen eveneens verschillend van afmeting zijn. Het aantal pixels per inch (PPI) noemt men de resolutie van de digitale afbeelding. Hoe hoger de resolutie, des te beter is de detailweergave.
Elke pixel heeft een kleur. Die kleur wordt vaak beschreven met een of meerdere bits (een ‘bit’ is een afkorting voor ‘binary digit’). Het aantal bits per pixel bepaalt het aantal kleuren dat een pixel kan weergeven. Een twee-bit pixel kan 4 kleuren weergeven; een 8-bit (één byte)-pixel geeft 256 kleuren weer. In het algemeen kan een pixel 2n kleuren weergeven als n het aantal bits is. Welke verschillende kleuren een pixel kan weergeven, hangt niet alleen af van het aantal bits dat beschikbaar is, maar ook van de gebruikte kleurcodering. Er kan worden afgesproken dat iedere primaire kleur een aantal bits krijgt (RGB) of dat iedere unieke combinatie bits verwijst naar een bepaalde kleur in een palet. Dit laatste systeem wordt gebruikt in GIF-plaatjes, die maximaal 256 kleuren kunnen gebruiken.
Hoe hoger de beeldresolutie en hoe groter het aantal bits per pixel, hoe meer computergeheugen nodig is om alle informatie op het scherm te verwerken. In de allereenvoudigste weergave (1 bit = 1 pixel) kan een pixel alleen ‘aan’ of ‘uit’ staan.
Een megapixel is gelijk aan 1 miljoen pixels. De resolutie van een digitale camera wordt vaak in megapixels aangegeven. Dit is dan de resolutie (of het aantal pixels) die de CCD- sensor aankan. Om het correcte aantal pixels te weten vermenigvuldig je het aantal horizontale lijnen met het aantal verticale lijnen van de digitale foto. Zo is dus een camera die een foto produceert met een resolutie van 1280 x 960 pixels een 1.3 megapixel camera en een 5 megapixels camera zal dan een foto produceren van 2560 x 1920 pixels.
Hoe meer pixels, hoe groter het “bestand”. Hoe meer pixels een afbeelding bevat, hoe meer informatie over de individuele kleuren moet bewaard worden. Om de bestandsgrootte in te perken kan men diverse compressietechnieken toepassen.
1. Een eerste manier bestaat erin om het aantal mogelijke kleurwaarden (de kleurdiepte) te beperken. Een GIF-afbeelding bijvoorbeeld kan maar 256 verschillende kleurwaarden bevatten voor alle kleuren samen. Dit betekent dat een GIF-afbeelding relatief klein is in bestandsomvang, maar ook niet meteen een geschikt formaat voor het bewaren van afbeeldingen waarin het aantal kleuren echt wel van belang is, zoals bijvoorbeeld een foto van een gezicht of een schilderij. In zekere zin bevatten alle digitale afbeeldingen een vorm van “compressie”, omdat ze het aantal kleuren in de werkelijkheid altijd op één of andere manier “beperken”. Toch zal een afbeelding met een kleurdiepte van 16-bit (tov. 8 bit bij RGB-kleuren) of 24-bit veel meer ruimte innemen omdat ze veel meer kleurencombinaties mogelijk maakt. Dat wil daarom nog niet zeggen dat alle afbeeldingen sowieso even groot zijn. Een foto van een grasveld zal bijvoorbeeld minder “plaats” in nemen op een opslagmedium dan de foto van een schilderij van Pieter Paul Rubens.
2. Ten tweede kan je ook het aantal pixels reduceren. Je kan met beeldbewerkingssoftware het aantal pixels verlagen. Zo kan je een afbeelding van 1920 pixels breedte verlagen naar bijvoorbeeld 300 pixels. Deze techniek wordt vaak toegepast bij het klaarstomen van afbeeldingen voor het gebruik op internet. Ook het aantal pixels per inch kan verlaagd worden (dpi of dots per inch). Voor drukwerk heb je afbeeldingen nodig van 300 dpi, voor internet volstaan afbeeldingen met een resolutie van 72 dpi. Het aantal pixels of dpi verhogen is eveneens mogelijk, maar dit betekent niet dat de kwaliteit van de afbeelding groter wordt. De software voegt dan kunstmatig pixels toe door bepaalde pixels te verdubbelen. Verloren informatie kan echter niet worden “toegevoegd”. In politieseries op TV zie je bijvoorbeeld hoe men een “duidelijk” beeld tevoorschijn tovert uit een lageresolutiebeeld van een digitale camera. Dit kan in feite niet.
3. Tenslotte kan men ook met wiskundige algoritmes afbeeldingen comprimeren. Afbeeldingsbestanden kunnen op diverse manieren bewaard worden. TIFF, jpg, gif, png... zijn bekende bestandsformaten voor pixelafbeeldingen. Ze hebben allemaal hun specifieke doeleinden alsook voor- en nadelen. Een TIFF-afbeelding kan zonder compressie worden bewaard, d.w.z. dat alle pixelinformatie en alle informatie over de kleuren behouden blijft in het bestand. Uiteraard zorgt dit ervoor dat een TIFF-bestand veel meer ruimte inneemt op een opslagmedium.
Bij andere afbeeldingsformaten past de gebruikte digitale camera of software een compressiealgoritme toe. In zo goed als alle gevallen betekent dit dat bepaalde pixelinformatie verloren gaat en nadien ook niet meer kan worden toegevoegd.
Een voorbeeld van een compressie-algoritme:
'Het menselijk oog is gevoeliger voor helderheid dan voor kleur. Om op een onzichtbare manier informatie te verwijderen is het de bedoeling dat we minder informatie aan kleur opslaan dan aan helderheid.' Bij een JPG-afbeelding worden op die manier heel wat kleurverschilen weggelaten. Simpel voorgesteld: een jpeg verdeelt een afbeelding in een raster waarbij gemiddelde waardes worden gemeten. Veel variatie in kleur wordt weggelaten. Hoe meer verschillen weggelaten worden, hoe groter de compressie.
Ongetwijfeld heb je al gehoord van beeldbewerkingssoftware zoals Adobe Photoshop of het open source GIMP (www.gimp.org). Met software kan je heel eenvoudige bewerkingen uitvoeren op pixelafbeeldingen, maar ook heel geavanceerde waarbij je software gebruikt om composities te bouwen door verschillende lagen pixels “boven” elkaar te plaatsen. Met beeldbewerkingssoftware kan je allerlei bewerkingen doen op individuele pixels of op groepen pixels in een afbeelding.
Hogerop heb je reeds gezien dat een pixelafbeelding bestaat uit een aantal pixels.
Elke pixel krijgt binnen een matrix een unieke positie op basis van zijn x- en y-waarde in die “tabel”.
Elke pixel heeft een kleurwaarde. In beeldbewerkingssoftware kan je op basis van de positie van elke pixel een bepaalde “actie” uitvoeren. Een “gom” in Adobe Photoshop zal bijvoorbeeld de positie van de muiscursor vergelijken met die van de pixels waarboven de muis zich bevindt en vervolgens de kleurwaarde van die pixels vervangen door “wit”. Als je de “digitale gom” groter maakt, zal Photoshop niet alleen de pixel onder de muiscursor wit maken, maar ook alles in een straal daar rond.
Machines begrijpen niet welke informatie in een foto staat. Ze herkennen geen koe, zon, huis of mens.
Toch kan je via de website www.tineye.com zoeken op welke plaatsen op het internet een bepaalde foto reeds eerder is gepubliceerd. Ook een “deel” van een afbeelding volstaat om ze terug te vinden in de mazen van het wereldwijde web. De mobiele versie van Google kan streepjescodes, merknamen, schilderijen enz. herkennen en u op basis daarvan de gewenste zoekresultaten tonen. Google Picasa herkent gezichten en kan zelfs de daaraan gekoppelde “personen” herkennen, eens je aan een gezicht een naam verbindt. De machines van de Belgische firma BEST kunnen dankzij de beeldherkenningschip van de Leuvense firma EASICS in een hels tempo producten herkennen. Ze filteren tegen een gigantische snelheid frieten en muizenketels uit krenten, of schroeven uit paperclips. Slimme camera's herkennen gezochte boeven, en digitale politiecamera's herkennen nummerplaten. Op luchthavens “zoeken” camera's naar verdachte gedragingen van aanwezigen. Big Brother is watching you. Hoe gebeurt zulke “beeldherkenning” (image recognition)?
Op de manier waarop beeldherkenning of “patroonherkenning” werkt, is geen eenduidig en al zeker geen “eenvoudig” antwoord te geven. Moderne image recognition-algoritmes werken vaak angstaanjagend goed, maar niet feilloos.
Image recognition stoot op een hele reeks problemen die niet eenvoudig te overbruggen zijn. Zelfs firma's die zich reeds jaren op de ontwikkeling van zulke algoritmes toeleggen, stuiten nog steeds op het probleem dat hun “tools” niet feilloos en 100% betrouwbaar werken. Menselijke controle of bijsturing is in veel gevallen nog steeds noodzakelijk.
Stel dat we een stuk software willen schrijven dat “gezichten” herkent in een afbeelding. Begrijp het niet verkeerd: de software herkent gezichten, maar niet de namen of personen die er aan verbonden zijn. Voor een mens is het duidelijk wat een gezicht is, maar het is niettemin moeilijk om er een definitie op te plakken die je in een herkenbare formule voor een machine zou kunnen gieten. We stuiten al snel op een definitie-probleem:
Een gezicht bevat een neus, twee ogen en een mond... maar hoe definieer je die individuele onderdelen (feature detection)?
De onderlinge verhouding en positie van die “onderdelen” is misschien belangrijker. Maar wat te doen als de machine enkel het zijprofiel van het gezicht te zien krijgt? Herkent de software dan nog steeds een “gezicht”? Wat met “Piet Piraat” als hij een ooglapje draagt? Is een smiley ook een gezicht? Vaak “traint” men de software met een trainingsset, waarbij de software zo is geprogrammeerd (met neurale netwerken) dat hij “kan leren” (eventueel met de hulp van een mens) of hij nu echt een gezicht heeft gevonden of niet. De software leert dan bij en onthoudt, net zoals een kind dat woordjes moet leren lezen.
Bovendien kan een afbeelding een gezicht in close-up tonen, of een groepsfoto met meerdere gezichten. Hier stuiten we op het probleem van “schaling-invariantie”. Hoe vertel je een machine dat hij zowel “kleine” als “grote” gezichten in een afbeelding moet herkennen? Sommige algoritmes kunnen met dit probleem van schaling overweg, maar de handigste manier om dit probleem te omzeilen is door te zorgen voor een “gecontroleerde omgeving”.
Een voorbeeld: als je een camera in een straat hangt, kan je hem zo plaatsen dat de gezicht van alle mensen die voorbij de lens wandelen steeds ongeveer even groot zijn. Op die manier voorkom je het schalingsprobleem. 's Nachts gaat de camera problemen ondervinden met het herkennen van “gezichten” omdat de geregistreerde pixels de “donker” zijn. Er is namelijk te weinig contrast tussen de gezichten en de omgeving. Een goed verlichte inkomhal is dus een beter te “controleren” omgeving dan een plaats in open lucht, waar de camera niet alleen te leiden heeft onder verschillen in belichting, maar ook onder regen, stof en wind.
Het mag duidelijk zijn dat er nog een verre weg is af te leggen vooraleer machines en software in staat zijn om met het gemak van menselijke intelligentie patronen zoals gezichten, huizen, dieren, groenten, fruit enz. te herkennen in een pixelbeeld van de omgeving.
Vectorafbeeldingen bestaan uit losse of gecombineerde geometrische vormen die met een kleur, verlooptint of 'afbeelding' worden gevuld.
Een cirkel zou je kunnen omschrijven op de volgende manier:
fill(0,0,255);
ellipse(200, 200, 100, 100);
De vulling van de cirkel wordt uitgedrukt in een RGB-waarde. De kleur van de cirkel is dus “blauw”. De instructie ellipse() bevat een viertal parameters. De eerste paar waarden behandelen de x- en de y-positie t.o.v. het programmavenster. De twee volgende waarden bepalen hoe groot de “horizontale” en de “verticale” straal moet zijn. Maak je die beide waarden gelijk, dan teken je een perfecte cirkel, maak je de ene waarde groter dan de andere, dan teken je een ellips.
Omdat enkel de coördinaten en de vormen en vullingen dienen opgeslagen te worden, blijven de bestanden uiterst klein. Een groot voordeel aan vectorafbeeldingen is dat zij oneindig kunnen geschaald worden zonder kwaliteitsverlies. Om de bovenstaande “ellips” te vergroten, moet je enkel de waardes aanpassen:
fill(0,0,255);
ellipse(200, 200, 10000, 10000);
Lettertypes zijn over het algemeen eveneens vectorieel. Door deze voordelen zijn vectorafbeeldingen uitermate geschikt voor logo's, maar niet voor “foto's”.
Vectortekenprogramma's:
Adobe Illustrator (commercieel)
Adobe Flash (commercieel, vectoranimatie)
CorelDraw (commercieel)
Processing (open source, vectoranimatie)
Raphael.js (open source, weergave van vectoren in webpagina's)
Xara (commercieel, open source en gratis versie)
Inkscape (open source en gratis)
Anders dan bij bitmapafbeeldingen die uit beeldpunten of pixels bestaan, bestaan er voor vectorafbeeldingen weinig algemeen ondersteunde opslagformaten. Het W3C heeft een internationale XML-standaard voor vectorafbeeldingen ontwikkeld onder de naam SVG (scalable vector graphics).
1Merckx, K.. Niet van gisteren, Leuven, 2013.
2RGB, (nl.wikipedia.org), geraadpleegd op 20 oktober 2014.
3http://www.rapidtables.com/web/color/RGB_Color.htm, geraadpleegd op 4/11/2014.