参考:http://blog.csdn.net/trent1985/article/details/50904173

根据国外一篇大牛的文章:No-Reference Perceptual Quality Assessment of JPEG Compressed Images

在无参考图像的质量评价中,图像的清晰度是衡量图像质量优劣的重要指标,它能够较好的与人的主观感受相对应,图像的清晰度不高表现出图像的模糊。本文针对无参考图像质量评价应用,对目前几种较为常用的、具有代表性清晰度算法进行讨论分析,为实际应用中选择清晰度算法提供依据。

对于JPEG图像,根据大牛的文章,写成的MATLAB代码如下:

function score = jpeg_quality_score(img)

%========================================================================
%
%Copyright (c) 2002 The University of Texas at Austin
%All Rights Reserved.
%
%This program is free software; you can redistribute it and/or modify
%it under the terms of the GNU General Public License as published by
%the Free Software Foundation; either version 2 of the License, or
%(at your option) any later version.
%
%This program is distributed in the hope that it will be useful,
%but WITHOUT ANY WARRANTY; without even the implied warranty of
%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%GNU General Public License for more details.
%
%The GNU Public License is available in the file LICENSE, or you
%can write to the Free Software Foundation, Inc., 59 Temple Place -
%Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
%World Wide Web at http://www.fsf.org.
%
%Author : Zhou Wang
%Version : 1.0
%
%The authors are with the Laboratory for Image and Video Engineering
%(LIVE), Department of Electrical and Computer Engineering, The
%University of Texas at Austin, Austin, TX.
%
%Kindly report any suggestions or corrections to zhouwang@ieee.org
%
%========================================================================
%
%This is an implementation of the algorithm for calculating the quality
%score of JPEG compressed images proposed by Zhou Wang, Hamid R. Sheikh
%and Alan C. Bovik. Please refer to the paper: Zhou Wang, Hamid R. Sheikh
%and Alan C. Bovik, "No-Reference Perceptual Quality Assessment of JPEG
%Compressed Images," submitted to IEEE International Conference on Image
%Processing, Sept. 2002.
%
%You can change this program as you like and use it anywhere, but please
%refer to its original source (cite our paper and our web page at
%http://anchovy.ece.utexas.edu/~zwang/research/nr_jpeg_quality/index.html).
%
%Input : A test 8bits/pixel grayscale image loaded in a 2-D array
%Output: A quality score of the image. The score typically has a value
% between 1 and 10 (10 represents the best quality, 1 the worst).
%
%Usage:
%
%1. Load the image, for example
%
% image = imread('testimage.jpg');
%
%2. Call this function to calculate the quality score:
%
% Quality_Score = jpeg_quality_score(image)
%
%========================================================================
% img=imread('/Users/anitafang/Desktop/testimg/test0.jpg'); if (nargin > 1)
score = -1;
return;
end % [M,N] = size(img);
% if (M < 16 | N < 16)
% score = -2;
% return;
% end x1= rgb2gray(img);
x = double(x1);
[M,N] = size(x); % Feature Extraction: % 1. horizontal features d_h = x(:, 2:N) - x(:, 1:(N-1));
% [m, n]=size(d_h);
% disp(d_h);
% fprintf('img width %d,and height %d,length %d, dims %d\n',M,N,length(img),ndims(img));
% fprintf('d_h width %d,and height %d, length %d, dims %d\n',m,n,length(d_h),ndims(d_h)); B_h = mean2(abs(d_h(:, 8:8:8*(floor(N/8)-1)))); A_h = (8*mean2(abs(d_h)) - B_h)/7; sig_h = sign(d_h);
left_sig = sig_h(:, 1:(N-2));
right_sig = sig_h(:, 2:(N-1));
Z_h = mean2((left_sig.*right_sig)<0); % fprintf('B_h:%f,A_h:%f,Z_h:%f,\n',B_h,A_h,Z_h); % 2. vertical features d_v = x(2:M, :) - x(1:(M-1), :); B_v = mean2(abs(d_v(8:8:8*(floor(M/8)-1), :))); A_v = (8*mean2(abs(d_v)) - B_v)/7; sig_v = sign(d_v);
up_sig = sig_v(1:(M-2), :);
down_sig = sig_v(2:(M-1), :);
Z_v = mean2((up_sig.*down_sig)<0); % 3. combined features B = (B_h + B_v)/2;
A = (A_h + A_v)/2;
Z = (Z_h + Z_v)/2; % Quality Prediction alpha = -245.8909;
beta = 261.9373;
gamma1 = -239.8886;
gamma2 = 160.1664;
gamma3 = 64.2859; score = alpha + beta*(B.^(gamma1/10000))*(A.^(gamma2/10000))*(Z.^(gamma3/10000));

调用的main函数:

function main()

allNum = ;
blurNum = ; threshold = 7.7; for k = :
try
image = imread(['/Users/anitafang/Desktop/testimg/','test',num2str(k),'.jpg']);
%image = imread(['/Users/user/Desktop/test/ye_blur/',num2str(k),'.jpg']);
quality_score = jpeg_quality_score(image);
fprintf('Quality_Score:%d.jpg %f\n',k,quality_score);
allNum = allNum + ; if quality_score < threshold
blurNum = blurNum + ;
savePath = ['/Users/anitafang/Desktop/blur/',num2str(k),'.jpg'];
imwrite(image,savePath);
end
% break
catch err
%throw(err);
end
end % fprintf('relevance:%f\n',blurNum/allNum)

为了集成方便,把它变成c++代码,调研opencv库:

//
// jpegquality.hpp
// SDM_Train
//
// Created by anitafang on 2017/6/27.
// Copyright © Anita,fang. All rights reserved.
// #ifndef jpegquality_hpp
#define jpegquality_hpp #include <stdio.h>
#include <vector>
#include <iostream>
#include <time.h>
#include <fstream>
#include <math.h>
#include <cmath> #include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp" #endif /* jpegquality_hpp */ using namespace std;
using namespace cv; class JPEGQ{
public:
JPEGQ();
void h_feature(Mat x,int M,int N);
void v_feature(Mat x,int M,int N);
void combine_feature();
double qual_predict(); private: double B_h,A_h,Z_h;
double B_v,A_v,Z_v;
double B,A,Z;
};

cpp代码是:

//
// jpegquality.cpp
// SDM_Train
//
// Created by anitafang on 2017/6/27.
// Copyright © 2017年 antia.fang All rights reserved.
// #include "jpegquality.hpp" using namespace std;
using namespace cv; JPEGQ::JPEGQ(){
B_h = ;
A_h = ;
Z_h = ;
B_v = ;
A_v = ;
Z_v = ;
B = ;
A = ;
Z = ;
}
//% 1. horizontal features
void JPEGQ::h_feature(Mat x,int M,int N){ Mat d_h(M,N-,CV_64F, Scalar(,,)); for(int i=;i<M;i++){
for(int j=;j<N-;j++){
d_h.at<double_t>(i,j)=x.at<double_t>(i,j+)-x.at<double_t>(i,j);
}
}
// cout << "d_h = " << d_h << "\n";
int DEL= floor(N/);
Mat d1_h(M,DEL,CV_64F, Scalar(,,)); for (int i=;i<M;i++){
for(int j=;j<DEL;j++){
d1_h.at<double_t>(i,j)= abs(d_h.at<double_t>(i,*j+));
}
} //求矩阵像素的的平均值
B_h = mean(d1_h)[];
A_h = (*mean(abs(d_h))[] - B_h)/; Mat sig_h(M,N-,CV_64F, Scalar(,,)); for(int i=;i<M;i++){
for(int j=;j<N-;j++){
if(d_h.at<double_t>(i,j) < ){
sig_h.at<double_t>(i,j) = -;
}
else if(d_h.at<double_t>(i,j) > ){
sig_h.at<double_t>(i,j) = ;
}
else {
sig_h.at<double_t>(i,j) = ;
}
}
} Mat left_sig(M,N-,CV_64F,Scalar(,,));
Mat right_sig(M,N-,CV_64F,Scalar(,,)); for(int i=;i<M;i++){
for(int j=;j<N-;j++){
left_sig.at<double_t>(i,j)=sig_h.at<double_t>(i,j);
right_sig.at<double_t>(i,j)=sig_h.at<double_t>(i,j+);
}
} //double Z_h = mean2((left_sig.*right_sig)<0);
Mat multi_sig(M,N-,CV_64F, Scalar(,,));
for(int i=;i<M;i++){
for(int j=;j<N-;j++){
double temp1=left_sig.at<double_t>(i,j)* right_sig.at<double_t>(i,j);
if(temp1<){
multi_sig.at<double_t>(i,j)= ;
}
else {
multi_sig.at<double_t>(i,j)= ;
} }
}
Z_h =mean(multi_sig)[]; // cout <<"B_h: "<< B_h<<"A_h: "<< A_h<<"Z_h: "<< Z_h << endl; } // % 2. vertical features
void JPEGQ::v_feature(Mat x,int M,int N){ Mat d_v(M-,N,CV_64F, Scalar(,,)); for(int i=;i<M-;i++){
for(int j=;j<N;j++){ d_v.at<double_t>(i,j)=x.at<double_t>(i+,j)-x.at<double_t>(i,j); }
} int DELV= floor(M/);
Mat d1_v(DELV,N,CV_64F, Scalar(,,)); for (int i=;i<DELV;i++){
for(int j=;j<N;j++){ d1_v.at<double_t>(i,j)= abs(d_v.at<double_t>(*i+,j));
}
} //求矩阵像素的的平均值 B_v=mean(d1_v)[];
A_v = (*mean(abs(d_v))[] - B_v)/; Mat sig_v(M-,N,CV_64F, Scalar(,,)); for(int i=;i<M-;i++){ for(int j=;j<N;j++){ if(d_v.at<double_t>(i,j)<)
{ sig_v.at<double_t>(i,j)=-; } else if(d_v.at<double_t>(i,j) >)
{ sig_v.at<double_t>(i,j) = ; } else { sig_v.at<double_t>(i,j) = ;} }
} Mat up_sig(M-,N,CV_64F, Scalar(,,));
Mat down_sig(M-,N,CV_64F, Scalar(,,)); for(int i=;i<M-;i++){
for(int j=;j<N;j++){ up_sig.at<double_t>(i,j)=sig_v.at<double_t>(i,j);
down_sig.at<double_t>(i,j)=sig_v.at<double_t>(i+,j); }
} //double Z_h = mean2((left_sig.*right_sig)<0);
Mat vmulti_sig(M-,N,CV_64F, Scalar(,,));
for(int i=;i<M-;i++){
for(int j=;j<N;j++){
double temp2=up_sig.at<double_t>(i,j)* down_sig.at<double_t>(i,j);
if(temp2<)
{ vmulti_sig.at<double_t>(i,j)= ;}
else { vmulti_sig.at<double_t>(i,j)= ; } }
}
Z_v =mean(vmulti_sig)[]; } //% 3. combined features
void JPEGQ::combine_feature(){ B = (B_h + B_v)/;
A = (A_h + A_v)/;
Z = (Z_h + Z_v)/; } //% Quality Prediction
double JPEGQ::qual_predict(){ double alpha = -245.8909;
double beta = 261.9373;
double gamma1 = -239.8886;
double gamma2 = 160.1664;
double gamma3 = 64.2859; double score = alpha + beta*(pow(B,gamma1/)*pow(A,gamma2/)*pow(Z,gamma3/)); return score;
}

调用的main代码:

//
// main.cpp
// jpg_quality
//
// Created by anitafang on 2017/6/28.
// Copyright © 2017年 anitafang. All rights reserved.
//
#include <iostream>
#include "jpegquality.hpp" using namespace std;
using namespace cv; int main(int argc, const char * argv[]) { char filename[];
double threshold = 7.7;
int num =;
// int *pia = new int[num] (); // 每个元素初始化为0 for(int k=;k<num;k++){ sprintf(filename,"/Users/anitafang/Desktop/VIP/xcode-demo/test-img/testimg/test%d.jpg",k); Mat x1=imread(filename,IMREAD_GRAYSCALE); int M=x1.rows;
int N=x1.cols; Mat x;
x1.convertTo(x, CV_64F);//转换成浮点运算 JPEGQ *jpegq = new JPEGQ();
jpegq->h_feature(x,M, N);
jpegq->v_feature(x,M, N);
jpegq->combine_feature();
double score= jpegq->qual_predict(); if(score<threshold){
cout<<"this is a blur image"<<endl;
} cout<<"the image :"<<k<<" "<<" score is :"<<score<<endl; } return ;
}

可以看到阈值的设置7.7是个经验值。

opencv---JPEG图像质量检测代码的更多相关文章

  1. OpenCV特征点检测------ORB特征

    OpenCV特征点检测------ORB特征 ORB是是ORiented Brief的简称.ORB的描述在下面文章中: Ethan Rublee and Vincent Rabaud and Kurt ...

  2. [转]Android通过NDK调用JNI,使用opencv做本地c++代码开发配置方法

    原文地址:http://blog.csdn.net/watkinsong/article/details/9849973 有一种方式不需要自己配置所有的Sun JDK, Android SDK以及ND ...

  3. opencv车道线检测

    opencv车道线检测 完成的功能 图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像 反透视变换:用的是老师给的视频,没有对应的变换矩阵.所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视 ...

  4. OpenCV + Python 人脸检测

    必备知识 Haar-like opencv api 读取图片 灰度转换 画图 显示图像 获取人脸识别训练数据 探测人脸 处理人脸探测的结果 实例 图片素材 人脸检测代码 人脸检测结果 总结 下午的时候 ...

  5. 利用OpenCV的人脸检测给头像带上圣诞帽

    我们来看下效果 原图: 效果: 原理其实很简单: 采用一张圣诞帽的png图像作为素材, 利用png图像背景是透明的,贴在背景图片上就是戴帽子的效果了. 人脸检测的目的主要是为了确定贴帽子的位置,类似p ...

  6. OpenCV+OpenCL stereo match 代码

    之前配置cuda跟opencv 的混合编程,发现只要使用的东西多半还要用opencv的代码编译一次,加上cuda的编译太浪费时间了,我看了几个博客,觉的opencl这个可能会比较好整,就把opencv ...

  7. 【转载】opencv实现人脸检测

    全文转载自CSDN的博客(不知道怎么将CSDN的博客转到博客园,应该没这功能吧,所以直接复制全文了),转载地址如下 http://blog.csdn.net/lsq2902101015/article ...

  8. [PyImageSearch] Ubuntu16.04 使用深度学习和OpenCV实现物体检测

    上一篇博文中讲到如何用OpenCV实现物体分类,但是接下来这篇博文将会告诉你图片中物体的位置具体在哪里. 我们将会知道如何使用OpenCV‘s的dnn模块去加载一个预训练的物体检测网络,它能使得我们将 ...

  9. OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现

    # OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-环 ...

随机推荐

  1. python3获取一个网页特定内容

    我们今天要爬取的网址为:https://www.zhiliti.com.cn/html/luoji/list7_1.html 一.目标:获取下图红色部分内容 即获取所有的题目以及答案. 二.实现步骤. ...

  2. ubutu强制关闭应用程序的方法

    1.打开终端,输入命令 top 2.查看应用程序PID号,比如是8080 3.然后终端输入 kill 8080 ,行了

  3. 关于Dynamics CRM 安装用户权限的说明

    做了这么多年的CRM项目,但发现部分客户的IT安全监管很严格,在CRM系统安装时,要求给出系统安排账号的权限. 这时小伙伴们 坚持不住了~~ 天天都是用域控的admin操作,这个时候问我要什么权限,于 ...

  4. 在线报表设计实战系列 – 制作多Y轴组合图表(8)

    葡萄城报表是一套强大的报表开发和系统搭建工具,既能与您开发的报表软件项目紧密集成,也可独立部署运行,支持多数据源,具有无编码.灵活.稳定等特性,可以帮您快速搭建专业的报表软件系统,实现各类报表的设计. ...

  5. 安卓基础之Get方式发送http请求

    本文参考作者:超超boy 链接:https://www.cnblogs.com/jycboy/p/post01.html 一.在android用Get方式发送http请求,使用的是java标准类. 主 ...

  6. Android逆向 Android平台虚拟机

    一 Dalvik:是Google开发运行在Android平台的Java虚拟机, Android程序编译后会生成dex文件.Dalvik虚拟机下运行Java时,要将字节码通过即时编译器(just in ...

  7. MySQL升级后 MySQL 5.7 时间不兼容问题

  8. 转:queue

    数据结构C#版笔记--队列(Quene)   队列(Quene)的特征就是“先进先出”,队列把所有操作限制在"只能在线性结构的两端"进行,更具体一点:添加元素必须在线性表尾部进行, ...

  9. 看代码网备份|利用WebClient|eKing.CmdDownLoadDbBakOper|实现定时拷贝数据库备份文件到文件服务器

    摘要: 1.有两台服务器 (1)看代码网(记为A):内网IP:10.186.73.30 (2)文件服务器(记为B):内网IP:10.135.87.157 2.在A架设一个网站,端口8088(防火强设置 ...

  10. phpstudy绑定项目(dist文件)域名--陈远波

    该篇博客是针对已经打包好的dist文件用phpstudy工具进行域名绑定,dist文件生成在这笔者不进行描述,绑定步骤如下: 一:官网下载phpstudy软件进行安装:http://phpstudy. ...