OpenCV Uso de las funciones Split y Merge

La librería OpenCV cuenta con un par de funciones muy útiles que nos servirán de mucho a la hora de crear aplicaciones que requieran aplicar técnicas de visión por computador, hablamos de las funciones cv::split() y cv::merge(), la primera nos ayudará a dividir y obtener los distintos canales que componen una imagen y la segunda nos permite unirlos nuevamente.

Una imagen digital a color usualmente esta compuesta por tres canales de información, para un espacio de color RGB tendremos los siguientes canales, (R)Rojo, (G)Verde y (B)Azul, lo que veremos en este tutorial son las funciones que nos proporciona OpenCV para poder extraer y fundir estos canales, puedes tener un poco más de información en: https://es.wikipedia.org/wiki/Canal_(imagen_digital)

La función cv::split(...)

Ella nos permitirá obtener todos los canales que componen una imagen a color, luego podremos acceder individualmente a cada uno de ellos, por ejemplo:

std::vector<Mat> channels;
cv::split(image, channels);

Para obtener el canal rojo channels[2], recordemos que OpenCV almacena por defecto los canales en el siguiente orden BGR por lo que el índice 2 corresponde a R, también recordemos que podemos cambiar el espacio de color con la siguiente función cv::cvtColor(image, image, CV_BGR2RGB), donde CV_BGR2RGB indica que deseamos convertir de BGR a RGB.

Vemos un código C/C++ de ejemplo:

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

using namespace cv;
using namespace std;

int main(int argc, char** argv )
{
     Mat image = imread("rgb.png", CV_LOAD_IMAGE_COLOR);

     imshow("Imagen Original", image);

 std::vector<Mat> channels;
 split(image, channels);

 Mat zero = Mat::zeros(image.size(), CV_8UC1);

 std::vector<Mat> B = { channels[0], zero, zero };
 std::vector<Mat> G = { zero, channels[1], zero };
 std::vector<Mat> R = { zero, zero, channels[2] };

 Mat rdst, gdst, bdst;

 merge(R, rdst);
 merge(G, gdst);
 merge(B, bdst);

 imshow("R Channel", rdst);
 imshow("G Channel", gdst);
 imshow("B Channel", bdst);

     waitKey(0);
     return 0;
}

La imagen original es la siguiente:

OpenCV split y merge

Separamos los canales BGR usando cv::split(...) como lo vimos previamente.

La función cv::merge(...)

Esta nos servirá para hacer lo contrario, es decir, unir un conjunto de canales en una sola imagen, en este caso la usaremos para mostrar cada uno de los canales individualmente, para ello tomaremos el canal que nos interesa y los demás los dejaremos en cero, de este modo podemos mostrar este canal en una ventana, por ejemplo:

Mat zero = Mat::zeros(image.size(), CV_8UC1);

std::vector<Mat> B = { channels[0], zero, zero };
std::vector<Mat> G = { zero, channels[1], zero };
std::vector<Mat> R = { zero, zero, channels[2] };

Mat rdst, gdst, bdst;

merge(R, rdst);
merge(G, gdst);
merge(B, bdst);

Como vemos primero creamos un objeto Mat rellenado con ceros, del mismo tamaño de la imagen original y de un solo canal.

Para obtener una imagen con el canal que nos interesa creamos un vector<Mat> con tres elementos, tomamos el canal que deseemos visualizar y dejamos los demás a cero.

imagen BGR

Estos son los objetos rdst, bdst y gdst, respectivamente, extraídos de la imagen superior.

extraer canales RGB

Es todo por ahora, espero les sea de ayuda.

Comentarios

Temas relacionados

Entradas populares de este blog

tkinter Grid

Conectar SQL Server con Java

Controles y Contenedores JavaFX 8 - I

Histogramas OpenCV Python