División de separación de canales OpenCV4 (), fusión de canales (fusión), mezcla de canales mixChannels ()

Directorio de artículos

La función imread predeterminada en opencv carga archivos de imagen, y la imagen cargada es una imagen en color de tres canales, el espacio de color es el espacio de color RGB y el orden de los canales es BGR (azul, verde, rojo). , OpenCV proporciona tres API. La función se utiliza para realizar la separación de canales split(), merge() y mixChannels();

Imagen RGB, en Mat de opencv, datos de píxeles, estructura de almacenamiento y separación de canales, el diagrama de relación de operación es el siguiente:

inserte la descripción de la imagen aquí

1. Función de separación de canales split()

Prototipo de función:

El uso de los dos prototipos de funciones es el mismo, y se utiliza para separar imágenes multicanal en varias imágenes de un solo canal. La diferencia entre los dos prototipos de funciones es que las imágenes separadas de un solo canal tipo Mat se almacenan en Mat -tipo matrices, Mat mvbegin[3]o Almacenado en un contenedor de vectores, vector <Mat> mv;

La función split() en OpenCV 4 tiene 2 prototipos sobrecargados:

(1) Prototipo de función 1: use una matriz de tipo Mat Mat mvbegin[3]para almacenar la imagen separada;

void split( const Mat &src, Mat *mvbegin )

Parámetros de entrada:
  • src: imagen a separar, matriz multicanal tipo Mat;
  • mvbegin: imagen de un solo canal de tipo Mat separada, almacenada en una matriz de tipo Mat, Mat mvbegin[3]al definir el tamaño de la matriz, debe saber la cantidad de canales de la imagen original, tamaño de la matriz = número de canales de la imagen original;
  • Las imágenes separadas se almacenan en una matriz de tipo Mat Mat mvbegin[3]. Los tres elementos de la matriz son matrices de tipo Mat con el tamaño de image.rows X image.cols, que almacenan los datos de los componentes B, G y R de la imagen original a su vez, y tome la matriz Los elementos dentro solo pueden ser []valorados por , no por at();

(2) Prototipo de función 2: use un contenedor de vectores vector <Mat>para almacenar imágenes separadas;

void split( InputArray m, OutputArrayOfArrays mv )

Parámetros de entrada:
  • m: imagen a separar, Matriz multicanal tipo Mat;
  • mv: Imagen monocanal separada tipo Mat, almacenada en un contenedor vectorial, vector <Mat> mvno necesita saber el número de canales de la imagen original;
  • La imagen separada se almacena en el contenedor vectorial. vector <Mat> mvHay 3 elementos en el contenedor mv, y el tamaño de cada elemento es una matriz tipo Mat de image.rows X image.cols, que almacena los componentes B, G y R de la imagen original a su vez Datos, cada elemento se puede obtener por []valor, o por at()valor;

(3) Ejemplo:

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	// 用Mat型数组,存储分离后的图像,只能用 [] 访问
	// Mat mvbegin[3];
	// split(src, mvbegin);
	// imshow("B", mvbegin[0]);
	// imshow("G", mvbegin[1]);
	// imshow("R", mvbegin[2]); 

	// 用vector容器,存储分离后的图像,用 [] 访问
	// vector<Mat> mv;
	// split(src, mv);
	// imshow("B", mv[0]);
	// imshow("G", mv[1]);
	// imshow("R", mv[2]);

	// 用vector容器,存储分离后的图像,用 at() 访问
	vector<Mat> mv;
	split(src, mv);
	imshow("B", mv.at(0));
	imshow("G", mv.at(1));
	imshow("R", mv.at(2));

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

2. Función de combinación de canales merge()

  • El uso de los dos prototipos de funciones es el mismo, que se utiliza para combinar varias imágenes (imágenes de un solo canal o de varios canales) en una imagen de varios canales. La diferencia entre los dos prototipos de funciones es que la entrada son los datos de la imagen. en forma de matriz Mat, Mat mvbegin[3]o datos de imagen en forma de contenedor vectorial vector <Mat>, que corresponde al prototipo de la función split();
  • La salida de la función de fusión es una imagen multicanal, y su número de canales es la suma del número de canales de todas las imágenes de entrada. Las imágenes utilizadas para la fusión no son todas de un solo canal, sino que también pueden ser multicanal. imágenes. El número de canales de la imagen de entrada puede ser diferente. Igual, pero requiere que todas las imágenes sean del mismo tamaño y tipo de datos;

Prototipo de función:

(1) Prototipo de función 1: la entrada son datos de imagen en forma de matriz MatMat mvbegin[3]

void merge( const Mat *mvbegin, size_tcount, OutputArray dst )

Parámetros de entrada:
  • mvbegin: imágenes de un solo canal o de varios canales que deben fusionarse, la entrada son datos de una imagen en forma de una matriz Mat mvbegin[3];
  • size_tcount: la longitud de la matriz de imágenes de entrada, su valor debe ser mayor que 0;
  • dst: imagen fusionada;

(2) Prototipo de función 2: la entrada son datos de imagen en forma de contenedor vectorialvector <Mat>

void merge( InputArrayOfArrays mv, OutputArray dst )

Parámetros de entrada:
  • mv: las imágenes de un solo canal o de varios canales que deben fusionarse. La entrada son datos de una imagen en forma de contenedor vectorial vector <Mat>, donde cada imagen debe tener el mismo tamaño y tipo de datos;
  • dst: la imagen fusionada mv[0]tiene el mismo tamaño y tipo de datos, y la cantidad de canales es igual a la suma de la cantidad de canales de todas las imágenes de entrada;

(3) Ejemplo 1: use split() para separar la imagen en tres canales, Mat mvbegin[3]almacene la imagen separada en una matriz tipo Mat y luego fusione las imágenes de tres canales con merge(), correspondiente al prototipo de función 1;

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);


	// 通道分离,用Mat型数组存储分离后的图像
	Mat mvbegin[3];
	split(src, mvbegin);
	Mat BlueChannel = mvbegin[0];
	Mat GreenChannel = mvbegin[1];
	Mat RedChannel = mvbegin[2];

	// 将R通道全部置0
	Mat r = mvbegin[2].clone();
	r.setTo(0);

	// 需要合并的Mat型数组 
	Mat newChannel[3] = {
    
     BlueChannel , GreenChannel , r };

	// 合并通道
	Mat dst;
	merge(newChannel, 3, dst);
	// 显示
	imshow("Merged", dst);

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

(4) Ejemplo 2: primero use split() para separar los tres canales de la imagen, use el contenedor de vectores para vector <Mat>almacenar la imagen separada y luego combine las imágenes de tres canales con merge(), correspondiente a la función prototipo 2;

#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);


	// 通道分离
	vector<Mat> mv;
	split(src, mv);
	Mat BlueChannel = mv.at(0);
	Mat GreenChannel = mv.at(1);
	Mat RedChannel = mv.at(2);

	// 将B通道全部置0
	Mat b = mv.at(0).clone();
	b.setTo(0);

	vector<Mat> newChannel;
	newChannel.push_back(b);
	newChannel.push_back(GreenChannel);
	newChannel.push_back(RedChannel);

	//通道合并
	Mat mergedImage;
	merge(newChannel, mergedImage);
	// 显示
	imshow("Merged", mergedImage);

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

3. Mezcla de canales mixChannels()

Prototipo de función:

(1) Prototipo de función uno:

void cv::mixChannels	(
	InputArrayOfArrays		src,
	InputOutputArrayOfArrays 	dst,
	const std::vector< int > 	&fromTo 
)
Parámetros de entrada:
  • src: matriz de entrada, todas las matrices deben tener el mismo tamaño y profundidad;
  • dst: matriz de salida, el tamaño y la profundidad deben ser los src[0]mismos que;
  • fromTo: par de índices, que indica en qué canal de la matriz de entrada se copia, en qué canal de la matriz de salida; por ejemplo: {
    0, 2, 1, 1, 2, 0 } significa:
    src color el canal 0 se copia en dst Color canal 2
    src color canal 1 copiado a dst color canal 1
    src color canal 2 copiado a dst color canal 0
    inserte la descripción de la imagen aquí

(2) Prototipo de función 2:

En este prototipo de función:

  • Si la matriz de entrada y la matriz de salida son ambas 1, entonces es consistente con el prototipo de la primera función;
  • Si no es 1, se pueden fusionar múltiples matrices, o una matriz se puede dividir en múltiples matrices u otras funciones;
void cv::mixChannels
(
	const Mat 	*src,
	size_t 		nsrcs,
	Mat		*dst,
	size_t	        ndsts,
	const int       *fromTo,
	size_t 		npairs 
)
Parámetros de entrada:
  • src: matriz de entrada, todas las matrices deben tener el mismo tamaño y profundidad;
  • ndsts: número de matrices;
  • dst: matriz de salida, el tamaño y la profundidad deben ser los src[0]mismos que;
  • fromTo: par de índices, que indica en qué canal de la matriz de entrada, copiado, en qué canal de la matriz de salida;
  • ndsts: número de matrices;
  • npairs: el número de pares de índices en fromTo;

(3) Ejemplo 1: Cambio de canal de color cian (255, 255, 0) amarillo (0, 255, 255)

El color cian (255, 255, 0) de la imagen original se copia en la imagen de salida a través del canal especificado y se vuelve amarillo (0, 255, 255);

Canal de correspondencia:

El significado del par de índices from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 }:

  • Canal 0 de bg, copiado al canal 2 de out[], es decir, canal 0 de bgr;
  • Canal 1 de bgra, copiado al canal 1 de out[], es decir, canal 1 de bgr;
  • Canal 2 de bgra, copiado al canal 0 de out[], es decir, canal 2 de bgr;
  • Los 3 canales de bgra, copiados a, los 3 canales de out[], es decir, el canal alfa de bgr;
    inserte la descripción de la imagen aquí
Código de muestra:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	Mat bgra(200, 200, CV_8UC4, Scalar(255, 255, 0, 255));
	Mat bgr(bgra.rows, bgra.cols, CV_8UC3);
	Mat alpha(bgra.rows, bgra.cols, CV_8UC1);

	Mat out[] = {
    
     bgr, alpha };

	int from_to[] = {
    
     0, 2, 1, 1, 2, 0, 3, 3 };
	mixChannels(&bgra, 1, out, 2, from_to, 4);

	imshow("bgra", bgra);
	imshow("bgr", bgr);

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

(4) Ejemplo 2: Segmentación de imágenes

Divida una matriz de 4 canales (imagen BGRA) en una matriz de 3 canales (imagen BGR) y una matriz de un solo canal (imagen de canal alfa);

Correspondencia de canales: par de índices, int fromTo[] = { 0, 2, 1, 1, 2, 0, 3, 3 }

  • Canal 0 de bgra, copiado al canal 2 de bgr;
  • Canal 1 de bgra, copiado al canal 1 de bgr;
  • Canal 2 de bgra, copiado al canal 0 de bgr;
  • Canal 3 de bgra, copiado al canal 0 de alfa;
Código de muestra:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    

	Mat bgra( 200, 200, CV_8UC4, Scalar(255, 0, 0, 255) );
	Mat bgr( bgra.rows, bgra.cols, CV_8UC3 );
	Mat alpha( bgra.rows, bgra.cols, CV_8UC1 );

	Mat out[] = {
    
     bgr,alpha };
	// 通道对应关系
	int fromTo[] = {
    
     0, 2, 1, 1, 2, 0, 3, 3 };

	mixChannels(&bgra, 1, out, 2, fromTo, 4);
	imshow("bgra", bgra);
	imshow("bgr", bgr);
	imshow("alpha", alpha);

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

(5) Ejemplo 3: Adquisición de canal HSV

Utilice la función mixChannels() para copiar el canal especificado y podrá ver los detalles de los tres canales en el espacio de color HSV;

Espacio de color HSV:

  • Hue (tono): representa el color, medido de 0 a 360 grados (rojo-amarillo-verde-cian-azul-magenta);
  • Saturación (saturación, croma): se refiere a la profundidad del color. La saturación representa la proporción de gris a tono, y se mide desde 0 % (gris) hasta 100 % (saturación total). Cuando S=0, solo hay gris escala;
  • Valor (tono): el brillo del color, V=1, que incluye las tres caras de R=1, G=1 y B=1 en el modelo RGB, y el color representado es más brillante;
Código de muestra:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	// 读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", src);

	Mat hsv, dst;
	cvtColor(src, hsv, COLOR_BGR2HSV);
	dst.create( hsv.size(), hsv.depth() );

	//分离Hue,色相通道
	int ch[] = {
    
     0, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch, 1);
	imshow("H channel", dst);

	//分离Saturation,饱和度通道
	int ch1[] = {
    
     1, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch1, 1);
	imshow("S channel", dst);

	//分离Value,色调通道
	int ch2[] = {
    
     2, 0 };
	mixChannels(&hsv, 1, &dst, 1, ch2, 1);
	imshow("V channel", dst);

	waitKey();
	destroyAllWindows();
	return 0;
}
resultado de la operación:

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_33867131/article/details/131602283
Recomendado
Clasificación