OpenCV Operaciones Morfológicas

Las dos operaciones morfológicas básicas son la erosión y la dilatación, a partir de estas se pueden aplicar las operaciones de apertura y cierre, estas operaciones son usualmente utilizadas para eliminar ruido en imágenes binarias.

Para realizar una operación morfológica de erosión o dilatación con OpenCV requerimos un elemento estructurante, el resultado de la operación dependerá de la forma y tamaño de este elemento, para generarlo en OpenCV usamos la función cv::getStructuringElement(MORPH_RECT, Size(5, 5)) donde el primer parámetro define la forma, puede ser: MORPH_RECT, MORPH_CROSS y MORPH_ELLIPSE, el segundo parámetro define el tamaño.

Elemento estructural para operación morfológicas

En la imagen podemos ver la matriz usada como elemento estructural en sus tres formas diferentes, todas son de tamaño 3x3 pero lo podemos cambiar si deseamos.

Dilatación

Al aplicar esta operación sobre una imagen obtendremos el efecto de expandir o ampliar la región de la imagen que estemos trabajando, para aplicar la operación de dilatación con OpenCV usaremos la función cv::dilate(src, dst, kernel).

OpenCV operación de dilatación (dilate)

Obtuvimos este resultado con el siguiente código:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv )
{
    Mat src, dst, kernel; 

    src = cv::imread("../tutor.png", CV_LOAD_IMAGE_COLOR);
    kernel = cv::getStructuringElement(MORPH_RECT, Size(5, 5));

    cv::dilate(src, dst, kernel);

    cv::imshow("Original", src);
    cv::imshow("Dilatacion", dst);

    cv::waitKey(0);

    return 0;
}

Puedes variar la forma y tamaño del elemento estructurante para observar los distintos resultados que puedes obtener al realizar la dilatación.

Erosión

Al aplicar la operación morfológica de erosión obtenemos el efecto de adelgazamiento del área que compone la imagen, podemos verlo como el inverso de la dilatación, para aplicar esta operación con OpenCV usaremos la función cv::erode(src, dst, kernel).

OpenCV aplicando erosión (erode)

El código para obtener esta imagen es el siguiente:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv )
{
    Mat src, dst, kernel; 

    src = cv::imread("../tutor.png", CV_LOAD_IMAGE_COLOR);
    kernel = cv::getStructuringElement(MORPH_ELLIPSE, Size(3, 3));

    cv::erode(src, dst, kernel);

    cv::imshow("Original", src);
    cv::imshow("Erosion", dst);

    cv::waitKey(0);

    return 0;
}

Al igual que, con la operación anterior, te recomiendo variar el tamaño y forma del elemento estructurante para poder apreciar los distintos resultados.

Gradiente

Esta operación es equivalente a la diferencia entre las operaciones de dilatación y erosión, esta operación es bastante útil cunado deseamos buscar la silueta de una figura.

OpenCV MORPH_GRADIENT para detectar silueta

Para aplicar esta operación no disponemos de una función en especifico, pero podemos usar la función cv::morphologyEx(...) que nos permite aplicar varias operaciones morfológicas, incluso la erosión y la dilatación.

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;

int main(int argc, char** argv )
{
    Mat src, dst, kernel; 

    src = cv::imread("../ave.jpg", CV_LOAD_IMAGE_COLOR);
    kernel = cv::getStructuringElement(MORPH_ELLIPSE, Size(3, 3));

    cv::morphologyEx(src, dst, MORPH_GRADIENT, kernel);

    cv::imshow("Original", src);
    cv::imshow("Gridiente", dst);

    cv::waitKey(0);

    return 0;
}

Para indicar la operación que deseamos aplicar usamos la enumeración cv::MorphTypes en este caso MORPH_GRADIENT, otras opciones son: MORPH_ERODE, MORPH_DILATE, MORPH_OPEN, MORPH_CLOSE, MORPH_TOPHAT, MORPH_BLACKHAT, MORPH_HITMISS.

Apertura y Cierre

Estas operaciones morfológicas las utilizamos comúnmente para la eliminación de ruido y simplificación de formas, entre otras cosas.

La operación de apertura es el resultado de aplicar una erosión y después una dilatación, nos servirá para eliminar ruido que se encuentre fuera de la estructura, para aplicarla usaremos MORPH_OPEN.

Mat src, dst, kernel; 

src = cv::imread("../ave-open.jpg", CV_LOAD_IMAGE_GRAYSCALE);
kernel = cv::getStructuringElement(MORPH_ELLIPSE, Size(3, 3));

cv::morphologyEx(src, dst, MORPH_OPEN, kernel);

cv::imshow("Original", src);
cv::imshow("Apertura", dst);

Operación morfológica de apertura con OpenCV

Podemos aumentar el tamaño del elemento estructurante para eliminar marcas de ruido mas grandes, también podemos  cambiar el número de iteraciones.

La operación de cierre se obtiene aplicando una dilatación y luego una erosión, el inverso del anterior, nos servirá para limpiar la figura, es decir eliminar el ruido interno de la misma, la aplicamos usando MORPH_CLOSE de la siguiente manera.

Mat src, dst, kernel; 

src = cv::imread("../ave-close.jpg", CV_LOAD_IMAGE_GRAYSCALE);
kernel = cv::getStructuringElement(MORPH_RECT, Size(3, 3));

cv::morphologyEx(src, dst, MORPH_CLOSE, kernel);

cv::imshow("Original", src);
cv::imshow("Cierre", dst);

Operación morfológica de cierre con OpenCV

Aun existen otras operaciones morfológicas disponibles en la enumeración cv::MorphTypes puedes probar cada una de ellas y ver los resultados que obtienes.

Esta operaciones son muy útiles ya que en muchas situaciones la funciones OpenCV nos devolverán una imagen binaria que por lo general tendrá ruido, por ejemplo, al detectar un objeto por color, en ese momento aplicaremos lo aprendido para obtener el área deseada.

Descargar: opencv-operaciones-morfológicas.zip

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Procesamiento de imágenes en OpenCV

Acceso a la webcam con OpenCV

Conociendo la clase cv::Mat de OpenCV