OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度

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、计算图像的平均梯度

平均梯度的计算公式如下:

OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度_第1张图片

下面的代码参考了: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
OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度_第2张图片

测试结果如下:
OpenCV 自学笔记33. 计算图像的均值、标准差和平均梯度_第3张图片

完整的测试程序如下:


/*************************************************

Copyright:bupt
Author: lijialin [email protected]
Date:2017-11-21
Description:写这段代码的时候,只有上帝和我知道它是干嘛的
            现在只有上帝知道

**************************************************/

#include 
#include 

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;
}

你可能感兴趣的:(OpenCV,OpenCV学习笔记)