domingo, 2 de julio de 2017

Module-2.1-Color-Spaces.pdf



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