【opencv】12.RGB和BGR的转化,通道分离与合并

RGB和BGR的转化,通道分离与合并

opencv中默认读取的图片格式是BGR,并非RGB.
下面是opencv更直接的BGRRGB方法:
cv::cvtColor(bgr_img, rgb_img, cv::COLOR_BGR2RGB);

关于cv::split()cv::merge()更细节的直观展示内容可以参考这篇博文:图像通道分离与合并——cv::split()与cv::merge()详解

void split(
	const cv::Mat& src_img, //输入图像
	std::vector<Mat>& mat_vct // 输出的多通道序列(n个单通道序列)
);
void merge(
	const vector<cv::Mat>& mat_vct, // 输入的多通道序列(n个单通道序列)
	cv::OutputArray dst // 输出图像(cv::OutputArray可以理解为等价于cv::Mat类型)
);

注意上面两个函数:
cv::split的输入是cv::Mat,输出是std::vector;
cv::merge的输入是std::vector,输出是cv::Mat


cv::Mat::convertTo(cv::OutputArray m, int type ) 用法:

//将cv::Mat类型的mat_1转换为CV_8UC3类型,输出到cv::Mat类型的mat_2中,mat_1值不变
mat_1.convertTo(mat_2, CV_8UC3);

下面是通道的分离与合并的例子:

cv::Mat src_img=cv::imread("./lena.png",1); //1是BGR,0是单通道灰度图
std::string window_name = "origin:BGR";
cv::namedWindow(window_name, 0);
cv::imshow(window_name, src_img);
cv::waitKey(1);


std::vector<cv::Mat> mat_vct_1(3);
cv::split(src_img, mat_vct_1); //这句话把src_img分离为三个Mat

//其实这个mat_vct_2有点多余,完全可以直接使用mat_vct_1进行merge即可。
//之所以这里增加一个mat_vct_2变量,是测试修改通道顺序看效果
std::vector<cv::Mat> mat_vct_2; 
//下面[0]、[1]、[2]分别表示B、G、R通道
//下面从[2]到[0]进行push_back就是变成了RGB顺序通道
mat_vct_2.push_back(mat_vct_1[2]); 
mat_vct_2.push_back(mat_vct_1[1]);
mat_vct_2.push_back(mat_vct_1[0]);

cv::Mat dst_img;
cv::merge(mat_vct_2, dst_img); //这句话把mat_vct_2合并为一个3通道的Mat

window_name = "RGB";
cv::namedWindow(window_name, 0);
cv::imshow(window_name, dst_img);
cv::waitKey(0);

上面的做法没有使用convertTo函数进行数据类型转换,会保持原来的数据类型。
下面的操作是使用convertTo函数进行数据类型转换,如16位转化为32位等操作,cv::Mat::type()的值和图片的 通道数 无关,例如,数据类型是CV_8U,而不是CV_8UC3这样的带通道的描述。
此处type返回的是一个int,具体的类型如下表:
在这里插入图片描述
例如:type()返回0就表示CV_8UC1,返回16就表示CV_8UC3


使用convertTo函数进行数据类型转换:

cv::Mat src_img=cv::imread("./lena.png",0); //BGR
std::vector<cv::Mat> mat_vct_1(3);
cv::split(src_img, mat_vct_1); //这句话把src_img分离为三个Mat

cv::Mat b_channel,g_channel,r_channel;
mat_vct_1.at(0).convertTo(b_channel, CV_8UC1);
mat_vct_1.at(1).convertTo(g_channel, CV_8UC1);
mat_vct_1.at(2).convertTo(r_channel, CV_8UC1);

下面是把存有3个cv::Matvector变量mat_vct_1合并为一个三通道cv::Mat的图像dst_img

cv::Mat img_tmp,dst_img;
//这句话把mat_vct_1合并为一个3通道的Mat: img_tmp
cv::merge(mat_vct_1, img_tmp); 
//将img_tmp转换为CV_8UC3类型,输出到dst_img中
img_tmp.convertTo(dst_img, CV_8UC3);

测试时的编译命令:

g++ `pkg-config opencv --cflags` test.cpp -std=c++11 -pthread -o test `pkg-config opencv --libs`
下面代码可以测试不同颜色通道组合后是什么颜色:
int main(void) {
  int cols = 500, rows = 500;
  cv::Mat img_b = cv::Mat::zeros(cv::Size(cols, rows), CV_8UC1) + 255;
  cv::Mat img_g = cv::Mat::zeros(cv::Size(cols, rows), CV_8UC1);
  cv::Mat img_r = cv::Mat::zeros(cv::Size(cols, rows), CV_8UC1);

  std::vector<cv::Mat> mat_vct;
  //下面[0]、[1]、[2]分别表示B、G、R通道
  //下面从[2]到[0]进行push_back就是变成了RGB顺序通道
  mat_vct.push_back(img_b);
  mat_vct.push_back(img_g);
  mat_vct.push_back(img_r);

  cv::Mat dst_img;
  cv::merge(mat_vct, dst_img);  //这句话把mat_vct合并为一个3通道的Mat

  std::string window_name = "img";
  cv::namedWindow(window_name, 0);
  cv::imshow(window_name, dst_img);
  cv::waitKey(0);

  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值