Acentuar Color

En este tutorial OpenCV creamos el efecto acentuar color, el mismo busca resaltar el área de una imagen que contenga un color indicado, las demás áreas son rellenadas con colores grises.

Para obtener de manera más fácil el color que deseamos resaltar cambiamos el formato de color de BGR a HSV donde nos enfocaremos un únicamente en la componente H (hue) que almacena el color.

Usaremos la siguiente ecuación para calcular los valores mínimos y máximos aceptados, los valores que se encuentren dentro de este rango serán procesados como un color válido (no cambian su color), los demás serán convertidos a escala de grises.

acentuar color opencv
La variable h establece el color que deseamos acentuar y r establece en rango de valores aceptable.

Lo primero que haremos será convertir la imagen a HSV, crear el cv::Mat para almacenar el resultado, debe ser del mismo tamaño y tipo que la imagen original, y finalmente calcularemos los valores h1 y h2.

cvtColor(src, hsv, CV_BGR2HSV);

int channels = src.channels();
int nRows = src.rows;
int nCols = src.cols * channels;

dst.create(src.rows, src.cols, src.type());

uchar h1 = (h - (r / 2) + 360) % 360;
uchar h2 = (h + (r / 2) + 360) % 360;

El siguiente paso es recorrer cada uno de los píxel de la imagen, por cada uno, tomamos el valor de la componente H y lo comparamos con el rango calculado, si el color esta fuera del rango convertimos a escala de grises, en caso contrario mantenemos en color.

for (int i = 0; i < nRows; i++) {
    ptr_dst = dst.ptr<uchar>(i); 
    ptr_src = src.ptr<uchar>(i);
    ptr_hsv = hsv.ptr<uchar>(i);

    for (int j = 0; j < nCols; j += 3) {
        in_range_color = false;

        // obtener el valor hue (H)
        uchar H = ptr_hsv[j];

        // verificar si se encuantra en el rango indicado
        if (h1 <= h2) {
            if (H >= h1 && H <= h2)
                in_range_color = true;
        }
        else if (H >= h1 || H <= h2)
            in_range_color = true;

        // si esta en el rango conservar el color
        // en caso contrario convertir a grises
        if (in_range_color == true) {
            ptr_dst[j + 0] = ptr_src[j + 0];
            ptr_dst[j + 1] = ptr_src[j + 1];
            ptr_dst[j + 2] = ptr_src[j + 2];
        }
        else {
            // conversion a grises usando usando en metodo de promedio
            uchar gray = (ptr_src[j] + ptr_src[j + 1] + ptr_src[j + 2]) / 3;
            ptr_dst[j + 2] = ptr_dst[j + 1] = ptr_dst[j] = gray;
        }
    }
}

Para terminar la aplicación creamos un par de trackbar, el primero para cambiar el valor h y el segundo para el valor r, cada vez que se produzca un cambio en cualquiera de estos dos valores actualizamos la imagen.

opencv_acentuar_color
Si deseamos ser más precisos en la detección del color podemos también comparar las componentes S y V, podemos utilizar la función cv::inRange, como lo hicimos en el tutorial: seguimiento de objeto por color para ser más precisos.

GitHub: Acentuar Color OpenCV

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Conociendo la clase cv::Mat de OpenCV

Procesamiento de imágenes en OpenCV

Acceso a la webcam con OpenCV