OpenCV学习之Mat数据按位操作与通道分离合并
2017-06-07 00:07
423 查看
**
以前一直用MATLAB做图像仿真,这次学习OPENCV后,第一步就是读取图像,并对图像进行位操作,在OPENCV中比较重要和基础的一个数据结构是MAT,针对MAT型结构的位处理,进行了以下试验。
试验结果图
![](https://img-blog.csdn.net/20170607000609023?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGV6MTAyMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2.彩色图像在OPENCV中的存储通道顺序是B-G-R,对彩色图像进行通道分离,可以利用split(srcImg, channels),这里channels是一个MAT类型的通道向量,可以通过at提取出来;
3.对多个通道合并可以用merge(channels,dstImg)函数,这里这里channels是一个MAT类型的通道向量,并按BGR的顺序在0-2的位置存放对应色彩通道数据,其中,通道向量可以用vector cha
a33f
nnels创建,并用channels.push_back( )按B-G-R的先后顺序存入;
4.对于1中的type类型,如果图像开始创建的类型为8S/8U,这里type对应着char/uchar,其赋值范围为-127~127/0~255;若初始创建类型为32F,则type类型可用float,赋值范围为0~1,小数点后几位。(此条待进一步修正)
以前一直用MATLAB做图像仿真,这次学习OPENCV后,第一步就是读取图像,并对图像进行位操作,在OPENCV中比较重要和基础的一个数据结构是MAT,针对MAT型结构的位处理,进行了以下试验。
**
#include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui/highgui.hpp> #include<iostream> #include"hessianHead.h" using namespace cv; using namespace std; #define Name1 "图一_3通道_Ptr_8位有符号" #define Name2 "图二_3通道_At_8位有符号" #define Name3 "图三_1通道_At_8位无符号" #define Name4 "图四_对分离后的channel进行操作" #define Name5 "图五_直接生成channel再进行合并" int main() { //namedWindow(windowsName3, WINDOW_NORMAL); Mat emptyImg1(500,500,CV_8SC3); //这里100*100是像元数,不是矩阵实际数,实际矩阵应该是100*100*C(通道数) Mat emptyImg2(500, 500, CV_8SC3); for (int i = 0; i < emptyImg1.rows; i++) { for (int b = 0, g = 1, r = 2; r < emptyImg1.rows*3; b += 3, g += 3, r += 3) //因为是三通道,所以列数应该乘以3 { emptyImg1.ptr<char>(i)[b] = 120; emptyImg1.ptr<char>(i)[g] = -127; emptyImg1.ptr<char>(i)[r] = -127; emptyImg2.at<char>(i,b) = 120; emptyImg2.at<char>(i,g) = 0; emptyImg2.at<char>(i,r) = 0; } } namedWindow(Name1, WINDOW_NORMAL); imshow(Name1, emptyImg1); namedWindow(Name2, WINDOW_NORMAL); imshow(Name2, emptyImg2); //这里是8通道无符号的赋值 Mat emptyImg3(20, 20, CV_8UC1); for (int i = 0; i < 20; i++) { for (int j = 0; j< 20; j++) { emptyImg3.at<uchar>(i, j) = 60; } } namedWindow(Name3, WINDOW_NORMAL); imshow(Name3, emptyImg3); //通道分离与合并 Mat emptyImg4(20, 20, CV_8SC3); Mat megeImg1, megeImg2; vector<Mat> channels; vector<Mat> channelsForMege; Mat imgBlueChannel; Mat imgGrayChannel; Mat imgRedChannel; //分离处颜色通道 split(emptyImg4, channels); /* 方法一:可以复制地址到新的Mat空间 imgBlueChannel=channels.at(0); imgGrayChannel=channels.at(1); imgRedChannel=channels.at(2); */ //方法二:也可以拷贝数据到新的Mat空间,修改后原图不变 channels.at(0).copyTo(imgBlueChannel); channels.at(1).copyTo(imgGrayChannel); channels.at(2).copyTo(imgRedChannel); for (int i = 0; i < 20; i++) { for (int j = 0; j< 20; j++) { //方法一:这里利用通道空间来赋值 channels.at(0).at<uchar>(i, j) = 0; channels.at(1).at<uchar>(i, j) = 100; channels.at(2).at<uchar>(i, j) = 100; /* 除了之间使用通道空间来赋值外,也可以用复制地址后的通道来赋值; imgBlueChannel.at<uchar>(i, j) =120; imgGrayChannel.at<uchar>(i, j) = -127; imgRedChannel.at<uchar>(i, j) = -127; */ //方法二:这里利用了复制数据后的通道来复制 imgBlueChannel.at<uchar>(i, j) = 1; imgGrayChannel.at<uchar>(i, j) = 1; imgRedChannel.at<uchar>(i, j) = 1; } } //使用方法二:需要重新做一个通道向量以便利用merge函数 //这里应该按先后顺序,按照B-G-R的顺序存入; channelsForMege.push_back(imgBlueChannel); channelsForMege.push_back(imgGrayChannel); channelsForMege.push_back(imgRedChannel); //*合并通道 merge(channelsForMege, megeImg2); merge(channels, megeImg1); namedWindow(Name4, WINDOW_NORMAL); namedWindow(Name5, WINDOW_NORMAL); imshow(Name4, megeImg1); imshow(Name5, megeImg2); Mat emptyImg6(20, 20, CV_32FC3);//(输入数据类型为32位Float型) double gr = 228 / 255; for (int i = 0; i < emptyImg6.rows; i++) { for (int b = 0, g = 1, r = 2; r < emptyImg6.rows * 3; b += 3, g += 3, r += 3) //因为是三通道,所以列数应该乘以3 { //(float 型的输入,输入范围应该在0~1,与图四相同,则输入应127/255=0.5,228/255=0.89,228/255) emptyImg6.ptr<float>(i)[b] = 0.5; emptyImg6.ptr<float>(i)[g] = 0.89; emptyImg6.ptr<float>(i)[r] = 0.89; } } cout << gr; namedWindow("six", WINDOW_NORMAL); imshow("six", emptyImg6); waitKey(0); return 0; }
试验结果图
总结:
1.按位操作,可以用MAT的at和ptr函数来实现,两者的写法不同,对位置位(i,j)处的像素,两者的表示的是at(i,j),ptr(i)[j];2.彩色图像在OPENCV中的存储通道顺序是B-G-R,对彩色图像进行通道分离,可以利用split(srcImg, channels),这里channels是一个MAT类型的通道向量,可以通过at提取出来;
3.对多个通道合并可以用merge(channels,dstImg)函数,这里这里channels是一个MAT类型的通道向量,并按BGR的顺序在0-2的位置存放对应色彩通道数据,其中,通道向量可以用vector cha
a33f
nnels创建,并用channels.push_back( )按B-G-R的先后顺序存入;
4.对于1中的type类型,如果图像开始创建的类型为8S/8U,这里type对应着char/uchar,其赋值范围为-127~127/0~255;若初始创建类型为32F,则type类型可用float,赋值范围为0~1,小数点后几位。(此条待进一步修正)
相关文章推荐
- 【OpenCV学习笔记】十二、图像的对比度和亮度调整及图像通道的分离与合并
- OpenCV之Python学习笔记(1)(2): 图像的载入、显示和保存 图像元素的访问、通道分离与合并
- 【基于C++和Python的Opencv3学习笔记之颜色空间缩减、ROI提取及多通道分离合并】
- OpenCV学习(十四)之彩色图像RGB通道的分离、合并与显示
- OpenCV学习(十四)之彩色图像RGB通道的分离、合并与显示
- OpenCV Python教程(2、图像元素的访问、通道分离与合并)
- OpenCV 2.x新数据结构cv::Mat的一些学习材料
- OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年
- OpenCV Python教程(2、图像元素的访问、通道分离与合并)
- python OpenCV 图像通道分离和合并 (四)
- 【OpenCV数字图像处理】(5) 【Python编程】(5) 像素访问之添加椒盐实例 通道分离与合并
- 【OpenCV学习笔记】之二:Mat使用的潜规则----对数据类型敏感
- 我的OpenCV学习笔记(23):Mat中实际数据是如何保存的
- 【学习OpenCV】通过DLL实现图像数据从.dat导入Mat
- OpenCV学习笔记 Mat数据操作之普通青年、文艺青年、暴力青年
- opencv-从图像旋转学习Mat数据访问
- opencv学习笔记-入门(7)单通道的图像数据访问
- opencv学习笔记-入门(7)单通道的图像数据访问
- OpenCV学习:Mat矩阵合并两张图像
- OpenCV Mat图像颜色通道分离(split)合成(merge),各通道合图显示