opencv---JPEG图像质量检测代码
参考: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图像质量检测代码的更多相关文章
- OpenCV特征点检测------ORB特征
OpenCV特征点检测------ORB特征 ORB是是ORiented Brief的简称.ORB的描述在下面文章中: Ethan Rublee and Vincent Rabaud and Kurt ...
- [转]Android通过NDK调用JNI,使用opencv做本地c++代码开发配置方法
原文地址:http://blog.csdn.net/watkinsong/article/details/9849973 有一种方式不需要自己配置所有的Sun JDK, Android SDK以及ND ...
- opencv车道线检测
opencv车道线检测 完成的功能 图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像 反透视变换:用的是老师给的视频,没有对应的变换矩阵.所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视 ...
- OpenCV + Python 人脸检测
必备知识 Haar-like opencv api 读取图片 灰度转换 画图 显示图像 获取人脸识别训练数据 探测人脸 处理人脸探测的结果 实例 图片素材 人脸检测代码 人脸检测结果 总结 下午的时候 ...
- 利用OpenCV的人脸检测给头像带上圣诞帽
我们来看下效果 原图: 效果: 原理其实很简单: 采用一张圣诞帽的png图像作为素材, 利用png图像背景是透明的,贴在背景图片上就是戴帽子的效果了. 人脸检测的目的主要是为了确定贴帽子的位置,类似p ...
- OpenCV+OpenCL stereo match 代码
之前配置cuda跟opencv 的混合编程,发现只要使用的东西多半还要用opencv的代码编译一次,加上cuda的编译太浪费时间了,我看了几个博客,觉的opencl这个可能会比较好整,就把opencv ...
- 【转载】opencv实现人脸检测
全文转载自CSDN的博客(不知道怎么将CSDN的博客转到博客园,应该没这功能吧,所以直接复制全文了),转载地址如下 http://blog.csdn.net/lsq2902101015/article ...
- [PyImageSearch] Ubuntu16.04 使用深度学习和OpenCV实现物体检测
上一篇博文中讲到如何用OpenCV实现物体分类,但是接下来这篇博文将会告诉你图片中物体的位置具体在哪里. 我们将会知道如何使用OpenCV‘s的dnn模块去加载一个预训练的物体检测网络,它能使得我们将 ...
- OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现
# OpenCV学习系列(一) Mac下OpenCV + xcode人脸检测实现 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-环 ...
随机推荐
- amazeui+canvas绘制二维码
<link rel="stylesheet" type="text/css" href="css/amazeui.min.css"/& ...
- 移动设备 小米2S不显示CD驱动器(H),便携设备,MTP,驱动USB Driver,MI2感叹号的解决方法
小米2S不显示CD驱动器(H),便携设备,MTP,驱动USB Driver,MI2感叹号的解决方法 by:授客 QQ:1033553122 用户环境 操作系统:Win7 手机设备:小米2S 问题描 ...
- Android 机器人项目Pepper_Android
github地址:https://github.com/ohwada/Pepper_Android
- Android友盟增量更新
1.增量升级的原理 增量更新的原理就是将本地apk与服务器端最新版本比对,并得到差异包.比如现在的版本是1.1.4,大小是7.2M,新版本是1.1.5.大小是7.3M.我们发现两个版本只有0.1M的差 ...
- idea 关联 jdk
1.打开IntelliJ IDEA 2.选择 "File" 菜单 3.找到 "other settings" 4.选择 “Structure for new P ...
- Go语言包管理工具dep
什么是dep? dep和go,在一定程度上相当于maven之于Java,composer之于PHP,dep是go语言官方的一个包管理工具. 相比较go get而言,dep可以直接给引入的第三方包一个专 ...
- LeetCode 题解之Rotate List
1.题目描述 2.题目分析 首先数出链表中的元素个数count,然后对k = k % count 求余数.接着将链表形成一个环,从最后一个元素开始,运动 count - k 步,此时节点的下一个节点 ...
- Unix操作系统监控详解(一)
一.描述 监控在检查系统问题运行状况以及优化系统性能工作上是一个不可缺少的部分.通过操作系统监控工具监视操作系统资源的使用情况,间接地反映了各服务器程序的运行情况.根据运行结果分析可以帮助我们快速定位 ...
- 为 Azure Resource Manager 中的虚拟机设置 WinRM 访问权限
Azure 服务管理中的 WinRM 与 Azure Resource Manager Note Azure 具有用于创建和处理资源的两个不同的部署模型:Resource Manager 和经典. 本 ...
- Sysstat的工具集sar、 iostat、mpstat、sadf、sar、sadc
sysstat Sysstat的工具集sar. iostat.mpstat.sadf.sar.sadc * iostat 工具提供CPU使用率及硬盘吞吐效率的数据: * mpstat 工具提供单个处理 ...