前言
记录opencv有关像素操作的一些函数和功能
一、多通道的分离合并
多通道分离函数split()
形式1:
void split(const Mat & scr,Mat * mvbegin)
scr:待分离的多通道图像
mvbegin:分离后的单通道图像,为数组形式,数组大小需要与图像的通道数相同
形式2:
void split(InputArray m,OutputArrayOfArrays mv)
m:待分离的多通道图像
mv:分离后的单通道图像,为向量(vector)形式
对比:形式1的第二个参数输出一个Mat型的数组,并且数组长度要与图像的通道数相同并且提前定义。
形式2的第二个参数输出一个vector<Mat>容器,不需要知道多通道图像的通道数。
多通道合并函数merge()
形式1:
void merge(const Mat * mv,size_t count,OutputArray dst)
mv(第一种重载原型参数):需要合并的图像数组,其中每个图像必须拥有相同的尺寸和数据类型
count:输入的图像数组的长度,其数值必须大于0
dst:合并输出后的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和
形式2:
void merge(InputArrayOfArrays mv,OutputArray dst)
mv(第二种重载原型参数):需要合并的图像向量(vector),其中每个图像必须拥有相同的尺寸和数据类型
dst:合并输出后的图像,与mv[0]具有相同的尺寸和数据类型,通道数等于所有输入图像的通道数总和
示例程序:
#include<opencv2\opencv.hpp> //加载OpenCV4的头文件
#include<iostream>
#include<vector>
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
Mat img = imread("lena.jpg");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat HSV;
cvtColor(img, HSV, COLOR_RGB2HSV); //RGB图像模型转HSV
Mat imgs0, imgs1, imgs2; //用于存放数组类型的结果
Mat imgv0, imgv1, imgv2; //用于存放vector类型的结果
Mat result0, result1, result2; //多通道合并的结果
Mat imgs[3];
split(img, imgs); //将img图像的3个通道分别存放到imgs数组中
imgs0 = imgs[0];
imgs1 = imgs[1];
imgs2 = imgs[2];
imshow("RGB-B通道", imgs0); //显示分离后B通道的像素值
imshow("RGB-G通道", imgs1); //显示分离后G通道的像素值
imshow("RGB-R通道", imgs2); //显示分离后R通道的像素值
imgs[2] = img; //将R通道变成完整的RGB三通道模式,是的数组中图像的通道数不一致
merge(imgs, 3, result0); //合并图像
//imshow("result0",result0); //imshow最多显示4个通道,因此结果在Image Watch中查看
Mat zero = zero.zeros(img.rows, img.cols, CV_8UC1); //构建一个全为0的矩阵
imgs[0] = zero;
imgs[2] = zero;
merge(imgs, 3, result1); //用于还原G通道的真实情况,合并结果为绿色
imshow("result1", result1); //显示合并结果
//输入vector参数的多通道分离与合并
vector<Mat> imgv;
split(HSV, imgv); //第二个参数为vector
imgv0 = imgv.at(0);
imgv1 = imgv.at(1);
imgv2 = imgv.at(2);
imshow("HSV-H通道", imgv0); //显示分离后H(色度)通道的像素值
imshow("HSV-S通道", imgv1); //显示分离后S(饱和度)通道的像素值
imshow("HSV-V通道", imgv2); //显示分离后V(亮度)通道的像素值
imgv.push_back(HSV); //将vector中的图像通道数变成不一致
merge(imgv, result2); //合并图像
//imshow("result2",result2); //imshow最多显示4个通道,因此结果在Image Watch中查看
waitKey(0);
return 0; //程序结束
}
imgs0(B通道):
![](https://i-blog.csdnimg.cn/blog_migrate/25c19857cd84d54faf756be64a4d32a6.png)
imgs1(G通道):
![](https://i-blog.csdnimg.cn/blog_migrate/7fcf51ed1b9770651da3fe60eba301f1.png)
imgs2(R通道):
![](https://i-blog.csdnimg.cn/blog_migrate/19b63d7f60d938f7399a74f87e688ea1.png)
result0(总共5个通道):
![](https://i-blog.csdnimg.cn/blog_migrate/8616fc366991176f85451d405667a673.png)
看起来还有点酷
result1(只显示绿色G通道):
![](https://i-blog.csdnimg.cn/blog_migrate/2d852af424a3c0795fa567da81d07a16.png)
result2(HSV模型下的5通道图像):
![](https://i-blog.csdnimg.cn/blog_migrate/53c1665fcf540654530f0c0ec2df6cb0.png)
二、图像像素统计
计算图像的平均值和标准差
形式1:
mean(InputArray src,InputArray mask=noArray())
src:待求平均值的图像矩阵
mask:用于标记求取哪些区域的平均值
可以求取的图像通道数为1~4,该函数返回一个Scalar类型的变量,通过Scalar[n]来查看第n个通道的平均值。
形式2:
meanStdDev(InputArray src,OutputArray mean,OutputArray stddev,InputArray mask=noArray())
src:待求平均值的图像矩阵
mean:图像每个通道的平均值,参数为Mat类型变量
stddev:图像每个通道的标准差,参数为Mat类型变量
mask:用于标记求取哪些区域的平均值和标准差
该函数没有返回值,因为返回的内容在传入的参数中,第二个参数是平均值,第三个参数是标准差
图像的平均值越大,图像整体越亮;图像的标准差越大,图像中明暗的对于越明显
如果对Scalar类型想有更深入的理解,推荐这位博主的博客:OpenCV学习笔记(3)——Scalar数据类型理解_Lavi的专栏-CSDN博客_scalar
来一个示例程序:
#include<opencv2\opencv.hpp> //加载OpenCV4的头文件
#include<iostream>
#include<vector>
using namespace std;
using namespace cv; //OpenCV命名空间
int main()
{
system("color F0"); //更改界面输出颜色
float a[12] = { 1,2,3,4,5,10,6,7,8,9,10,0 };
Mat img = Mat(3, 4, CV_32FC1, a); //单通道矩阵,3*4
Mat imgs = Mat(2, 3, CV_32FC2, a); //多通道矩阵,2*3*2
cout << "/* 用mean求取图像的平均值 */" << endl;
Scalar myMean;
myMean = mean(imgs);
cout << "imgs平均值=" << myMean << endl; //输出格式为[0,0,0,0]分别对应第一,二,三,四通道
cout << "imgs第一个通道的平均值=" << myMean[0] <<" "<< "imgs第二个通道的平均值=" << myMean[1] << endl;
cout << "/* 用meanStdDev同时求取图像的平均值和标准差 */"<<endl;
Mat myMeanMat, myStddevMat;
meanStdDev(img, myMeanMat, myStddevMat); //平均值和标准差
cout << "img平均值=" << myMeanMat << endl;
cout << "img标准差=" << myStddevMat << endl;
meanStdDev(imgs, myMeanMat, myStddevMat);
cout << "imgs平均值=" << myMeanMat << endl;
cout << "imgs标准差=" << myStddevMat << endl;
return 0; //程序结束
}
![](https://i-blog.csdnimg.cn/blog_migrate/4c4287c55a655490b4c0e7fa57ee0531.png)
根据输出结果可以看出,如果不对某一通道进行针对性输出,那么输出的格式就为[0,0,0,0]格式,分别对应第一,二,三,四通道。
感谢阅读!
也欢迎大家关注小白博主,多多鼓励一下!