Module-2.1-Color-Spaces.pdf
Table of Contents
Color
Spaces
Why do
we need different color spaces?
The RGB
color space
The HSV
color space
Applications
Find the
dominant colors in an image
What is
a Histogram?
Plotting
Histograms using OpenCV
Histogram
Code & Tutorial
Desaturation
Filter
Desaturation
Code and Tutorial
The
YCrCb color space
Applications
The Lab
color space
Application
- Color Transfer between images
Color
Transfer Code and Tutorial
References
and Further Reading
En
este modulo, se describen los espacios de color RGB, HSV, YCrCb y Lab, las
ventajas y fundamentos de cada uno. Se
introduce el concepto de Histograma, la desaturación y la transferencia de
color.
El
programa colorTransfer usa la función hconcat() de OpenCV que exige que las
matrices tengan la misma altura, en caso contrario genera error. (Una solución
para usar cualquier archivo como base, es borrar o comentar” // o /* */” estas funciones y mostrar cada imagen
individualmente.
Module-2.2-Image-Enhancement.pdf
Table of Contents
Brightness
Adjustment
Brightness
Enhancement Code and Tutorial
Contrast
Adjustment
Intensity
Scaling
Contrast
Adjustment using Scaling Code and Tutorial
Histogram
Equalization
Contrast
Adjustment using Histogram Equalization Code and Tutorial
Will
Histogram Equalization make all my pictures beautiful?
Gamma
Correction or Power Law Transform
Gamma
Adjustment Code and Tutorial
Color
Tone Adjustment using Curves
Warming
Filter Code and Tutorial
Cooling
Filter Code and Tutorial
References
and Further Reading
En este módulo, se explica cómo
ajustar el brillo de una imagen mediante un método aditivo, es decir sumando o
restando una cantidad fija a todos los pixeles de la imagen consiguiendo de
esta manera aclarar o oscurecer una imagen.
También se explica el ajuste del
contraste, mediante dos métodos:
Escalando la intensidad de los
pixeles, que hace que los pixeles más luminosos aumenten su valor más que los
pixeles más oscuros, aumentando así su diferencia relativa y su contraste.
El segundo método emplea el ajuste
de contraste mediante la ecualización del histograma. Se discute el caso
desfavorable en que el histograma tenga una distribución con varios máximos.
Se explica la corrección gamma que
modifica la percepción lineal de los sensores de las cámaras para obtener una
respuesta más cercana a la del ojo humano.
Se explica el ajuste de los tonos
(canales del espacio de color, ejemplo R, G y B) usando una curva y se escribe
el código que hace la interpolación entre unos pocos valores característicos
para tener una LUT (tabla de respuesta, para todos los valores del rango,
usualmente 256 valores).
Como ejemplo de esta técnica, se
explica cómo modificar una imagen para conseguir tonos más cálidos o más fríos.
Module-2.3.1-Image-Filtering-Convolution-and-Blur.pdf
Table of Contents
Image Filtering 2
Signal Processing Jargon
2
What is
Image Filtering ? 3
Convolution 4
What is
convolution? 4
Convolution
Code & Tutorial 6
Blur 10
Blur
Code & Tutorial 10
Gaussian
Blur 12
Gaussian
Blur Code & Tutorial 13
Median
Blur 16
Median
Blur Code & Tutorial 18
Bilateral
Filtering 21
Bilateral
Filter Code & Tutorial 23
Bilateral
vs Median: Comparison under different noise conditions 26
Salt-And-Pepper
Noise 26
Gaussian
Noise 26
Excessive smoothing 27
References and Further Reading 28
En este módulo,
entramos en el mundo de procesamiento de imágenes, concretamente en los filtros
de imagen. Se explican los conceptos generales de los filtros y se explica la
aplicación práctica mediante una convolución (o correlación), la creación de un
“kernel” con todos sus elementos iguales y su utilización en un filtro general
mediante la función filter2D() de OpenCV.
Se presenta la
función Blur(), que hace el mismo filtro anterior directamente y suaviza y
desenfoca la imagen que es procesada.
Se explica la
función GaussianBlur() que tiene aplicaciones importantes para remover
determinados tipos de ruido y para preparar la imagen para procesamientos
futuros.
El filtro
medianBlur() de OpenCV, que sustituye el pixel “ancla” por la mediana de los
pixeles abarcados por el “kernel”, está especialmente indicado para remover el
ruido llamado de “sal y pimienta”.
El filtro
bilateralFilter() diseñado para preservar los bordes mientras reduce el ruido,
dándole más peso a los pixeles más cercanos al centro del “kernel” y consigue
remover el llamado ruido Gaussiano.
Module-2.3.2-Image-Filtering-Gradients.pdf
Table of Contents
Image
Gradients 2
Prewitt
Filter 3
Sobel
Filter 3
Magnitude
and Direction of Gradient 4
Gradient
Code & Tutorial 4
Second
Order Derivative Filters 8
Laplacian
Filter 8
Laplacian
of Gaussian Filter 9
Laplacian
and LoG Code & Tutorial 10
Image
Sharpening 14
Image Sharpening Code & Tutorial 15
References and Further Reading 18
En este módulo,
se presentan varios filtros que sirven para detectar cambios dentro de las
imágenes. Así el filtro Prewitt y el filtro Sobel() calculan las derivadas y a
partir de ellas es posible calcular la magnitud y la dirección del vector
gradiente.
Se estudian los
filtros basados en las derivadas de segundo orden, Laplacian() y Laplaciana de
Gaussiano “LoG”.
Se presenta el
kernel del filtro para enfocar las imágenes.
Module-2.3.3-Edge-Detection.pdf
Table of Contents
Edge Detection 2
Canny Edge Detection 2
Canny Edge Detection Code & Tutorial 3
Diving Deep into Canny Parameters 10
References and Further
Reading 10
En este módulo, esta
dedicado al algoritmo detector de bordes “Canny()”, explicando las fases para
su correcta aplicación:
El suavizado de
la imagen.
La supresión de
los gradientes no-máximos en el entorno del pixel considerado.
La histéresis,
representada por los parámetros, “lowThreshold” y “highThreshold”.
También se
incluye una explicación de los efectos en la detección de bordes que se derivan
de la alteración de los parámetros de la función Canny().
Module-2.4-Instagram-Filters.pdf
Table of Contents
Overview
Instagram Filters
Clarendon
Clarendon Filter Code and tutorial
Results
Kelvin
Kelvin Filter Code and tutorial
Results
Moon
Moon Filter Code and tutorial
Final
Results
X-Pro II
X-Pro II Filter Code and tutorial
Results
More photographic Filters
Pencil Sketch using Edge Detection
Pencil Sketch using Edge Detection Code and tutorial
Final Results
Pencil Sketch using Blending
Color Dodge Blending
Pencil Sketch using Color Dodge Blending Code and
tutorial
Final Results
Cartoon
Filter
Cartoon
Filter Code and tutorial
Final
Results
References and Further Reading
En este módulo,
se estudian los filtros “Instagram” y se desarrolla un programa que los recrea
en OpenCV, básicamente consiste en unas tablas LUT que se generan por interpolación
a partir de unos puntos en una curva para cada canal de color (rojo, verde,
azul) así se crea un filtro que modifica la imagen.
Tambien se
presentan otros filtros que tienen naturaleza diferente.
Module-2-Assignment.pdf
Table of Contents
Color Extraction 2
Make your own Instagram Filter
2
Implement the motion blur filter
3
Color
Extraction
I have modified a program from the OpenCV tutorials http://opencv-srf.blogspot.com.es/2010/09/object-detection-using-color-seperation.html,
that way I can use an image and display the color segmented on a window.
Figure . red extraction.
Figure . green extraction.
Figure . blue extraction.
Figure . yellow extraction.
Instagram
Filters
From the references and
further lectures, I knew than Charles
Perrault made an “Instructable” recreating around 20 instagram filters
using photoshop’s channel curves of adjustment layers.
Dr. Satya Mallick from
learnopencv.com wrote an OpenCV program recreating some of the filters.
The assignment asks to
recreate more filters, to do that,I have just changed in the Dr. Mallick’s
program kelvin.cpp with the arrays original*[] and *Curve[] (*=R,G,B,r,g,b)
that I will write below:
1: No-Filter
// Specifying the x-axis for mapping
float originalR[]
= {0, 31, 63, 95, 127, 159,191,255};
float
originalG[] = {0, 31, 63, 95, 127, 159,191,255};
float
originalB[] = {0, 31, 63, 95, 127, 159,191,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0, 31, 63, 95, 127, 159,191,255};
float gCurve[]
= {0, 31, 63, 95, 127, 159,191,255};
float bCurve[]
= {0, 31, 63, 95, 127, 159,191,255};
Figure. No-Filter
Filter
2: Amaro Filter
// Specifying the x-axis for mapping
float
originalR[] = {0, 30, 82, 128, 145, 255};
float
originalG[] = {0, 48, 115, 160, 233, 255};
float
originalB[] = {0, 35, 106, 151,240, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {19, 62, 148, 188, 200, 250};
float gCurve[]
= {0, 72, 188, 220,245, 255};
float bCurve[]
= {25, 80, 175, 188, 235, 255};
Figure. Amaro
Filter
3: Mayfair filter
// Specifying the x-axis for mapping
float
originalR[] = {0, 85, 125, 221, 254};
float
originalG[] = {0, 40, 80, 142, 188,255};
float
originalB[] = {0, 45, 85, 135, 182,235,255};
// Specifying
the y-axis for mapping
float rCurve[]=
{30, 110, 170, 232, 242};
float gCurve[]
= {15, 55, 95, 196, 215,230};
float bCurve[]
= {15,60,115,185,215,230,225};
Figure. Mayfair
Filter
4: Rise filter
// Specifying the x-axis for mapping
float
originalR[] = {0,30,130,170,233,255};
float
originalG[] = {0, 30, 65, 100, 152,210,255};
float
originalB[] = {0, 40, 120,175,220,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {25,70,192,200,233,255};
float gCurve[]
= {25,72,118,158,195,230,255};
float bCurve[]
= {33,75,162,188,214,255};
Figure. Rise
Filter
5: Hudson Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,42,85,124,170,215, 255};
float
originalG[] = {0,45,102,140,192, 255};
float
originalB[] = {0, 24,60,105,145,210,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {35,68,115,165,200,228,255};
float gCurve[]
= {0,60,135,182,215,255};
float bCurve[]
= {0,42,100,170,208,235,245};
Figure. Hudson
Filter
6: Valencia
// Specifying the x-axis for mapping
float
originalR[] = {0, 50,85,128,228,255};
float
originalG[] = {0, 18,60,104,148,212,255};
float
originalB[] = {0, 42,80,124,170,220,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {20,80,120,162,224,240};
float gCurve[]
= {0,12,70,128,178,224,255};
float bCurve[]
= {20,62,104,144,182,210,230};
Figure. Valencia
Filter
7: X-Pro II
// Specifying the x-axis for mapping
float
originalR[] = {0, 42,105,148,185,255};
float
originalG[] = {0, 40,85,125,165,212,255};
float
originalB[] = {0,40,82,125,170,235, 255};
// Specifying the y-axis for mapping
float rCurve[]
= {0,28,100,160,208,255};
float gCurve[]
= {0,25,75,130,180,230,255};
float bCurve[]
= {30,58,90,125,160,210,222};
Figure. X-ProII
Filter
7:X-Pro IIb (de acuerdo al Dr. Satya Mallick)
// Specifying the x-axis for mapping///////////
float
originalR[] = { 0 , 42 , 105 , 148 , 185 , 255 };
float
originalG[] = { 0 , 40 , 85 , 125 , 165 , 212 , 255 };
float
originalB[] = { 0 , 40 , 82 , 125 , 170 , 225 , 255 };
//
Specifying the y-axis for mapping
float
rCurve[] = { 0 , 28 , 100 , 165 , 215 , 255 };
float
gCurve[] = { 0 , 25 , 75 , 135 , 185 , 230 , 255 };
float
bCurve[] = { 0 , 38 , 90 , 125 , 160 , 210 , 222 };
Figure. X-ProIIb
Filter
8: Sierra
// Specifying the x-axis for mapping
float originalR[] = {0, 48,105,130,190,232,255};
float
originalG[] = {0, 38,85,124,172,218,255};
float
originalB[] = {0,45,95,138,176,210, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {10,88,155,180,212,234,245};
float gCurve[]
= {0,72,124,160,186,210,230};
float bCurve[]
= {30,82,132,164,182,200,218};
Figure. Sierra
Filter
9: Willow
// Specifying the x-axis for mapping
float
originalR[] = {0,68,95,175, 255};
float
originalG[] = {0,55,105,198, 255};
float
originalB[] = {0,40,112,195, 255};
// Specifying the y-axis for mapping
float rCurve[]
= {30,105,145,215,240};
float gCurve[]
= {30,85,160,210,230};
float bCurve[]
= {30,70,165,215,228};
Figure. Willow
Filter
10: Lo-Fi Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,40,88,128,170,230, 255};
float
originalG[] = {0,35,90,105,148,188, 255};
float
originalB[] = {0, 62,100,130,150,190,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0,20,80,150,200,245,255};
float gCurve[]
= {0,15,70,105,180,218,255};
float bCurve[]
= {0,50,95,155,182,220,255};
Figure. Lo-Fi
Filter
11: Early-bird
Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,45,85,120,230, 255};
float originalG[]
= {0,40,88,132,168,215, 255};
float
originalB[] = {0, 42,90,120,164,212,255};
// Specifying the y-axis for mapping
float rCurve[]
= {25,80,135,180,240,255};
float gCurve[]
= {0,55,112,172,198,218,240};
float bCurve[]
= {18,58,102,130,170,195,210};
Figure. Earlybird
Filter
12: Sutro Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,40,90,145,235, 255};
float
originalG[] = {0,62,155,210, 255};
float
originalB[] = {0, 80,128,182,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0,35,92,155,230,235};
float gCurve[]
= {0,50,140,188,225};
float bCurve[]
= {0,80,112,145,220};
Figure. Sutro
Filter
13: Toaster
Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,50,105,145,190, 255};
float originalG[] = {0,22,125, 255};
float
originalB[] = {0, 40,80,122,185,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {120,160,198,215,230,255};
float gCurve[]
= {0,60,180,255};
float bCurve[]
= {50,60,102,148,185,210};
Figure. Toaster
Filter
14: Brannan Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,40,125,175, 255};
float
originalG[] = {0,65,92,180, 255};
float
originalB[] = {0,62,88,132,225, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {35,50,165,230,255};
float gCurve[]
= {0,50,102,220,255};
float bCurve[]
= {35,62,95,158,230,232};
Figure. Brannan
Filter
15: Inkwell Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,60,168, 255};
float
originalG[] = {0, 40,85,122,170,255};
float
originalB[] = {0, 40,90,130,175,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0,75,218,255};
float gCurve[]
= {12,44,125,180,220,255};
float bCurve[]
= {35,78,140,188,215,245};
Figure. Inkwell
Filter
16: Walden Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,40,85,122,170, 255};
float
originalG[] = {0,40,90,130,175, 255};
float
originalB[] = {0,85,130,165, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {12,44,125,180,220,255};
float gCurve[]
= {35,78,140,188,215,245};
float bCurve[]
= {85,150,170,185,220};
Figure. Walden
Filter
17: Hefe Filter Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,60,130, 255};
float
originalG[] = {0,65,125, 255};
float
originalB[] = {0,65,125,170, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0,55,155,255};
float gCurve[]
= {0,40,125,255};
float bCurve[]
= {0,30,105,165,240};
Figure.
Hefe Filter
18: Nashville
Filter
// Specifying the x-axis for mapping
float
originalR[] = {0, 30,58,83,112,190,255};
float
originalG[] = {0, 20,50,132,190,255};
float
originalB[] = {0,40,85,212, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0,5,25,85,140,220,255};
float gCurve[]
= {0,5,62,150,205,225};
float bCurve[]
= {65,90,115,185,205};
Figure.
Nashville Filter
19: 1977 Filter
// Specifying the x-axis for mapping
float
originalR[] = {0,75,145,190, 255};
float
originalG[] = {0, 42,110,154,232,255};
float
originalB[] = {0, 65,108,175,210,255};
// Specifying
the y-axis for mapping
float rCurve[]
= {75,125,200,220,230};
float gCurve[]
= {52,54,120,168,235,242};
float bCurve[]
= {62,82,132,210,208,208};
Figure. 1977
Filter
20: Kelvin Filter
// Specifying the x-axis for mapping
float
originalR[] = {0, 60, 110, 150, 235, 255};
float
originalG[] = {0, 68, 105, 190, 255};
float
originalB[] = {0, 88, 145, 185, 255};
// Specifying
the y-axis for mapping
float rCurve[]
= {0, 102, 185, 220, 245, 245};
float gCurve[]
= {0, 68, 120, 220, 255};
float bCurve[]
= {0, 12, 140, 212, 255};
Figure. Kelvin Filter
Implement the motion blur filter
Horizontal Blur: I applied a kernel filter with values
in the central row equals to 1/filter.cols, I made a mask a little bigger than
Lena figure. This way, I blurred only Lena image.
Figure. Horizontal Blur.
Vertical Blur: I applied a kernel filter with values
in the central column equals to 1/filter.rows, I made a mask a little bigger
than Lena. This way, I blurred only Lena image.
Figure . Vertical Blur.
Inclinated Blur: I applied a kernel filter with values
equals to 1/filter.rows, in the line with the same slope that the figure, I
made a mask a little bigger than the car. This way, I blurred only the car
image.
Figure. Inclinated Blur.
Figure. Inclinated Blur Inverse.
Next, someone could write a program that will do dilation o
erosion interactive with the mask to tune it according to the size of the
kernel.
Hasta la proxima semana con el modulo 3.
No hay comentarios:
Publicar un comentario