Title: Bildverarbeitungsalgorithmen Gesamtwiederholung
1BildverarbeitungsalgorithmenGesamtwiederholung
- Manfred Thaller, Universität zu Köln
- Köln 29. Januar 2008
2I. Bildverarbeitung
Bearbeitung von Bildern, die als strukturierter
Bytestream im Memory geladen sind.
3Basisalgorithmus Bildverarbeitung
Unter Annahme eines Bildes als struct image
int zeilen int spalten unsigned char
bytes o for (i0ilto.spalteni) for
(j0jlto.zeilenj) transform(
(o.bytes (jspalten) i) )
4Basisalgorithmus Bildverarbeitung
Oder allgemeiner struct image int
zeilen int spalten pixel pixel
o for (i0ilto.spalteni) for
(j0jlto.zeilenj) transform(
(o.pixel (jspalten) i) )
5Basisalgorithmus Bildverarbeitung
Eingebunden in den Kontext von Qt (i.e.,
QImage) Beispiel Negation 8 Bit for (int
y0yltimage-gtheight()y) for (int
x0xltimage-gtwidth()x)
oldVal (image-gtscanLine(y) x)
newVal255-oldVal
(image-gtscanLine(y) x) newVal
6Basisalgorithmus Bildverarbeitung
Eingebunden in den Kontext von Qt (i.e.,
QImage) Beispiel Negation 24 Bit for (int
y0yltimage-gtheight()y) for (int
x0xltimage-gtwidth()x) RGB(QRgb
)image-gtscanLine(y) x oldRed
qRed(RGB) newRed255-oldRed
oldGreen qGreen(RGB)
newGreen255-oldGreen oldBlue
qBlue(RGB) newBlue255-oldBlue
RGB qRgb(newRed,newGreen,newBlue)
7Basisalgorithmus Bildverarbeitung
Dabei gilt jedoch for (int y0yltresult.height()
y) for (int x0xltresult.width()x)
(result.scanLine(y) x)
meineTransformation((image.scanLine(y))
Etwa eine Größenordnung langsamer als
8Basisalgorithmus Bildverarbeitung
for (int y0yltresult.height()y)
newpixelresult.scanLine(y)
oldpixelimage.scanLine(y) for (int
x0xltresult.width()x)
(newpixel) meineTransformation((
oldpixel))
9Basisalgorithmus Bildverarbeitung
Merke Bildverarbeitung muss performant sein!
10Basistransformationen
Negation oldVal (image-gtscanLine(y)
x) newVal255-oldVal (image-gtscanLine(y) x)
newVal
11Basistransformationen
Horizontale Spiegelung for (int
y0yltimage-gtheight()y) for (int
target0,sourceimage-gtwidth()-1
targetltlimittarget,source--)
pixel(image-gtscanLine(y) source)
(image-gtscanLine(y) source)
(image-gtscanLine(y)
target) (image-gtscanLine(y)
target) pixel
12Basistransformationen
Vertikale Spiegelung for (int
target0,sourceimage-gtheight()-1
targetltlimittarget,source--) for (int
x0xltimage-gtwidth()x)
pixel(image-gtscanLine(source) x)
(image-gtscanLine(source) x)
(image-gtscanLine(target) x)
(image-gtscanLine(target) x) pixel
13Basistransformationen
Farbbandextraktion (Qt spezifisch, lookup
table) for (int y0yltimage-gtheight()y)
for (int x0xltimage-gtwidth()x)
RGBvalimage-gtcolorTable()
(image-gtscanLine(y) x)
pixelqRed(RGBval)
(result.scanLine(y) x) pixel
14Basistransformationen
Quadrantenrotation for (int oldy0,newximage-gth
eight()-1oldyltimage-gtheight()
oldy,newx--) for (int oldx0,newy0oldxlt
image-gtwidth()
oldx,newy)
(result.scanLine(newy) newx)
(image-gtscanLine(oldy) oldx)
15Basistransformationen
Gradgenaue Rotation for (int y0yltimage-gtheight
()y) himage-gtheight()-y for
(int x0xltimage-gtwidth()x)
rhosqrt((double)(xx)(double)(hh))
thetaatan((double)h/(double)x)-usearc
newx(int)rint(rhocos(theta)xmin)
newyysize-((int)rint(rhosin(theta)ymin))
(inter(newyxsize)newx) (image-gtscanLine(y
) x)
16Basistransformationen
Nachgeschobene Interpolation zur
Rotation offset0 -1 offset1 1
offset2 xsize-1 offset3 xsize for (int
y0yltresult.height()y) for (int
x0xltresult.width()x,use) if
(usegt0) (result.scanLine(y)x) use
else if ((use-1)lt0 (use1)lt0)
(result.scanLine(y)x) 0 else
(result.scanLine(y)x)
(useoffsetnow) if (now4)
now0
17Lookuptable Transformationen
Intensitätsmodifikation table8new unsigned
int256 for (int i0ilt256i)
newpixelivalue if (newpixel lt
0)newpixel0 else if (newpixelgt255)
newpixel255 table8inewpixel
resultTIlookup(image,(void )table8) delete
table8
18Lookuptable Transformationen
Wobei gilt TIlookup for (int
y0yltimage.height()y) for (int
x0xltimage.width()x)
(result.scanLine(y) x)
table8(image.scanLine(y) x)
19Lookuptable Transformationen
Wobei gilt TIlookup for (int
y0yltimage.height()y) for (int
x0xltimage.width()x)
(result.scanLine(y) x)
table8(image.scanLine(y) x)
20Lookuptable Transformationen
Davon abgeleitet Winkeltransformation (Beispiel
cosinus) arcfactorM_PI/180.0 cosfactor255.0/2.
0 table8new unsigned int256 for (int
i0ilt256i) table8i(int)rint((cos((do
uble)iarcfactor)1.0)cosfactor) resultTIlooku
p(image,(void )table8) delete table8
21Lookuptable Transformationen
Davon abgeleitet Reduktion auf
Helligkeitsausschnitt factor(float)256.0/(high-l
ow1) table8new unsigned int256 steplow fo
r (int i0ilt256i) table8i(int)step
if (steplt255.0) stepfactor
if (stepgt255.0) step255.0
resultTIlookup(image,(void
)table8) delete table8
22Lookuptable Transformationen
Histogramm errechnen histo8 new unsigned
int256 for (int i0 ilt256 i) histo8i
0 for (int y0yltimage.height()y) for
(int x0xltimage.width()x)
histo8(image.scanLine(y) x)
23Lookuptable Transformationen
Davon abgeleitet auch Standardkontrastausgleich 1
/ 2 histo8 (unsigned int)TIhistogram(image)
totalimage.width() image.height() limit(int)(
total0.05) for (low0,i0lowltlimiti)
lowhisto8i lowi for (high0,i255highltlimi
ti--) highhisto8i highi
24Lookuptable Transformationen
Davon abgeleitet auch Standardkontrastausgleich 2
/ 2 factor13.0/low for (i0,step0.0iltlowi
) histo8i(int)step
stepfactor factor230.0/(high-low) for
(step13.0ilthigh1i)
histo8i(int)step stepfactor
factor13.0/(256-high) for (step243.0ilt256i
) histo8i(int)step
stepfactor return TIlookup(image,(void
)histo8)
25Lookuptable Transformationen
Davon abgeleitet auch Standardkontrastausgleich 2
/ 2 factor13.0/low for (i0,step0.0iltlowi
) histo8i(int)step
stepfactor factor230.0/(high-low) for
(step13.0ilthigh1i)
histo8i(int)step stepfactor
factor13.0/(256-high) for (step243.0ilt256i
) histo8i(int)step
stepfactor return TIlookup(image,(void
)histo8)
26Lookuptable Transformationen
Verwandt damit Table-basierter Zoom factor
(float) zoom / (float)image.width() xtablenew
intresult.width() ytablenew
intresult.height() for (int newy0newyltresult.
height()newy) ytablenewy (int)(newy /
factor) for (int newx0newxltresult.width()newx
) xtablenewx (int)(newx / factor) for
(int newy0newyltresult.height()newy)
newpixelresult.scanLine(newy)
oldbaseimage.scanLine(ytablenewy) for
(int newx0newxltresult.width()newx)
(newpixel) (oldbase xtablenewx)
27Lookuptable Transformationen
NB Interpolierender Zoom wird realisiert durch
komplexeren Aufbau der Lookuptables.
28Nachbarschaftstransformationen
Basisvorgehen for (int y1yltresult.height()-1y
) baselineimage.scanLine(y)
for (int x1xltresult.width()-1x)
(result.scanLine(y) x)
TIneighbour8(image,x,type,baseline)
29Nachbarschaftstransformationen
Beispiel für eine Nachbarschaftstransformation s
tatic int Xoffset -1, 0, 1, -1, 0, 1, -1,
0, 1 static int Yoffset -1, -1, -1, 0, 0,
0, 1, 1, 1 widthimage.width() switch(action)
case TINMinimum result255 for (int
i0i lt 9 i) candidate (baseline
(widthYoffseti) x Xoffseti) if
(candidate lt result) resultcandidate
break
30Nachbarschaftstransformationen
Hervorheben von Intensitätsänderungen X
Differenz for (int y0yltresult.height()y)
for (int x1xltresult.width()x)
collect (image.scanLine(y) x)
(image.scanLine(y) x-1)
(result.scanLine(y) x)
(collectlt0) ? collect -1 collect
31Nachbarschaftstransformationen
NB Partielle Transformationen können in Bilder
eingeschrieben werden Übergangsbetonung durch
Einrechnen XY Differenz step1TIcontrastS(TIXYdi
fference(image)) for (int y0yltresult.height()
y) for (int x0xltresult.width()x)
(result.scanLine(y) x)
((step1.scanLine(y) x) gt 128) ? 0
(image.scanLine(y) x)
32Filteroperationen Nachbarschaften
Auf der operativen nicht mathematischen Ebene
können Filter als multiplikative
Nachbarschaftstransformationen verstanden werden.
33Filteroperationen Nachbarschaften
Filteranwendung 1 / 2 static int filter49
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 divisor4
9,5,1,1 unsigned char baseline for (int
y1yltresult.height()-1y) baselineimage.scan
Line(y) for (int x1xltresult.width()-1x
) (result.scanLine(y) x)
TIfilter8(image,x,filtertype,divisortype
,baseline)
34Filteroperationen Nachbarschaften
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 widthimage.width() collect0 for (int
i0i lt 9 i) collect (baseline
(widthYoffseti) x Xoffseti)
filteri result collect / divisor
35Filter
Dementsprechend, die wichtigsten Filter static
int filter159 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
divisor15 9,5,1,1,16,6,1,1,3,1,1,1,1,1,1 st
atic int absolute15 0,0,0,0,0,0,0,0,0,-1,-1,-
1,-1,-1,-1
36Transformationen des Fourier Typs
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.
37Transformationen des Fourier Typs
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.
38Transformationen des Fourier Typs
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.
39Transformationen des Fourier Typs
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
40Transformationen des Fourier Typs
(1) Fouriertransformationen sind voll umkehrbar
41Transformationen des Fourier Typs
(2) Transformierte Bilder können zielgerichtet
bearbeitet werden
42Transformationen des Fourier Typs
(2) Transformierte Bilder bestehen üblicherweise
aus überwiegend sehr viel kleineren Zahlenwerten
43II. Bildspeicherung und Kompression
Techniken zum Transfer von Bytestreams aus der
linearen Form (Platte) in strukturierte Form
(Memory).
44Binäres Lesen (Qt flavour)
Lesen imageFile.seek(ifd_addr) imageFile.read(
(char )buffer,n) Schreiben imageFile.seek(ifd
_addr) imageFile.write((char )buffer,n) Posit
ion merken ifdstart imageFile.pos()
45Komprimieren
Run Length Encoding while(line gt 0) c
(source) if (c lt 0) count c
-1 1 memset(target, source, count)
source else count c
1 memcpy(target, source, count)
source count line - count
target count
46Komprimieren
CCITT / Huffmann Encoding (bitonal) 1 /
3 while(gottenltheader-gtwidth) if
((runlengthTIfetchrun(ccitt,buffer,0,err))lt0)
goto cleanup memset(target,usecolor0,runl
ength) targetrunlength
gottenrunlength if (gottengtheader-gtwidth
) break if ((runlengthTIfetchrun(ccitt,bu
ffer,1,err))lt0) goto cleanup
memset(target,usecolor1,runlength)
targetrunlength gottenrunlength
47Komprimieren
CCITT / Huffmann Encoding (bitonal) 2 / 3
48Komprimieren
CCITT / Huffmann Encoding (bitonal) 3 / 3
49Komprimieren
Lempel-Ziv Welch (LZW) 1 / 2 InitializeStringTa
ble() WriteCode(ClearCode) W the empty
string for each character in the strip K
GetNextCharacter() if WK is in the
string table W WK / string
concatenation / else WriteCode
(CodeFromString(W)) AddTableEntry(WK)
W K WriteCode (CodeFromString(W)) W
riteCode (EndOfInformation)
50Komprimieren
Lempel-Ziv Welch (LZW) 2 / 2 static int
shifts48 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-gtlzwbits gtgt 3 if (use gtmax)
return TiffLZWEOI raw (rasteruse ltlt 8)
(rasteruse 1) if (lzw-gtlzwcsgt9) raw
(rawltlt8) (rasteruse 2) raw gtgt
shiftslzw-gtlzwcs-9lzw-gtlzwbits
8 lzw-gtlzwbits lzw-gtlzwcs return
(rawlzw-gtlzwmask)
51Komprimieren
- JPEG
- Sechs Schritte zum s/w JPEG Image
- In Blöcke gruppieren Zentrieren um Null.
- DCT jedes Blocks.
- Elimieren einiger Werte durch "quantization".
- 8 x 8 Blöcke ? lineare Sequenz, per Entropy
Encoding. - Run length encoding.
- Huffman encoding.
- Vor diesen Schritten im 24 Bit Fall
- Transformation RGB ? YCbCr.
52Schöne Ferien!