Filtros de imágenes por convolución de matrices con open cv
Un filtro de imagen es un procedimiento que se aplica a una imagen para resaltar o mejorar algunas características de la misma, para lograr esto se modifica la matriz que compone la imagen aplicándole un determinado procedimiento, en este tutorial estudiaremos el procedimiento llamado convolución de matrices.
Convolución de matrices en OpenCV
OpenCV cuenta con gran variedad de función que aplican los distintos filtros más comunes, estos filtros ya los hemos visto en cursos previos, en esta ocasión utilizaremos la función
Lo primero debemos saber es que para crear un filtro requerimos una matriz de convolución o kernel, esta será una matriz cuadrada cuyos tamaños normalmente son: 3x3, 5x5, 7x7, etc., dependiendo del filtro que deseemos aplicar, esta matriz será usada para calcular el valor de cada pixel de la imagen resultante, a la matriz de convolución se le asigna un punto de anclaje que normalmente se ubica en el centro, este es un ejemplo de una matriz de convolución o kernel.
Para calcular el valor de un pixel tomamos los elementos vecinos al mismo y creamos una ventana de igual tamaño que la matriz de convolución, luego multiplicamos las matrices elemento por elemento y sumamos los resultados para obtener el pixel deseado, normalmente el que se ubica en el centro.
Otra cosa que debemos saber es que tenemos que definir como manejaremos los bordes de la matriz, por ejemplo, para calcular el valor del pixel en la posición (0, 0) la ventana de convolución sobresale de la matriz, mira la imagen:
En OpenCV la enumeración
Existen más tipos de bordes que podemos utilizar, te queda de tarea explorar los demás.
Esta función usa tres parámetros adicionales, en nuestro ejemplo no los utilizamos, ellos son: anchor: define la posición de anclaje por defecto es el centro del kernel, delta: indica un valor que se sumará al filtro, por defecto es cero, por ultimo, borderType: indica el tipo de borde por defecto se usa BORDER_DEFAULT.
cv::filter2D(...)
que nos permitirá implementar nuestro propio filtro.Lo primero debemos saber es que para crear un filtro requerimos una matriz de convolución o kernel, esta será una matriz cuadrada cuyos tamaños normalmente son: 3x3, 5x5, 7x7, etc., dependiendo del filtro que deseemos aplicar, esta matriz será usada para calcular el valor de cada pixel de la imagen resultante, a la matriz de convolución se le asigna un punto de anclaje que normalmente se ubica en el centro, este es un ejemplo de una matriz de convolución o kernel.
Para calcular el valor de un pixel tomamos los elementos vecinos al mismo y creamos una ventana de igual tamaño que la matriz de convolución, luego multiplicamos las matrices elemento por elemento y sumamos los resultados para obtener el pixel deseado, normalmente el que se ubica en el centro.
Otra cosa que debemos saber es que tenemos que definir como manejaremos los bordes de la matriz, por ejemplo, para calcular el valor del pixel en la posición (0, 0) la ventana de convolución sobresale de la matriz, mira la imagen:
En OpenCV la enumeración
cv::BorderTypes
define las opciones que tenemos disponibles, podemos utilizar la función copyMakeBorder()
para ver los distintos tipos de bordes, esta función agrega un borde del tipo indicado a una imagen, debemos indicar las dimensiones del bordes en cada una de sus lados correspondientes, para nuestro ejemplo todos son iguales.int dim = 20;
Mat border_w, border_r;
copyMakeBorder(src, border_w, dim, dim, dim, dim, cv::BorderTypes::BORDER_WRAP);
copyMakeBorder(src, border_r, dim, dim, dim, dim, cv::BorderTypes::BORDER_REPLICATE);
Existen más tipos de bordes que podemos utilizar, te queda de tarea explorar los demás.
Filtro de imágenes en OpenCV
Con esto ya tenemos los conocimientos necesarios para aplicar filtros a nuestras imágenes en OpenCV, esta biblioteca nos facilita la tarea con la funcióncv::filter2D()
diseñada para tal propósito, si deseas trabajar directamente sobre los pixeles puedes ver el tutorial acceso a los pixeles de un Mat, si usamos la función antes mencionada solo debemos indicar como mínimo la imagen de entrada, la de salida y el kernel.#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
String imagen = "../../../opencv-3.2.0/samples/data/lena.jpg";
Mat src = imread(imagen, CV_LOAD_IMAGE_GRAYSCALE);
if (src.empty()) {
cout << "No se ha podido leer la imagen: " << imagen << endl;
}
Mat dst;
Mat kernel = (Mat_<char>(3, 3) << 0, 1, 0,
1, -4, 1,
0, 1, 0);
cv::filter2D(src, dst, src.depth(), kernel);
imshow("Display Image", src);
imshow("Display Filter2D", dst);
waitKey(0);
return 0;
}
Mat kernel = (Mat_<char>(3, 3) << -2, -1, 0,
-1, 1, 1,
0, 1, 2);
cv::filter2D(src, dst, src.depth(), kernel);
Esta función usa tres parámetros adicionales, en nuestro ejemplo no los utilizamos, ellos son: anchor: define la posición de anclaje por defecto es el centro del kernel, delta: indica un valor que se sumará al filtro, por defecto es cero, por ultimo, borderType: indica el tipo de borde por defecto se usa BORDER_DEFAULT.
0 comentarios:
Publicar un comentario