一般以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;