#include <iostream>
#include "13_opencv_mat.h"
using namespace std;
void QuickDemo::pixel_statistic_demo(Mat &image)
{
/*
* 函数minMaxLoc用来查找最小和最大元素值及其位置。
* 在整个图像(数组)中搜索极值,如果mask不是空数组,则在指定的数组区域中搜索极值。
*
* void minMaxLoc(InputArray src, double* minVal, double* maxVal=0,
* Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
*
* 参数:
* src - 单通道图像
* minVal - 指向返回最小值的指针。如果不需要写NULL 或 缺省
* maxVal - 指向返回最大值的指针。如果不需要写NULL 或 缺省
* minLoc - 指向返回的最小位置的指针(在2D情况下)。如果不需要写NULL 或 缺省
* maxLoc - 指向返回的最大位置的指针(在2D情况下)。如果不需要写NULL 或 缺省
* mask - 可选掩码,用于选择子数组,如果不需要就缺省。
*
* 需要特别注意的是:
* 这个函数不能用于多通道图像(数组)。如果需要在所有通道中找到最小或最大元素(像素值),
* 请先首先使用Mat::reshape()将图像(数组)转换为单通道。
* 或者你可以使用extractImageCOI()、mixChannels()或split()来提取特定的通道。
*/
std::vector<Mat> mv;
/*
* 函数原型:void split(const Mat& mtx, vector<Mat>& mv)
* 函数功能:将一个多通道阵列划分为几个单通道阵列。
*/
split(image, mv);
imshow("蓝色", mv[0]);
imshow("绿色", mv[1]);
imshow("红色", mv[2]);
double minVal, maxVal;//定义两个变量分别用来记录最大像素值和最小像素值
Point minLoc, maxLoc;//记录最大像素值和最小像素值的位置
//查找图像中的最小值和最大值。
for (int i = 0; i < 3; i++)
{
minMaxLoc(mv[i], &minVal, &maxVal, &minLoc, &maxLoc, noArray());
std::cout << "minVal = " << minVal << ",maxVal = " << maxVal << std::endl;
std::cout << "minLoc = " << minLoc << ",maxLoc = " << maxLoc << std::endl;
}
/*
* 函数原型:void meanStdDev(InputArray src, OutputArray mean,
OutputArray stddev, InputArray mask=noArray())
*
* 函数功能:计算数组元素的平均值和标准偏差。
* 参数:
* src - 源图像(数组)应该有1到4个通道,以便结果可以存储在Scalar类型的数组中。
* mean - 输出参数:计算平均值。
* stddev - 输出参数:计算标准偏差。
* mask - 可选掩码,用于选择子数组,如果不需要就缺省。
*
* 函数meanStdDev独立计算每个通道的数组元素的均值和标准差,并通过输出参数返回:
*/
Mat mean, stddev;
meanStdDev(image, mean, stddev);
std::cout << "mean = " << mean << std::endl;
std::cout << "stddev = " << stddev << std::endl;
}
程序运行结果如下:
方差和均值代表的意义及其应用
均值
我们来看不同亮度的同一张图像。
可见,均值可以反应图片的明亮暗程度。
方差
根据计算出来的均值和方差,可以对图像所携带的信息做出一些判断。
比如方差,方差就是数据的分散程度(偏离均值)。图像中有个人和有辆车,那么他们的灰度值是不同的(颜色不同),你把全图像的灰度值取平均,偏离平均值越大,方差越大。方差越大,说明信息越多,能量越大。
比如下面这张图,方差为0,说明该图片的像素点没有变化,是张纯色图片。纯色的图片的每个通道的像素值都等于它每个通道的均值。再根据均值可以判断出该图片是什么颜色的。