Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Bildverarbeitungsalgorithmen Gesamtwiederholung Manfred Thaller, Universität zu Köln Köln 29. Januar 2008.

Ähnliche Präsentationen


Präsentation zum Thema: "Bildverarbeitungsalgorithmen Gesamtwiederholung Manfred Thaller, Universität zu Köln Köln 29. Januar 2008."—  Präsentation transkript:

1 Bildverarbeitungsalgorithmen Gesamtwiederholung Manfred Thaller, Universität zu Köln Köln 29. Januar 2008

2 I. Bildverarbeitung 2 Bearbeitung von Bildern, die als strukturierter Bytestream im Memory geladen sind.

3 Basisalgorithmus Bildverarbeitung 3 Unter Annahme eines Bildes als: struct image { int zeilen; int spalten; unsigned char *bytes; } o; for (i=0;i<o.spalten;i++) for (j=0;j<o.zeilen;j++) transform(* (o.bytes + (j*spalten) + i) );

4 Basisalgorithmus Bildverarbeitung 4 Oder allgemeiner: struct image { int zeilen; int spalten; pixel *pixel; } o; for (i=0;i<o.spalten;i++) for (j=0;j<o.zeilen;j++) transform(* (o.pixel + (j*spalten) + i) );

5 Basisalgorithmus Bildverarbeitung 5 Eingebunden in den Kontext von Qt (i.e., QImage): Beispiel: Negation 8 Bit for (int y=0;y height();y++) for (int x=0;x width();x++) { oldVal = *(image->scanLine(y) + x); newVal=255-oldVal; *(image->scanLine(y) + x) = newVal; }

6 Basisalgorithmus Bildverarbeitung 6 Eingebunden in den Kontext von Qt (i.e., QImage): Beispiel: Negation 24 Bit for (int y=0;y height();y++) for (int x=0;x width();x++) { RGB=(QRgb *)image->scanLine(y) + x; oldRed = qRed(*RGB); newRed=255-oldRed; oldGreen = qGreen(*RGB); newGreen=255-oldGreen; oldBlue = qBlue(*RGB); newBlue=255-oldBlue; *RGB = qRgb(newRed,newGreen,newBlue); }

7 Basisalgorithmus Bildverarbeitung 7 Dabei gilt jedoch: for (int y=0;y<result.height();y++) { for (int x=0;x<result.width();x++) { *(result.scanLine(y) + x) = meineTransformation(*(image.scanLine(y)) ; } Etwa eine Größenordnung langsamer als:

8 Basisalgorithmus Bildverarbeitung 8 for (int y=0;y<result.height();y++) { newpixel=result.scanLine(y); oldpixel=image.scanLine(y); for (int x=0;x<result.width();x++) *(newpixel++) = meineTransformation(*(oldpixel++)); }

9 Basisalgorithmus Bildverarbeitung 9 Merke: Bildverarbeitung muss performant sein!

10 Basistransformationen 10 Negation: oldVal = *(image->scanLine(y) + x); newVal=255-oldVal; *(image->scanLine(y) + x) = newVal;

11 Basistransformationen 11 Horizontale Spiegelung: for (int y=0;y height();y++) for (int target=0,source=image->width()-1; target<limit;target++,source--) { pixel=*(image->scanLine(y) + source); *(image->scanLine(y) + source) = *(image->scanLine(y) + target); *(image->scanLine(y) + target) = pixel; }

12 Basistransformationen 12 Vertikale Spiegelung: for (int target=0,source=image->height()-1; target<limit;target++,source--) for (int x=0;x width();x++) { pixel=*(image->scanLine(source) + x); *(image->scanLine(source) + x) = *(image->scanLine(target) + x); *(image->scanLine(target) + x) = pixel; }

13 Basistransformationen 13 Farbbandextraktion (Qt spezifisch, lookup table): for (int y=0;y height();y++) for (int x=0;x width();x++) { RGBval=image->colorTable() [*(image->scanLine(y) + x)]; pixel=qRed(RGBval); *(result.scanLine(y) + x) = pixel; }

14 Basistransformationen 14 Quadrantenrotation: for (int oldy=0,newx=image->height()-1;oldy height(); oldy++,newx--) for (int oldx=0,newy=0;oldx width(); oldx++,newy++) *(result.scanLine(newy) + newx) = *(image->scanLine(oldy) + oldx);

15 Basistransformationen 15 Gradgenaue Rotation: for (int y=0;y height();y++) { h=image->height()-y; for (int x=0;x width();x++) { rho=sqrt((double)(x*x)+(double)(h*h)); theta=atan((double)h/(double)x)-usearc; newx=(int)rint(rho*cos(theta)+xmin); newy=ysize-((int)rint(rho*sin(theta)+ymin)); *(inter+(newy*xsize)+newx)= *(image->scanLine(y) + x); }

16 Basistransformationen 16 Nachgeschobene Interpolation zur Rotation: offset[0]= -1; offset[1]= 1; offset[2]= xsize*-1; offset[3]= xsize; for (int y=0;y<result.height();y++) { for (int x=0;x<result.width();x++,use++) { if (*use>=0) *(result.scanLine(y)+x) = *use; else if (*(use-1)<0 || *(use+1)<0) *(result.scanLine(y)+x) = 0; else { *(result.scanLine(y)+x) = *(use+offset[now]); if (++now==4) now=0; }

17 Lookuptable Transformationen 17 Intensitätsmodifikation: table8=new unsigned int[256]; for (int i=0;i<256;i++) { newpixel=i+value; if (newpixel < 0)newpixel=0; else if (newpixel>255) newpixel=255; table8[i]=newpixel; } result=TIlookup(image,(void *)table8); delete table8;

18 Lookuptable Transformationen 18 Wobei gilt TIlookup ==: for (int y=0;y<image.height();y++) for (int x=0;x<image.width();x++) *(result.scanLine(y) + x) = table8[*(image.scanLine(y) + x)];

19 Lookuptable Transformationen 19 Wobei gilt TIlookup ==: for (int y=0;y<image.height();y++) for (int x=0;x<image.width();x++) *(result.scanLine(y) + x) = table8[*(image.scanLine(y) + x)];

20 Lookuptable Transformationen 20 Davon abgeleitet: Winkeltransformation (Beispiel cosinus) arcfactor=M_PI/180.0; cosfactor=255.0/2.0; table8=new unsigned int[256]; for (int i=0;i<256;i++) table8[i]=(int)rint((cos((double)i*arcfactor)+1.0)*cosfactor); result=TIlookup(image,(void *)table8); delete table8;

21 Lookuptable Transformationen 21 Davon abgeleitet: Reduktion auf Helligkeitsausschnitt factor=(float)256.0/(high-low+1); table8=new unsigned int[256]; step=low; for (int i=0;i<256;i++) { table8[i]=(int)step; if (step<255.0) { step+=factor; if (step>255.0) step=255.0; } } result=TIlookup(image,(void *)table8); delete table8;

22 Lookuptable Transformationen 22 Histogramm errechnen: histo8 = new unsigned int[256]; for (int i=0; i<256; i++) histo8[i] = 0; for (int y=0;y<image.height();y++) for (int x=0;x<image.width();x++) histo8[*(image.scanLine(y) + x)]++;

23 Lookuptable Transformationen 23 Davon abgeleitet auch Standardkontrastausgleich 1 / 2: histo8 = (unsigned int*)TIhistogram(image); total=image.width() * image.height(); limit=(int)(total*0.05); for (low=0,i=0;low<limit;i++) low+=histo8[i]; low=i; for (high=0,i=255;high<limit;i--) high+=histo8[i]; high=i;

24 Lookuptable Transformationen 24 Davon abgeleitet auch Standardkontrastausgleich 2 / 2: factor=13.0/low; for (i=0,step=0.0;i<low;i++) { histo8[i]=(int)step; step+=factor; } factor=230.0/(high-low); for (step=13.0;i<high+1;i++) { histo8[i]=(int)step; step+=factor; } factor=13.0/(256-high); for (step=243.0;i<256;i++) { histo8[i]=(int)step; step+=factor; } return TIlookup(image,(void *)histo8);

25 Lookuptable Transformationen 25 Davon abgeleitet auch Standardkontrastausgleich 2 / 2: factor=13.0/low; for (i=0,step=0.0;i<low;i++) { histo8[i]=(int)step; step+=factor; } factor=230.0/(high-low); for (step=13.0;i<high+1;i++) { histo8[i]=(int)step; step+=factor; } factor=13.0/(256-high); for (step=243.0;i<256;i++) { histo8[i]=(int)step; step+=factor; } return TIlookup(image,(void *)histo8);

26 Lookuptable Transformationen 26 Verwandt damit: Table-basierter Zoom: factor = (float) zoom / (float)image.width(); xtable=new int[result.width()]; ytable=new int[result.height()]; for (int newy=0;newy<result.height();newy++) ytable[newy] = (int)(newy / factor); for (int newx=0;newx<result.width();newx++) xtable[newx] = (int)(newx / factor); for (int newy=0;newy<result.height();newy++) { newpixel=result.scanLine(newy); oldbase=image.scanLine(ytable[newy]); for (int newx=0;newx<result.width();newx++) *(newpixel++) = *(oldbase + xtable[newx]); }

27 Lookuptable Transformationen 27 NB: Interpolierender Zoom wird realisiert durch komplexeren Aufbau der Lookuptables.

28 Nachbarschaftstransformationen 28 Basisvorgehen: for (int y=1;y<result.height()-1;y++) { baseline=image.scanLine(y); for (int x=1;x<result.width()-1;x++) *(result.scanLine(y) + x) = TIneighbour8(image,x,type,baseline); }

29 Nachbarschaftstransformationen 29 Beispiel für eine Nachbarschaftstransformation: static int Xoffset[] = { -1, 0, 1, -1, 0, 1, -1, 0, 1}; static int Yoffset[] = { -1, -1, -1, 0, 0, 0, 1, 1, 1}; width=image.width(); switch(action) { case TINMinimum: result=255; for (int i=0;i < 9; i++) { candidate = *(baseline + (width*Yoffset[i]) + x + Xoffset[i]); if (candidate < result) result=candidate; } break;

30 Nachbarschaftstransformationen 30 Hervorheben von Intensitätsänderungen – X Differenz for (int y=0;y<result.height();y++) for (int x=1;x<result.width();x++) { collect = *(image.scanLine(y) + x) – *(image.scanLine(y) + x-1); *(result.scanLine(y) + x) = (collect<0) ? collect * -1 : collect; }

31 Nachbarschaftstransformationen 31 NB: Partielle Transformationen können in Bilder eingeschrieben werden – Übergangsbetonung durch Einrechnen XY Differenz: step1=TIcontrastS(TIXYdifference(image)); for (int y=0;y<result.height();y++) for (int x=0;x<result.width();x++) *(result.scanLine(y) + x) = (*(step1.scanLine(y) + x) >= 128) ? 0 : *(image.scanLine(y) + x);

32 Filteroperationen : Nachbarschaften 32 Auf der operativen – nicht mathematischen – Ebene können Filter als multiplikative Nachbarschaftstransformationen verstanden werden.

33 Filteroperationen : Nachbarschaften 33 Filteranwendung 1 / 2: static int filter[4][9]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 = low pass 1 */ 0, 1, 0, 1, 1, 1, 0, 1, 0, /* 1 = low pass 2 */ 0,-1, 0,-1, 5,-1, 0,-1, 0, /* 2 = high pass 1 */ -1,-1,-1,-1, 9,-1,-1,-1,-1 /* 3 = high pass 2 */ }; static int divisor[4] = {9,5,1,1}; unsigned char *baseline; for (int y=1;y<result.height()-1;y++) { baseline=image.scanLine(y); for (int x=1;x<result.width()-1;x++) *(result.scanLine(y) + x) = TIfilter8(image,x,filter[type],divisor[type],baseline);

34 Filteroperationen : Nachbarschaften 34 Wobei gilt (Filteranwendung 2 / 2): int Xoffset[] = { -1, 0, 1, -1, 0, 1, -1, 0, 1}; int Yoffset[] = { -1, -1, -1, 0, 0, 0, 1, 1, 1}; width=image.width(); collect=0; for (int i=0;i < 9; i++) collect += *(baseline + (width*Yoffset[i]) + x + Xoffset[i]) *filter[i]; result = collect / divisor;

35 Filter: 35 Dementsprechend, die wichtigsten Filter: static int filter[15][9]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 = low pass 1 */ 0, 1, 0, 1, 1, 1, 0, 1, 0, /* 1 = low pass 2 */ 0,-1, 0,-1, 5,-1, 0,-1, 0, /* 2 = high pass 1 */ -1,-1,-1,-1, 9,-1,-1,-1,-1, /* 3 = high pass 2 */ 1, 2, 1, 2, 4, 2, 1, 2, 1, /* 4 = W.Mean 1 */ 0, 1, 0, 1, 2, 1, 0, 1, 0, /* 5 = W.Mean 2 */ 0, 1, 0, 1,-4, 1, 0, 1, 0, /* 6 = Laplace 1 */ -1,-1,-1,-1, 8,-1,-1,-1,-1, /* 7 = Laplace 2 */ 0,-1, 0,-1, 7,-1, 0,-1, 0, /* 8 = Laplace 3 */ -1,-1,-1, 0, 0, 0, 1, 1, 1, /* 9 = Prewitt A */ -1, 0, 0, 0, 0, 0, 0, 0, 1, /* 10 = Roberts A */ -1,-2,-1, 0, 0, 0, 1, 2, 1, /* 11 = Sobel A */ 1, 0,-1, 1, 0,-1, 1, 0,-1, /* 12 = Prewitt B */ 0, 0,-1, 0, 0, 0, 1, 0, 0, /* 13 = Roberts B */ -1, 0, 1,-2, 0, 2,-1, 0, 1 /* 14 = Sobel B */ }; static int divisor[15] = {9,5,1,1,16,6,1,1,3,1,1,1,1,1,1}; static int absolute[15] = {0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1};

36 Transformationen des Fourier Typs 36 Prinzip: Die Zuordnung von Helligkeitswerten zu Punkten wird durch eine andere geometrisch / mathematische Interpretation derselben numerischen Werte ersetzt. Fourier: Die räumliche Verteilung von Helligkeitswerten kann durch eine Bündelung von Frequenzwerten ersetzt werden.

37 Transformationen des Fourier Typs 37 Beispielsweise ist leicht nachvollziehbar, dass im Bild jede Zeile des Bildes auch als eine Schwingung verstanden werden kann, deren hohe Amplitude besonders hell, deren niedrige besonders dunkel ist.

38 Transformationen des Fourier Typs 38 Wenn dies so ist, kann dieses Bild offensichtlich durch Angabe der Schwingungsdauer und der Amplitude dargestellt werden. Wird dies weitergedacht, kann man konzeptuell jeden Punkt eines Punktes dadurch beschreiben, dass man behauptet, das Bild von n x m Pixeln stelle n x m Schwingungen dar, von denen jede an genau einem der Pixel jene Ausprägung der Amplitude habe, die dem Helligkeitswert dieses Pixels entspräche.

39 Transformationen des Fourier Typs 39 Fouriertransformationen sind relativ anspruchsvoll effektiv zu optimieren; wurden deshalb während des Semesters NICHT im Quellcode besprochen. Sie sind aber EXTREM wichtig. Wichtig ist, folgende Eigenschaften festzuhalten:

40 Transformationen des Fourier Typs 40 (1) Fouriertransformationen sind voll umkehrbar:

41 Transformationen des Fourier Typs 41 (2) Transformierte Bilder können zielgerichtet bearbeitet werden:

42 Transformationen des Fourier Typs 42 (2) Transformierte Bilder bestehen üblicherweise aus überwiegend sehr viel kleineren Zahlenwerten:

43 II. Bildspeicherung und Kompression 43 Techniken zum Transfer von Bytestreams aus der linearen Form (Platte) in strukturierte Form (Memory).

44 Binäres Lesen (Qt flavour) 44 Lesen imageFile.seek(ifd_addr); imageFile.read((char *)buffer,n); Schreiben imageFile.seek(ifd_addr); imageFile.write((char *)buffer,n); Position merken ifdstart = imageFile.pos();

45 Komprimieren 45 Run Length Encoding while(line > 0) { c = *(source)++; if (c < 0) { count = c * -1 + 1; memset(target, *source, count); source++; } else { count = c + 1; memcpy(target, source, count); source += count; } line -= count; target += count; }

46 Komprimieren 46 CCITT / Huffmann Encoding (bitonal) 1 / 3 while(gotten width) { if ((runlength=TIfetchrun(&ccitt,buffer,0,&err))<0) goto cleanup; memset(target,usecolor[0],runlength); target+=runlength; gotten+=runlength; if (gotten>=header->width) break; if ((runlength=TIfetchrun(&ccitt,buffer,1,&err))<0) goto cleanup; memset(target,usecolor[1],runlength); target+=runlength; gotten+=runlength; }

47 Komprimieren 47 CCITT / Huffmann Encoding (bitonal) 2 / 3

48 Komprimieren 48 CCITT / Huffmann Encoding (bitonal) 3 / 3

49 Komprimieren 49 Lempel-Ziv & Welch (LZW) 1 / 2 InitializeStringTable(); WriteCode(ClearCode); W = the empty string; for each character in the strip { K = GetNextCharacter(); if W+K is in the string table { W = W+K; /* string concatenation */ } else { WriteCode (CodeFromString(W)); AddTableEntry(W+K); W = K; } WriteCode (CodeFromString(W)); WriteCode (EndOfInformation);

50 Komprimieren 50 Lempel-Ziv & Welch (LZW) 2 / 2 static int shifts[4][8] = { 7, 6, 5, 4, 3, 2, 1, 0, 14, 13, 12, 11, 10, 9, 8, 7, 13, 12, 11, 10, 9, 8, 7, 6, 12, 11, 10, 9, 8, 7, 6, 5 }; int raw, use; use = lzw->lzwbits >> 3; if (use >=max) return TiffLZWEOI; raw = (raster[use] << 8) + (raster[use + 1]); if (lzw->lzwcs>9) raw= (raw<<8) + (raster[use + 2]); raw >>= shifts[lzw->lzwcs-9][lzw->lzwbits % 8]; lzw->lzwbits += lzw->lzwcs; return (raw&lzw->lzwmask);

51 Komprimieren 51 JPEG Sechs Schritte zum s/w JPEG Image 1.In Blöcke gruppieren; Zentrieren um Null. 2.DCT jedes Blocks. 3.Elimieren einiger Werte durch "quantization". 4.8 x 8 Blöcke lineare Sequenz, per Entropy Encoding. 5.Run length encoding. 6.Huffman encoding. Vor diesen Schritten im 24 Bit Fall: Transformation RGB YCbCr.

52 52 Schöne Ferien!


Herunterladen ppt "Bildverarbeitungsalgorithmen Gesamtwiederholung Manfred Thaller, Universität zu Köln Köln 29. Januar 2008."

Ähnliche Präsentationen


Google-Anzeigen