计算图像清晰度

本文详细介绍了OpenCV中使用Sobel算子、Brenner方法、拉普拉斯变换、标准差、Vollath方法、SMD和EOG等算法来计算图像清晰度的方法,最后汇总为混合评分函数mix()。
摘要由CSDN通过智能技术生成

一般以sobel梯度,方差,拉普拉斯变换计算梯度数值,然后求其平均数,用以衡量清晰度,代码如下

double tenengrad(Mat& src) {
	Mat dst;
	Sobel(src, dst, src.type(), 1, 1);
	double meanValue = 0.0;
	meanValue = mean(dst)[0];
	return meanValue;
}


double brenner(Mat& src) {
	double score = 0.0;
	for (int i = 0; i < src.rows - 2; i++)
	{
		for (int j = 0; j < src.cols; j++) {
			double diff = src.at<uchar>(i + 2, j) - src.at<uchar>(i, j);
			score += diff * diff / 255.0;
		}
	}
	return score;
}


double laplacian(Mat& src) {
	Mat dst;
	double meanValue = 0.0;
	Laplacian(src, dst, CV_32F);
	meanValue = mean(dst)[0];
	return meanValue;
}


double std(Mat& src) {
	Mat mean, std;
	meanStdDev(src, mean, std);
	return std.at<double>(0, 0);
}


double vollath(Mat src) {
	double score = 0.0;
	for (int i = 0; i < src.rows - 1; i++)
	{
		for (int j = 0; j < src.cols; j++) {
			score += src.at<uchar>(i + 1, j) * src.at<uchar>(i, j);
		}
	}
	return score - src.rows * src.cols * mean(src)[0];
}


double smd(Mat& src) {
	double score = 0.0;
	for (int i = 0; i < src.rows - 1; i++)
	{
		for (int j = 0; j < src.cols - 1; j++) {
			score += abs(src.at<uchar>(i + 1, j) - src.at<uchar>(i, j));
			score += abs(src.at<uchar>(i, j + 1) - src.at<uchar>(i, j));
		}
	}
	return score;
}


double smd2(Mat& src) {
	double score = 0.0;
	for (int i = 0; i < src.rows - 1; i++)
	{
		for (int j = 0; j < src.cols - 1; j++) {
			score += abs(src.at<uchar>(i + 1, j) - src.at<uchar>(i, j)) * abs(src.at<uchar>(i, j + 1) - src.at<uchar>(i, j)) / 255;
		}
	}
	return score;
}

double eog(Mat& src) {
	double score = 0.0;
	for (int i = 0; i < src.rows - 1; i++)
	{
		for (int j = 0; j < src.cols - 1; j++) {
			double gradx = src.at<uchar>(i + 1, j) - src.at<uchar>(i, j);
			double grady = src.at<uchar>(i, j + 1) - src.at<uchar>(i, j);
			score += gradx * gradx + grady * grady;
		}
	}
	return score / (src.rows * src.cols);
}

double dctEval(Mat& src) {
	Mat imgF;
	Mat dctI;
	src.convertTo(imgF, CV_64F);
	int rows = imgF.rows % 2 == 0 ? imgF.rows : imgF.rows - 1;
	int cols = imgF.cols % 2 == 0 ? imgF.cols : imgF.cols - 1;
	resize(imgF, imgF, Size(cols, rows));
	dct(imgF, dctI);
	double score = 0;
	double* p;
	for (int i = 1; i < dctI.rows; i++)
	{
		p = dctI.ptr<double>(i);
		for (int j = 1; j < dctI.cols; ++j)
		{
			score += (i + j) * abs(p[j]);

		}
	}
	return score / (dctI.rows * dctI.cols);
}

double mix(Mat& src) {

	double scoreTenengrad = tenengrad(src);
	double scoreBrenner = brenner(src);
	double scoreStd = std(src);
	double scoreSmd = smd(src);
	double scoreEog = eog(src);
	return (scoreTenengrad * 10000 + scoreBrenner + scoreStd + scoreSmd + scoreEog * 1000) / 5.0;
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值