15.图像像素统计
1、寻找图像最值
代码清单3-7 minMaxLoc()函数原型 1. void cv::minMaxLoc(InputArray src, 2. double * minVal, 3. double * maxVal = 0, 4. Point * minLoc = 0, 5. Point * maxLoc = 0, 6. InputArray mask = noArray() 7. )
-
src:需要寻找最大值和最小值的图像或者矩阵,要求必须是单通道矩阵
-
minVal:图像或者矩阵中的最小值。
-
maxVal:图像或者矩阵中的最大值。
-
minLoc:图像或者矩阵中的最小值在矩阵中的坐标。
-
maxLoc:图像或者矩阵中的最大值在矩阵中的坐标。
-
mask:掩模,用于设置在图像或矩阵中的指定区域寻找最值。
这里我们见到了一个新的数据类型Point,该数据类型是用于表示图像的像素坐标,由于图像的像素坐标轴以左上角为坐标原点,水平方向为x轴,垂直方向为y轴,因此Point(x,y)对应于图像的行和列表示为Point(列数,行数)。在OpenCV中对于2D坐标和3D坐标都设置了多种数据类型,针对2D坐标数据类型定义了整型坐标cv::Point2i(或者cv::Point)、double型坐标cv::Point2d、浮点型坐标cv::Point2f,对于3D坐标同样定义了上述的坐标数据类型,只需要将其中的数字“2”变成“3”即可。对于坐标中x、y、z轴的具体数据,可以通过变量的x、y、z属性进行访问,例如Point.x可以读取坐标的x轴数据。
该函数实现的功能是寻找图像中特定区域内的最值,函数第一个参数是输入单通道矩阵,需要注意的是,该变量必须是一个单通道的矩阵数据,如果是多通道的矩阵数据,需要用cv::Mat::reshape()将多通道变成单通道,或者分别寻找每个通道的最值,然后再进行比较寻找到全局最值。对于cv::Mat::reshape()的用法,在代码清单3-8中给出。第二到第五个参数分别是指向最小值、最大值、最小值位置和最大值位置的指针,如果不需要寻找某一个参数,可以将该参数设置为NULL,函数最后一个参数是寻找最值得掩码矩阵,用于标记寻找上述四个值的范围,参数默认值为noArray(),表示寻找范围是矩阵中所有数据。
代码清单3-8 Mat::reshape()函数原型 Mat cv::Mat::reshape(int cn, int rows = 0)
-
cn:转换后矩阵的通道数。
-
rows:转换后矩阵的行数,如果参数为零,则转换后行数与转换前相同。
代码清单3-9 myfindMinAndMax.cpp寻找矩阵中的最值 1. #include <opencv2\opencv.hpp> 2. #include <iostream> 3. #include <vector> 4. 5. using namespace std; 6. using namespace cv; 7. 8. int main() 9. { 10. system("color F0"); //更改输出界面颜色 11. float a[12] = { 1, 2, 3, 4, 5, 10, 6, 7, 8, 9, 10, 0 }; 12. Mat img = Mat(3, 4, CV_32FC1, a); //单通道矩阵 13. Mat imgs = Mat(2, 3, CV_32FC2, a); //多通道矩阵 14. double minVal, maxVal; //用于存放矩阵中的最大值和最小值 15. Point minIdx, maxIdx; ////用于存放矩阵中的最大值和最小值在矩阵中的位置 16. 17. /*寻找单通道矩阵中的最值*/ 18. minMaxLoc(img, &minVal, &maxVal, &minIdx, &maxIdx); 19. cout << "img中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl; 20. cout << "img中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl; 21. 22. /*寻找多通道矩阵中的最值*/ 23. Mat imgs_re = imgs.reshape(1, 4); //将多通道矩阵变成单通道矩阵 24. minMaxLoc(imgs_re, &minVal, &maxVal, &minIdx, &maxIdx); 25. cout << "imgs中最大值是:" << maxVal << " " << "在矩阵中的位置:" << maxIdx << endl; 26. cout << "imgs中最小值是:" << minVal << " " << "在矩阵中的位置:" << minIdx << endl; 27. return 0; 28. }
2、计算图像的均值与标准差
图像的均值表示图像整体的亮暗程度,图像的均值越大图像整体越亮。标准方差表示图像中明暗变化的对比程度,标准差越大表示图像中明暗变化越明显。OpenCV 4提供了mean()函数用于计算图像的平均值,提供了meanStdDev()函数用于同时计算图像的均值和标准方差。接下来将详细的介绍这两个函数的使用方法。
代码清单3-10 mean()函数原型 1. cv::Scalar cv::mean(InputArray src, 2. InputArray mask = noArray() 3. )
-
src:待求平均值的图像矩阵。
-
mask:掩模,用于标记求取哪些区域的平均值。
该函数用来求取图像矩阵的每个通道的平均值,函数的第一个参数用来输入待求平均值的图像矩阵,其通道数目可以在1到4之间。需要注意的是,该函数的返回值是一个cv::Scalar类型的变量,函数的返回值有4位,分别表示输入图像4个通道的平均值,如果输入图像只有1个通道,那么返回值的后三位都为0,例如输入该函数一个单通道平均值为1的图像,输出的结果为[1,0,0,0],可以通过cv::Scalar[n]查看第n个通道的平均值。该函数的第二个参数用于控制图像求取均值的范围,在第一个参数中去除第二个参数中像素值为0的像素,计算的原理如式(3.5)所示,当不输入第二个参数时,表示求取第一个参数全部像素的平均值。
其中表示第c个通道的平均值,
表示第c个通道像素的灰度值。
meanStdDev()函数可以同时求取图像每个通道的平均值和标准方差,其函数原型在代码清单3-11中给出。
代码清单3-11 meanStdDev()函数原型 1. void cv::meanStdDev(InputArray src, 2. OutputArray mean, 3. OutputArray stddev, 4. InputArray mask = noArray() 5. )
-
src:待求平均值的图像矩阵。
-
mean:图像每个通道的平均值,参数为Mat类型变量。
-
stddev:图像每个通道的标准方差,参数为Mat类型变量。
-
mask:掩模,用于标记求取哪些区域的平均值和标准方差。
该函数的第一个参数与前面mean()函数第一个参数相同,都可以是1-4通道的图像,不同之处在于该函数没有返回值,图像的均值和标准方差输出在函数的第二个和第三个参数中,区别于mean()函数,用于存放平均值和标准方差的是Mat类型变量,变量中的数据个数与第一个参数通道数相同,如果输入图像只有一个通道,该函数求取的平均值和标准方差变量中只有一个数据。该函数计算原理如式(3.6)所示。
代码清单3-12 myMeanAndmearStdDev.cpp计算矩阵平均值和标准方差 1. #include <opencv2\opencv.hpp> 2. #include <iostream> 3. #include <vector> 4. 5. using namespace std; 6. using namespace cv; 7. int main() 8. { 9. system("color F0"); //更改输出界面颜色 10. float a[12] = { 1, 2, 3, 4, 5, 10, 6, 7, 8, 9, 10, 0 }; 11. Mat img = Mat(3,4, CV_32FC1, a); //单通道矩阵 12. Mat imgs = Mat(2, 3, CV_32FC2, a); //多通道矩阵 13. 14. cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl; 15. Scalar myMean; 16. myMean = mean(imgs); 17. cout << "imgs均值=" << myMean << endl; 18. cout << "imgs第一个通道的均值=" << myMean[0] << " " 19. << "imgs第二个通道的均值=" << myMean[1] << endl << endl; 20. 21. cout << "/* 用meanStdDev同时求取图像的均值和标准方差 */" << endl; 22. Mat myMeanMat, myStddevMat; 23. 24. meanStdDev(img, myMeanMat, myStddevMat); 25. cout << "img均值=" << myMeanMat << " " << endl; 26. cout << "img标准方差=" << myStddevMat << endl << endl; 27. meanStdDev(imgs, myMeanMat, myStddevMat); 28. cout << "imgs均值=" << myMeanMat << " " << endl << endl; 29. cout << "imgs标准方差=" << myStddevMat << endl; 30. return 0; 31. }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具