OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度
均值、标准差和平均梯度是验证图像质量的常用指标。其中:
- 均值反映了图像的亮度,均值越大说明图像亮度越大,反之越小;
- 标准差反映了图像像素值与均值的离散程度,标准差越大说明图像的质量越好;
- 平均梯度反映了图像的清晰度和纹理变化,平均梯度越大说明图像越清晰;
那么,如何使用OpenCV计算图像的均值、标准差和平均梯度呢?
OpenCV提供了几个函数,可以用来帮助我们计算。
1、计算图像的平均梯度
meanStdDev()函数用于计算一个矩阵的均值和标准差,它的声明如下:
void cv::meanStdDev (
InputArray src,
OutputArray mean,
OutputArray stddev,
InputArray mask = noArray()
)
函数参数
- src:输入的源图像或矩阵
- mean:输出的均值矩阵
- stddev:输出的标准差矩阵
- mask:可选的掩码矩阵
使用meanStdDev计算均值和标准差的代码如下:
// 输入图像的路径
// 计算图像的标准差
void cal_mean_stddev(string path) {
Mat src = imread(path);
Mat gray, mat_mean, mat_stddev;
cvtColor(src, gray, CV_RGB2GRAY); // 转换为灰度图
meanStdDev(gray, mat_mean, mat_stddev);
double m, s;
m = mat_mean.at<double>(0, 0);
s = mat_stddev.at<double>(0, 0);
cout << path << "的灰度均值是:" << m << endl;
cout << path << "的标准差是:" << s << endl;
}
标准差的计算公式如下:
其中, M * N表示图像的大小, P(i, j) 表示第i行、第j列的像素值, u表示均值。
2、计算图像的平均梯度
平均梯度的计算公式如下:
下面的代码参考了:http://blog.csdn.net/windydreams/article/details/22691349
// 输入图像的路径
// 计算图像的平均梯度
void cal_mean_gradient(string path) {
Mat src = imread(path);
Mat img;
cvtColor(src, img, CV_RGB2GRAY); // 转换为灰度图
img.convertTo(img, CV_64FC1);
double tmp = 0;
int rows = img.rows - 1;
int cols = img.cols - 1;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
double dx = img.at<double>(i, j + 1) - img.at<double>(i, j);
double dy = img.at<double>(i + 1, j) - img.at<double>(i, j);
double ds = std::sqrt((dx*dx + dy*dy) / 2);
tmp += ds;
}
}
double imageAvG = tmp / (rows*cols);
cout << path << "的平均梯度是:" << imageAvG << endl;
}
3、测试图像为:
images/image7.jpg
测试结果如下:
完整的测试程序如下:
/*************************************************
Copyright:bupt
Author: lijialin 1040591521@qq.com
Date:2017-11-21
Description:写这段代码的时候,只有上帝和我知道它是干嘛的
现在只有上帝知道
**************************************************/
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/***************** 函数声明部分 start ****************/
void cal_mean_stddev(string path); // 计算图像的标准差
void cal_mean_gradient(string path); // 计算图像的平均梯度
/***************** 函数声明部分 end ****************/
int main() {
string path = "images/image7.jpg"; // image7.jpg在images目录下
cal_mean_stddev(path);
cal_mean_gradient(path);
system("pause"); // 暂停
return 0;
}
// 计算图像的标准差
void cal_mean_stddev(string path) {
Mat src = imread(path);
Mat gray, mat_mean, mat_stddev;
cvtColor(src, gray, CV_RGB2GRAY); // 转换为灰度图
meanStdDev(gray, mat_mean, mat_stddev);
double m, s;
m = mat_mean.at<double>(0, 0);
s = mat_stddev.at<double>(0, 0);
cout << path << "的灰度均值是:" << m << endl;
cout << path << "的标准差是:" << s << endl;
}
// 计算图像的平均梯度
void cal_mean_gradient(string path) {
Mat src = imread(path);
Mat img;
cvtColor(src, img, CV_RGB2GRAY); // 转换为灰度图
img.convertTo(img, CV_64FC1);
double tmp = 0;
int rows = img.rows - 1;
int cols = img.cols - 1;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
double dx = img.at<double>(i, j + 1) - img.at<double>(i, j);
double dy = img.at<double>(i + 1, j) - img.at<double>(i, j);
double ds = std::sqrt((dx*dx + dy*dy) / 2);
tmp += ds;
}
}
double imageAvG = tmp / (rows*cols);
cout << path << "的平均梯度是:" << imageAvG << endl;
}