C++ 点锐度 灰度方差 峰值信噪比

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"


using namespace cv;
using namespace std;

double PVA_Grad(Mat &img);
double GrayAverage(Mat &img);
double GrayVariance(Mat &img);
double getPSNR(Mat &src, Mat &res);
int main()
{
    
    
	Mat imgIn, imgOut;
	imgIn = imread("D:\\user\\1.jpg", IMREAD_GRAYSCALE);
	imgOut = imread("D:\\user\\4.jpg", IMREAD_GRAYSCALE);

	if (imgIn.empty()) 
	{
    
    

		return -1;
	}

	if (imgOut.empty())
	{
    
    

		return -1;
	}


	double EVA1, EVA2;
	EVA1 = PVA_Grad(imgIn);
	EVA2 = PVA_Grad(imgOut);
	cout << "原始图像的点锐度: " << EVA1 << endl;
	cout << "增强后图像的点锐度: " << EVA2 << endl;
	
	double AVE1, AVE2;
	AVE1 = GrayAverage(imgIn);
	AVE2 = GrayAverage(imgOut);
	cout << "原始图像的灰度平均值: " << AVE1 << endl;
	cout << "增强后图像的灰度平均值: " << AVE2 << endl;

	double VAR1, VAR2;
	VAR1 = GrayVariance(imgIn);
	VAR2 = GrayVariance(imgOut);
	cout << "原始图像的灰度方差: " << VAR1 << endl;
	cout << "增强后图像的灰度方差: " << VAR2 << endl;

	double PSNR;
	PSNR = getPSNR(imgIn, imgOut);
	cout << "图像的峰值信噪比: " << PSNR << endl;

	waitKey(0);
	system("pause");
	return 0;
}

// 点锐度
double PVA_Grad(Mat &img)
{
    
    
	double P = 0;
	for (int i = 1; i < img.rows - 1; i++)
	{
    
    
		//定义行指针
		uchar *current_ptr = (uchar*)img.data + i * img.cols;
		uchar *pre_ptr = (uchar*)img.data + (i - 1)*img.cols;
		uchar *next_ptr = (uchar*)img.data + (i + 1)*img.cols;
		for (int j = 1; j < img.cols - 1; j++)
		{
    
    

			/*P += abs((pre_ptr[j - 1] - current_ptr[j])*0.7 + pre_ptr[j] - current_ptr[j] + (pre_ptr[j + 1] - current_ptr[j])*0.7
				+ (current_ptr[j - 1] - current_ptr[j]) + current_ptr[j + 1] - current_ptr[j]
				+ (next_ptr[j - 1] - current_ptr[j])*0.7 + next_ptr[j] - current_ptr[j] + (next_ptr[j + 1] - current_ptr[j])*0.7);
			*/
			// wj,公式是先取绝对值再求和,原程序得到的值会小很多
			P += abs(pre_ptr[j - 1] - current_ptr[j])*0.7 + abs(pre_ptr[j] - current_ptr[j] )+ abs(pre_ptr[j + 1] - current_ptr[j])*0.7
				+ abs(current_ptr[j - 1] - current_ptr[j]) + abs(current_ptr[j + 1] - current_ptr[j])
				+ abs(next_ptr[j - 1] - current_ptr[j])*0.7 + abs(next_ptr[j] - current_ptr[j]) + abs(next_ptr[j + 1] - current_ptr[j])*0.7;

		}
	}
	return P / (img.cols - 2) / (img.rows - 2);
}

//灰度平均值
double GrayAverage(Mat &img)
{
    
    
	double U = 0;
	for (int i = 0; i < img.rows; i++)
	{
    
    
		//定义行指针
		uchar* ptr = (uchar*)img.data + i *img.cols;
		for (int j = 0; j <img.cols; j++)
		{
    
    
			U += ptr[j];
			
		}
	} 
	return U / (img.cols ) / (img.rows );
}
	

//灰度方差
double GrayVariance(Mat &img)
{
    
    
	double aver = GrayAverage(img);
	double var = 0;
	for (int i = 0; i < img.rows; i++)
	{
    
    
		//定义行指针
		uchar* ptr = (uchar*)img.data + i *img.cols;
		for (int j = 0; j <img.cols; j++)
		{
    
    
			var += (ptr[j]-aver)*(ptr[j] - aver);

		}
	}
	return  var / (img.cols) / (img.rows);
}

// 峰值信噪比
double getPSNR( Mat &src,  Mat &res)
{
    
    
	
	
		Mat s1;
		absdiff(src, res, s1);       // |I1 - I2|AbsDiff函数是 OpenCV 中计算两个数组差的绝对值的函数
		s1.convertTo(s1, CV_32F);  // 这里我们使用的CV_32F来计算,因为8位无符号char是不能进行平方计算
		s1 = s1.mul(s1);           // |I1 - I2|^2
		
		Scalar s = sum(s1);         //对每一个通道进行加和

		double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels

		if (sse <= 1e-10) // 对于非常小的值我们将约等于0
			return 0;
		else
		{
    
    

			double MSE = sse / (src.cols) / (src.rows); //均方根误差
			int MAX = 255;		// 图像颜色的最大数值
			double psnr = 10.0*log10((MAX * MAX) / MSE);
			return psnr;//返回PSNR
		}
}


猜你喜欢

转载自blog.csdn.net/shuaijieer/article/details/126047037