OpenCV C++ 中统计学函数详解 —— 最大值、最小值、平均值、方差等应用介绍

1.简介

在图像处理和计算机视觉领域,统计学函数为图像数据的分析提供了基础工具。通过统计图像中的像素值信息,我们可以了解图像的动态范围、噪声水平以及图像整体的亮度分布,从而为图像增强、分割、目标检测等任务提供依据。本文将介绍 OpenCV C++ 中常用的统计学函数及其应用,包括求取最大值、最小值、平均值以及标准差(进而获得方差)的函数。

2.API介绍

2.1 最大值与最小值 —— cv::minMaxLoc

在图像处理过程中,了解图像中像素的最大值与最小值对于动态范围调整、图像归一化及阈值分割等都有重要意义。OpenCV 提供了 cv::minMaxLoc 函数,用于在图像(或矩阵)中查找像素的最小值和最大值,同时还可以获取这些值所在的位置。

void cv::minMaxLoc(InputArray src, double* minVal, double* maxVal, 
                   Point* minLoc = 0, Point* maxLoc = 0, InputArray mask = cv::noArray());

  • 参数说明
    • src:输入图像,可以是单通道或多通道,但对于多通道图像,需要先分离各个通道。
    • minVal:指向存放最小值的变量的指针。
    • maxVal:指向存放最大值的变量的指针。
    • minLoc:指向存放最小值位置(坐标)的变量的指针(可选)。
    • maxLoc:指向存放最大值位置(坐标)的变量的指针(可选)。
    • mask:掩码图像,若需要对图像的某一区域进行统计,则可传入掩码。

参考代码:

#include "stdio.h"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;

int main()
{
	cv::Mat srcImage=cv::imread("E:\\image\\Opencv-logo.png");
	//RGB通道分离
	std::vector<Mat> splitImage;
	split(srcImage, splitImage);
	double minValue, maxValue; //最大最小值
	Point minLoc, maxLoc;     //最大最小值的位置
	for (int i=0;i<srcImage.channels();i++)
	{
		minMaxLoc(splitImage[i], &minValue, &maxValue, &minLoc, &maxLoc);
		std::cout << "min:" << minValue << " max:" << maxValue << std::endl;
	}
	imshow("src", srcImage);
	waitKey();
	cv::destroyAllWindows();
	return 0;
}

2. 2 平均值计算 —— cv::mean

图像的平均值通常用于评估图像整体亮度和背景强度。在 OpenCV 中,cv::mean 函数能够计算图像的每个通道的平均值。对于多通道图像,返回的是一个 cv::Scalar 对象,其各个元素分别对应图像各个通道的平均值。

cv::Scalar cv::mean(InputArray src, InputArray mask = cv::noArray());
  • 参数说明
    • src:输入图像。
    • mask:可选参数,如果只想计算图像某一区域的平均值,可以传入掩码。

参考代码

#include "stdio.h"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;

int main()
{
	cv::Mat srcImage=cv::imread("E:\\image\\Opencv-logo.png");
	cv::Scalar avg = cv::mean(srcImage);
	std::cout << "图像平均值:B = " << avg[0]
		<< ", G = " << avg[1]
		<< ", R = " << avg[2] << std::endl;
	imshow("src", srcImage);
	waitKey();
	cv::destroyAllWindows();

	return 0;
}

通过这种方式,可以对图像整体亮度进行量化分析,常用于背景建模和图像分割前的预处理。

2.3. 方差与标准差 —— cv::meanStdDev

在很多图像处理任务中,除了平均值外,了解图像的像素分布离散程度(即标准差或方差)也非常重要。比如纯色的图像方差就是0。OpenCV 提供了 cv::meanStdDev 函数,可以同时计算图像的均值和标准差。

void cv::meanStdDev(InputArray src, OutputArray mean, OutputArray stddev, 
                    InputArray mask = cv::noArray());
  • 参数说明
    • src:输入图像。
    • mean:输出均值(cv::Scalar)。
    • stddev:输出标准差(cv::Scalar)。
    • mask:掩码图像(可选)。

由于方差等于标准差的平方,因此如果需要计算方差,只需要对 stddev 的每个通道进行平方操作即可。
参考代码:

#include "stdio.h"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;

int main()
{
	cv::Mat srcImage=cv::imread("E:\\image\\Opencv-logo.png");
	//RGB通道分离
	cv::Scalar avg = cv::mean(srcImage);
	std::cout << "图像平均值:B = " << avg[0]
		<< ", G = " << avg[1]
		<< ", R = " << avg[2] << std::endl;

  //计算方差和标准差
	Mat mean, stddev;
	meanStdDev(srcImage, mean, stddev);
	std::cout << "mean:" << mean <<std::endl;
	std::cout << "stddev:" << stddev << std::endl;
	imshow("src", srcImage);
	waitKey();
	cv::destroyAllWindows();

	return 0;
}

该函数在图像噪声分析、质量评价以及背景建模等任务中非常有用。

3.应用场景

3.1 图像归一化和增强

通过获取图像的最小值和最大值,可以对图像进行归一化处理,将像素值映射到一个新的范围内,从而提升图像对比度和视觉效果。例如,可以使用归一化函数 cv::normalize 结合统计数据进行图像增强。

3.2 阈值分割

利用统计学信息(如均值或中值),可以设定自适应阈值,对图像进行二值化处理。这在目标检测和图像分割中非常常见。例如,可以根据图像的平均亮度设定阈值,将背景与目标分离。

3.3 噪声评估与滤波

通过统计图像像素的方差,可以评估图像中的噪声水平。噪声较大的图像可能需要更强的滤波操作(如均值滤波或中值滤波)来提高图像质量。统计学函数帮助量化图像噪声,为后续滤波算法选择合适参数提供依据。

4. 总结

本文详细介绍了 OpenCV C++ 中常用的统计学函数,包括 cv::minMaxLoccv::meancv::meanStdDev。通过这些函数,我们可以快速获得图像的最大、最小值、平均值和标准差(从而计算方差),为图像归一化、阈值分割、噪声评估和图像增强等应用提供有力支持。在实际项目中,合理利用这些统计信息,可以有效提高图像处理的效果和效率。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐