OpenCV Restaurar Imagen

Inpainting es un proceso en el que se busca reconstruir partes dañadas de una imagen o video, también puede ser utilizado para remover textos u objetos de una imagen, esta función soporta dos métodos el primero llamado INPAINT_NS (Navier-Stokes) y el método INPAINT_TELEA propuesto por Alexandru Telea.

Esta pequeña aplicación que desarrollaremos intentara reparar o restaurar una imagen como la que se muestra en parte inferior de este párrafo, alguien que no tenía nada bueno que hacer a editado mi imagen y ha agregado la nubes que se encuentran en la parte inferior derecha.

baboon
Puedes encontrar un buen ejemplo de la función inpaint() en la carpeta: opencv\samples\cpp\inpaint.cpp

La función inpaint requiere que le indiquemos la imagen original y otra imagen donde indicamos que deseamos reparar (inpaintMask) además de otros parámetros, veamos la imagen mask requerida para restaurar esta imagen.

baboon-mask
Para obtener esta imagen usaremos la función OpenCV llamada floodfill() esta es utilizada para obtener un área que contiene todos los pixeles similares conectados a un pixel determinado por el usuario.

Este método es comúnmente utilizado por aplicaciones de edición de imágenes como GIMP, Paint y otros para seleccionar un grupo de pixeles del mismo color o parecidos, podemos encontró un ejemplo bastante completo de floodfill() en la carpeta opencv\samples\cpp\ffilldemo.cpp con este ejemplo tendremos una buena idea de cómo funciona y los distintos parámetros que pueden ser modificados.

opencv floodfill
En nuestra aplicación usaremos floofill() para obtener el grupo de pixeles que deseamos reparar y generar el inpaintMask, debemos hacer clic sobre una parte del área que deseamos restaurar, floodfill() seleccionara el área completa y además nos creara la imagen mask que requiere inpaint().

static void onMouse(int event, int x, int y, int, void*)
{
    if (event != EVENT_LBUTTONDOWN) return;

    Point seed = Point(x, y);

    int ffillMode = 1;
    int flags = connectivity + (newMaskVal << 8) + (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);
    int b = (unsigned)theRNG() & 255;
    int g = (unsigned)theRNG() & 255;
    int r = (unsigned)theRNG() & 255;
    int lo = 20, up = 20;

    Rect ccomp;
    Scalar newVal = Scalar(r * 0.299 + g * 0.587 + b * 0.114);

    Mat dst, mask, inpaint_mask;

    mask.create(image.rows + 2, image.cols + 2, CV_8UC1);
    mask = Scalar::all(0);

    floodFill(image, mask, seed, newVal, &ccomp,
        Scalar(lo, lo, lo),
        Scalar(up, up, up), flags);

    inpaint_mask = Mat(mask, Rect(1, 1, mask.cols - 2, mask.rows - 2));
    inpaint(image, inpaint_mask, dst, 3, INPAINT_NS);

    imshow("mask", mask);
    imshow("image", image);
    imshow("inpaint", dst);

    original.copyTo(image);
}

Establecemos un callback para manejar los eventos del ratón, al hacer clic usamos floodfill() para generar el inpaintMask, luego aplicamos la función inpaint() para restaurar la imagen.

Restauración de la imagen usando método INPAINT_NS.

floodfill inpaint opencv
A la izquierda se observa la imagen inpaintMask generada usando la función OpenCV floodfill(), en el centro la imagen original que deseamos restaurar, al hacer clic sobre la parte que deseamos restaurar floodfill() selecciona todos los pixeles conectados, el área seleccionada se pinta en color diferente para poder ver la selección y finalmente se ve la imagen restaurada con la otra función OpenCV que usamos en esta aplicación inpaint().

GitHub: Restaurar Imagen

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Detección de figuras geométricas